一、 shell脚本 1、 shell脚本,应该拥有以下基本元素 脚本以.sh为扩展名 方便查看
1、第1行的声明“#!/bin/bash” 2、注释:说明某些代码的功能 单行注释: # 多行注释: :<<BLOCK BLOCK (此处英文相照应就行) 3、可执行语句:实现程序的功能 (循环语句、判断、函数、数组、变量) 2、Shell脚本的执行 方法一:以相对路径的方式去执行shell脚本 方法二:以绝对路径的方式去执行shell脚本 方法三:直接使用bash来执行shell脚本 方法四:在当前的shell环境中执行bash shell脚本:source或. #区别: 1、方法三:可以在脚本中不指定解释器,脚本可以没有执行权限 2、方法一和方法二脚本需要有执行权限,./script_name.sh 或/path/script_name.sh 3、方法四:当前shell执行,方法1-3开启子shell 3、 shell脚本编写规范 1)没有必要使用cat命令 使用以下方式即可 grep guru /etc/passwd 2)代码缩进 4、 位置化参数 这种变量主要是用来向脚本当中传递参数或数据的,变量名不能自定义,变量作用是固定的。 $1 $2 $3 $4 $5 $6 $7 $8 $9 ${10} 预定义变量 是 Bash 中已经定义好的变量,变量名不能自定义,变量作用也是固定的。 $0 :脚本名 $* :所有的参数,双引号引起来时参数视为单个字符串 $@:所有的参数,双引号引起来时,每个参数作为个体 $# :参数的个数 $$ :当前进程的PID $? :上一个命令的返回值0表示成功 5、read从命令行读入变量值 read从命令行读入变量值 read 变量名 read -p 提示信息: 变量名 read -t 5 -p 提示信息: 变量名 (等待时常5秒) read命令行中也可以不指定变量 ,如果不指定变量,那么read命令会将接收到的数据放置在环境变 量REPLY中 6、exit退出码 程序执行后会携带一个退出码: (1) 0代表成功,1-255代表失败 (2) Shell程序的退出码储存在系统变量$?
【Horn Studio】编程专栏: 抢气球 解题思路 题目 题目描述 A教室的墙上挂满了五颜六色的气球,小朋友们都非常喜欢。刚一下课,小朋友们就打算去抢这些气球。每个气球在墙上都有一定的高度,只有当小朋友跳起来时,手能够到的高度大于等于气球的高度,小朋友才能摘到这个气球。为了公平起见,老师让跳的低的小朋友先摘,跳的高的小朋友后摘。小朋友都很贪心,每个小朋友在摘气球的时候都会把自己能摘的气球都摘掉。很巧的是,小朋友们跳起来手能够着的高度都不一样,这样就不会有跳起来后高度相同的小朋友之间发生争执了。 输入 第一行输入两个空格分隔的整数n,m,其中n表示小朋友的数量,m表示墙上气球的数量。第二行输入n个正整数(每两个整数之间用空格隔开),第i个数为 aiai,表示第i个小朋友跳起来手能够着的高度。第三行输入m个正整数(每两个整数之间用空格隔开),第i个数为 hihi,表示第i个气球的高度0<n、m≤100000,0<ai、hi≤1090<n、m≤100000,0<ai、hi≤109 输出 输出一共n行,每行一个整数。第i行表示第i个小朋友摘到的气球数量。 样例输入 复制 5 6 3 7 9 6 4 1 2 3 4 5 6 样例输出 复制 3 0 0 2 1 提示 来源 思路 这道题跟普通的二分题目十分的相像,而且用普通的解法也可以解出来。但是我们在这里用二分,因为其复杂度小,不容易T。
首先这里她并没有说明数据是有序的,我们先定义一个为存储儿童身高,下标的一个结构体,在排序。
sort(a+1,a+n+1,cmp) /* 由于结构体无法直接sort,所以需要自己写一个适配函数: bool cmp(qnode A,qnode B){ return A.x<B.x; } */ sort(h+1,h+m+1); 接下来跟二分就一样了,只要一直满足
h[mid]<=a[i].x 的条件,就可以继续二分下去,最后,我们还需要恢复下标:
ans[a[i].id]=res-pre; pre=res; 代码 #include<bits/stdc++.h> using namespace std; const int maxn=100005; int n,m; struct qnode{ int x,id; }a[maxn]; int h[maxn],ans[maxn]={}; bool cmp(qnode A,qnode B){ return A.
1.使用vmware创建虚拟机,
1.1选择对应的镜像文件,我这里使用的是CentOS-7-x86_64-Minimal-1804.iso纯净版,然后点击下一步。
1.2选择网络类型的时候,根据自己的需求进行选择,我喜欢使用NAT模式。如果使用桥接模式,这必须和自己的电脑在同一网段,输入ipconfig查看主机的 VMnet8 的 IP。
2.安装完成后,开始配置虚拟机IP设置。
2.1在虚拟机命令行中输入 vi /etc/sysconfig/network-scripts/ifcfg-ens33 打开网卡,进行网络配置。
BOOTPROTO是获取IP的方式,DHCP动态获取,static手动设置(为了便于理解我们就叫手动设置)
ONBOOT代表系统启动时是否激活网卡,我们设置为”yes”
IPADDR虚拟机IP地址
NETMASK 子网掩码
GATEWAY 网关
DNS 域名解析服务器
2.2设置完成后,然后输入 system restart network重启网卡,然后在输入ip addr
2.3当ens33的IP和你配置的IP一样时,那么恭喜你IP配置就成功了,下面正式开始JDK的配置。
3.1使用Xftp将JDK(Linux版)传送到虚拟机的文件夹下,我是放在了/usr/local目录下
3.2使用tar -zvxf jdk-8u181-linux-*64.tar.gz(一定要与自己的jdk名字相同)解压命令,解压缩包。解压完成后的文件如图所示。
3.3然后输入命令vi /etc/profile设置环境变量;粘贴下面的语句,完成后按esc键,然后冒号,wq保存退出
export JAVA_HOME=/usr/local/jdk(自己jdk文件名,路径必须正确)
export JRE_HOME=$JAVA_HOME/jre
export CLASSPATH=$CLASSPATH:.:$JRE_HOME/lib:$JAVA_HOME/lib
export PATH=$PATH:$JAVA_HOME/bin:$JRE_HOME/bin
3.4 source /etc/profile 重启环境变量,最后输入java -version查看,出现一下版本号证明你的jdk就配置成功了。
下期发布在Linux下配置多tomcat
// Python Extension Packages for Windows - Christoph Gohlke (uci.edu)
安装tensorflow 之前 先安装 termcolor 此处是我自己存放在博客园上的地址
https://files-cdn.cnblogs.com/files/RYSBlog/termcolor-1.1.0-py2.py3-none-any.whl.zip
下载好了之后 安装
先到安装目录 再 pip install termcolor-1.1.0-py2.py3-none-any.whl
之后安装 tensorflow
pip install tensorflow -i https://pypi.tuna.tsinghua.edu.cn/simple/
pip install torch -i https://pypi.tuna.tsinghua.edu.cn/simple/
//
【Horn Studio】编程专栏: 抢气球 解题思路 题目 题目描述 一年一度的“跳石头”比赛又要开始了!这项比赛将在一条笔直的河道中进行,河道中分布着一些巨大岩石。组委会已经选择好了两块岩石作为比赛起点和终点。在起点和终点之间,有NN块岩石(不含起点和终点的岩石)。在比赛过程中,选手们将从起点出发,每一步跳向相邻的岩石,直至到达终点。为了提高比赛难度,组委会计划移走一些岩石,使得选手们在比赛过程中的最短跳跃距离尽可能长。由于预算限制,组委会至多从起点和终点之间移走MM块岩石(不能移走起点和终点的岩石)。 输入 第一行包含三个整数L,M,NL,M,N,分别表示起点到终点的距离,起点和终点之间的岩石数,以及组委会最多移走的岩石数。保证L≥1L≥1且N≥M≥0N≥M≥0 。接下来NN行,每行一个整数,第ii行的整数DiDi,表示第ii块岩石与起点的距离。这些岩石按与起点距离从小到大的顺序给出,且不会有两个出现在同一个位置。 输出 一个整数,即最短跳跃距离的最大值。 样例输入 复制 25 5 2 2 11 14 17 21 样例输出 复制 4 提示 对于20%的数据,0≤M≤N≤100≤M≤N≤10对于50%的数据,0≤M≤N≤1000≤M≤N≤100对于100%的数据,0≤M≤N≤50,000,1≤L≤1,000,000,00000≤M≤N≤50,000,1≤L≤1,000,000,0000 来源 思路 这道题跟二分一样,从起点出发,先选定一段距离mid,若前面的石头B与你所站着的石头A的距离小于mid,就把B搬掉,记录一下;如果不,就把B留下,再跳到石头B上。照这个步骤多次循环后,如果搬掉的石头多了,就把距离mid定小点;如果少了,就把mid定大点。,很简单。直接考虑问题比较困难。我们首先考虑另一个问题,如果给定一个距离d,问至少要移走多少石头才能满足石头之间的最小距离不小于d?对于这个问题,答案就很简单了。从左岸开始,移走它小于d的所有石头,再往后跳一步,循环往复。就解决了!
我们同样需要一个判断,大概就是如下:
bool check(int x) { int last = 0, cnt = 0; for (int i = 1; i <= n; i++) { if (a[i] - last < x) cnt++; else last = a[i]; } if (cnt > m) return false; return true; } 代码 #include <bits/stdc++.
本文要解决的几个问题,
1、什么是模板方法模式;
2、模板方法模式的使用场景;
3、模板方法模式的优点;
4、源码中有哪些地方使用到了模板方法模式;
带着这几个问题,我们开始今天的设计模式的分享。
一、模式入场 大家在日常的工作生活中肯定碰到过这样的场景,比如,你要转正答辩了,总要有个PPT吧,这时你是不是会问你同事要个述职的PPT模板,有个模板的好处这里自不用说。你去帮助单位去投标拿项目了,你是不是要问甲方爸爸要个模板,按照模板准备你的材料。生活中这样的例子太多了,有模板好办事。
在平时的开发过程中,不知道你是否碰到过类似的情形,你要调用系统A和系统B的接口,把系统A和系统B的数据读取过来,经过处理存储到自己的数据库里。
针对这样的场景你要怎么设计呐,首先,针对这样一个场景进行分析,要明确的是需要调用两个系统的接口,这两个系统返回的数据是不一样的,并且要存储到不同的表中,下面先试图实现下这个场景。有两个类SyncSystemA和SyncSystemB分别表示处理系统A和系统B的接口数据,
SyncSystemA.java
package com.example.template; public class SyncSystemA { public void syncData(){ //1、组装参数 String url=http://a.com/query; String param=A; //2、发送请求 String result=sendRequest(url,param); //3、解析 String result2=parse(result); //4、保存数据 saveData(result2); } private String sendRequest(String url,String param){ System.out.println(发送请求到A); return ; } private String parse(String result){ System.out.println(对A返回结果进行解析); return ; } private void saveData(String result){ System.out.println(保存A的数据); } } SyncSystemB.java
package com.example.template; public class SyncSystemB { public void syncData(){ //1、组装参数 String url=http://b.
#!/bin/bash #yum 安装包更新 yum update -y #卸载旧版 yum remove docker docker-common docker-selinux docker-engine -y #安装docker依赖包 yum install -y yum-utils device-mapper-persistent-data lvm2 #安装docker yum install docker-ce -y #输出docker版本进行验证 if [ $? -eq 0 ];then docker version docker info else echo 安装失败 fi #开启docker服务和开机自启动 systemctl start docker if [ $? -eq 0 ];then echo docker 服务启动成功 else echo docker 服务没有正常启动请重新安装! systemctl enable docker
嵌入式linux开发-交叉编译的一些tips 时间:20201013,版本:V0.1
1.交叉编译工具链的组成 交叉编译工具链是一个由编译器、连接器和解释器组成的综合开发环境,交叉编译工具链主要由binutils、gcc和glibc三个部分组成。有时出于减小 libc 库大小的考虑,也可以用别的 c 库来代替 glibc,例如 uClibc和 newlib。
2.交叉编译工具的获取 (1)可以去下别人厂商提供的或者别人制作好的。
(2)交叉编译工具的制作可以参考这个文章:How to Build a GCC Cross-Compiler
https://preshing.com/20141119/how-to-build-a-gcc-cross-compiler/
以及《嵌入式linux系统开发教程 第二版》(图6-1),过程说的很清楚。制作过程比较繁琐,主要是因为为了生成完整版的gcc,需要先编译一个辅助版的不依赖glibc的编译器,再用辅助gcc编译libc,再生成完整的gcc。
(3)从头做一个太麻烦,可以使用工具。我们这里采用buildroot生成的。Buildroot使用见本站其文章。
3.交叉编译链工具的命名规则 交叉编译知识解析(二) —— 交叉编译器的名字的命名规则
https://blog.csdn.net/zqixiao_09/article/details/51823165
https://www.crifan.com/files/doc/docbook/cross_compile/release/html/cross_compile.html#crosscompiler_naming_rule
4.交叉编译器引用头文件的位置 交叉编译器默认引用的.h文件和lib文件的位置,可以使用如下的命令查看:
(这里的mipsel-linux-gcc是使用buildroot生成的。)
./mipsel-linux-gcc -print-search-dirs
打印出搜索路径。一堆挤在一起的路径,很难看。
网上大家貌似更喜欢另一个命令:
$ echo 'main(){}' | ./mipsel-linux-gcc -E -v -x c -
参数-E:
只进行预处理步骤,这个不生成文件, 需要把它重定向到一个输出文件里面。
参数-v:
使用 gcc -v 可以查看默认开启的选项。编译这个工具时所使用的configure 参数配置。
参数 - (只有一个短线):
这个参数需要特殊说明一下。短线的意思是 Specify input file as stdin, 在这里就是从管道接收输入了。-x c 的意思是以c语言来编译接收的文件。因为接收的是字符流,没有文件名,所指告知gcc是c语言。Gcc默认也是c。
一、postgresql中的序列 1.1 场景需求 需要向下图一样,需要对产品编码编码设置一个序列。编码规则 SKU + 序列号:
1.2 序列 序列是基于bigint算法的,因此范围是不能超过一个八字节 整数的范围(-9223372036854775808 到 9223372036854775807)。
由于nextval和setval调用绝不会回滚, 如果需要序数的无间隙分配,则不能使用序列对象。可以 通过在一个只包含一个计数器的表上使用排他锁来构建无间隙的分配, 但是这种方案比序列对象开销更大,特别是当有很多事务并发请求序数时
创建和使用语法:
1 2 3 4 5 CREATE SEQUENCE serial START 101; SELECT nextval('serial'); nextval --------- 101 本节描述用于操作序列对象的函数,序列对象也被称为序列生成器或者就是序列。
序列对象都是用CREATE SEQUENCE创建的特殊的单行表。
序列对象通常用于为表的行生成唯一的标识符。
表 中列出的这些序列函数,可以为我们从序列对象中获取连续的序列值提供了简单的、多用户安全的 方法。
获取序列值是安全的,可以用来和其他键组合形成唯一主键。
补充:PostgreSQL中序列相关函数 nextval、currval、lastval、setval、setval
PostgreSQL中序列主要涉及到的函数是 函数 返回类型 描述 nextval(regclass) bigint 递增序列对象到它的下一个数值并且返回该值。这个动作是自动完成的。即使多个会话并发运行nextval,每个进程也会安全地收到一个唯一的序列值。 currval(regclass) bigint 在当前会话中返回最近一次nextval抓到的该序列的数值。(如果在本会话中从未在该序列上调用过 nextval,那么会报告一个错误。)请注意因为此函数返回一个会话范围的数值,而且也能给出一个可预计的结果,因此可以用于判断其它会话是否执行过nextval。 lastval() bigint 返回当前会话里最近一次nextval返回的数值。这个函数等效于currval,只是它不用序列名为参数,它抓取当前会话里面最近一次nextval使用的序列。如果当前会话还没有调用过nextval,那么调用lastval将会报错。 setval(regclass, bigint) bigint 重置序列对象的计数器数值。设置序列的last_value字段为指定数值并且将其is_called字段设置为true,表示下一次nextval将在返回数值之前递增该序列。 setval(regclass, bigint, boolean) bigint 重置序列对象的计数器数值。功能等同于上面的setval函数,只是is_called可以设置为true或false。如果将其设置为false,那么下一次nextval将返回该数值,随后的nextval才开始递增该序列。 注意序列名中有大写字母时,regclass参数值需要用双引号括和单引号一起括起来,比如:
一、内存溢出与内存泄漏 内存溢出是指程序在申请内存时,没有足够的内存空间供其使用。
内存泄露是指程序在申请内存后,无法释放已申请的内存空间,一次内存泄露危害可以忽略,但内存泄露堆积后果很严重,无论多少内存,迟早会被占光
二、内存溢出定位相关方法 1.获取Java虚拟机内存快照 1.1.主动获取内存快照 #查看当前java进程 >jps #查看系统GC情况统计(jstat -gc 进程ID 持续监控n毫秒 打印次数) >jstat -gc 2780 1000 3 S0C: 第一个Survivor区域大小,S1C:第二个Survivor区域的大小
S0U:第一个Survivor区域使用的大小,S1U:第二个Survivor区域使用的大小
EC:Eden区域的大小,EU:Eden区域的使用大小
OC:Old区的大小,OU:Old区使用的大小
MC:方法区大小
YGC:年轻代垃圾回收次数,YGCT: 使用时间
FGC:年老代垃圾回收次数,FGCT: 使用时间
GCT:垃圾回收总耗时
#通过jmap导出堆内存使用情况的dump.dat文件 jmap -dump:format=b,file=C:/demo/jvm/dump.dat 2780 注意:生产环境内存一般很大,不能用这个方式导出。占用大量资源影响系统正常运行。
1.2.设置java虚拟机参数,内存溢出时,保留内存快照 #示例设置虚拟机最大内存30m -Xmx30m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=C:/demo/jvm/dump.dat 设置打印gc日志的参数
#设置保存GC日志,注意,需要设置日志文件个数(需大于1个),和文件大小(需大于8k) -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps -Xloggc:C:/demo/jvm/log/gc.log -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=10 -XX:GCLogFileSize=286k 注意:Windows环境下测试时,jvm参数中用到的文件路径,不能自动创建,需要提前创建好。
2.查看生成的内存快照 2.1.用java的jhat命令查看生成的dump jhat -port 8081 C:/demo/jvm/dump.dat 2.1.1.打开查看dump地址 http://localhost:8081,如下图:
2.1.2.查看各个类的内存占用情况 点击Show heap histogram,查看实例个数及占用内存情况,如下图:
点击Execute Object Query Language (OQL) query,打开查询工具,参考OQL Help写查询语句定位目标类