ZibuのHippocampus

人生天地间,忽如远行客

关于IO这方面,已经有过多次学习,但是一直不成系统,本文将作一个相对全面的总结。

同步、异步IO, 阻塞和非阻塞IO的区别

select,poll,epoll的原理。

阅读全文 »

在后台校验参数是接收参数后的第一步,如果使用@RequestParam接收参数,逐个校验,Controller方法会过长 校验代码页非常冗余而且多个方法都需要校验。

而使用@Validated 进行校验,可以更为快捷的完成参数校验的工作,而且可以将参数校验放置到Bean钟,Ctrl代码简洁优雅,参数校验实现复用

阅读全文 »

图灵完备性

概念

  • 一个图灵完备系统意味着在这个系统中程序能够找到解决方法(在无限运行时间和内存条件下)。—StackOverFlow

  • 图灵完备性是指在可计算性理论中,编程语言或任意其他的逻辑系统如具有等同于通用图灵机的计算能力。换言之,此系统可与通用图灵机互相模拟。这个词源于引入图灵机概念的数学家艾伦·图灵(Alan Turing)。

    虽然图灵机会受到存储能力的物理限制,图灵完全性通常指具有无限存储能力的通用物理机器或编程语言。简单来说,一切可计算的问题都能计算,这样的虚拟机或者编程语言就叫图灵完备的。—维基百科

比特币:

​ 比特币现在不是图灵完备的,因此只能作为数字货币使用,不能直接支持智能合约及更复杂的去中心化应用。

以太坊:

​ 相比与比特币,以太坊属于区块链2.0的范畴,解决了比特币网络的一些问题而进行了重新设计。

在shell脚本的学习编写过程中,受到了沈老师的推荐,把py作为个人的胶水语言,以当前个人的学习方向而言,Java是重点,作为工程开发语言。Golang作为区块链方向首选语言,并且打算阅读ETH和docker源码。

作为服务器脚本编程需要一门解释性语言,shell可以,但是太过于薄弱,干脆直接学了python,写脚本,写爬虫都很方便。而且python作为一门优秀的解释性语言已经有了相当强大完备的社区。

阅读全文 »

简单示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#!/bin/sh          #是shell脚本的注释 #!作为开头 专有注释 标识路径后所指定的程序即使解释此脚本文件shell程序
DIR=`dirname $0` #'dirname $0'为当前脚本文件的父目录 DIR=即为声明一个变量为DIR,=号左右不可以有空格
cd $DIR # 进入父目录下、即为当前目录
nohup java -XX:+UseG1GC -XX:+HeapDumpOnOutOfMemoryError -Xms512M -Xmx4G -jar `ls | grep jar` > /dev/null 2>&1 &
# java -jar 'ls | grep jar' 启动已经打包好的jar包
# -XX:+UseG1GC 使用G1 GC收集器
# -XX:+HeapDumpOnOutOfMemoryError 当堆内存空间溢出时输出堆的内存快照。
# -Xms512M 初始堆大小 默认值为物理内存的1/64 当空余堆内存小于40%时,JVM会增大堆
# -Xmx4G 最大堆大小 默认值为物理内存的1/4 当空余对内存大于70%时,JVM会减小堆
# > 标准输出流重定向 /dev/null 重定向到空设备文件 2:标准错误流 1:标准输出流
# 2>&1 stdout/stderr 往一个设备文件输出 但是stderr会沿用sedout的pipe
# >a 2>a 则会打开两个pipe,每个管道往文件里写入数据时,会flush掉原有的数据
# & 等同 2>&1 2的重定向(>)等于1

# ./xx.sh 执行 注意查看是否具有执行权限

前菜

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
cd `dirname $0`
BIN_DIR=`pwd` # 脚本所在目录
cd ..
PROJECT_DIR=`pwd` # 脚本所在父目录 项目目录

mvn clean install -DskipTests # 清除原有Jar包 并 重新Install
# -DskipTests,不执行测试用例,但编译测试用例类生成相应的class文件至target/test-classes下。
# -Dmaven.test.skip=true,不执行测试用例,也不编译测试用例类。

TARGET_JAR="$PROJECT_DIR/trade-web/target/trade.jar" # 选定目标Jar文件

if [ ! -f $TARGET_JAR ]; then # 如果目标文件不存在 输出错误信息 并 退出
echo "ERROR: $TARGET_JAR not exist"
exit 1
fi

rm -rf ./trade.jar # 移除当前目录下的Jar文件
cp $TARGET_JAR ./ # 拷贝新打包的Jar文件

echo "kill prev app.."

ps aux | grep java | grep "trade-web" | awk '{print $2}' | xargs kill -9
# 找出并杀死原有项目进程

DEBUG_OPT="-agentlib:jdwp=transport=dt_socket,address=48091,server=y,suspend=n"
# 设置远程调试的Agent,JVM允许外部的库运行时注入到JVM,这些外部的库就是Agent,Agent能够动态修改Class文件(方法区)
# **-agentlib:jdwp=... **来引入 jdwp 这个 Agent 的。
# jdwp 是一个 JVM 特定的 JDWP(Java Debug Wire Protocol) 可选实现,用来定义调试者与运行JVM之间的通讯,它的是通过 JVM 本地库的 jdwp.so 或者 jdwp.dll 支持实现的。

nohup java $DEBUG_OPT -Dfile.encoding=UTF-8 -DappName=trade-web -jar $PROJECT_DIR/trade.jar --spring.profiles.active=dev > app.log 2>&1 &

tail -f $PROJECT_DIR/app.log
# 查看log日志

Shell基础

Shell 环境

Linux 的 Shell 种类众多,常见的有:

  • Bourne Shell(/usr/bin/sh或/bin/sh)
  • Bourne Again Shell(/bin/bash)
  • C Shell(/usr/bin/csh)
  • K Shell(/usr/bin/ksh)
  • Shell for Root(/sbin/sh)

Bourne Again Shell**(Bash)**是Bourne Shell的后续兼容版本 ,所以,像 #!/bin/sh,它同样也可以改为 #!/bin/bash


执行 Shell 脚本:

1、作为可执行程序

1
2
3
4
5
# 使脚本具有执行权限
chmod +x run.sh
chmod 777 test.sh
# 执行脚本
./test.sh

注意,一定要写成 ./test.sh,而不是 test.sh,运行其它二进制的程序也一样,直接写 test.sh,linux 系统会去 PATH 里寻找有没有叫 test.sh 的,而只有 /bin, /sbin, /usr/bin,/usr/sbin 等在 PATH 里,因此需要告诉系统在当前目录需找对应文件。

2、作为解释器参数

这种运行方式是,直接运行解释器,其参数就是 shell 脚本的文件名,如:

1
2
/bin/sh test.sh
/bin/php test.php

这种方式运行的脚本,不需要在第一行指定解释器信息,写了也没用。


Shell变量

声明变量:局部变量 环境变量

1
2
3
4
5
my_name="zibu" #=号两边不能有空格 
#变量只可以由数字英文下划线组成 数字不能开头

echo ${my_name} #${}使用变量

字符串:单引号 双引号

1
2
3
4
5
6
7
8
9
10
str='this is a string' 
# 单引号里的任何字符都会原样输出,单引号字符串中的变量是无效的;
# 单引号字串中不能出现单独一个的单引号(对单引号使用转义符后也不行),但可成对出现,作为字符串拼接使用。

your_name='runoob'
str="Hello, I know you are \"$your_name\"! \n"
echo $str
Hello, I know you are "runoob"!
# 双引号里可以有变量
# 双引号里可以出现转义字符

数组:只支持一维数组

1
2
3
4
5
6
7
8
9
array_name={value0 value1 value2} # shell数组之间使用空格分割 一次性声明数组
array_name[0]=value0
array_name[1]=value1
array_name[2]=value2 # 单独定义数组的各个分量

${array_name[n]} # 读取数组某个元素
echo ${array_name[@]} # 获取数组的全部元素
${#array_name[@]} # 获得数组的长度
${#array_name[n]} # 获取某个元素某个位置的数据长度

Shell运算符:算数,关系,逻辑,布尔,文件测试

算数关系运算:原生不支持 利用expr命令

1
2
3
4
5
6
7
8
9
10
11
12
13
#!/bin/bash

val=`expr 2 + 2` # `是反引号 '单引号是字符串 表达符和运算符之间有空格
echo "两数之和为 : $val"

+ 加法 `expr $a + $b` 结果为 30。
- 减法 `expr $a - $b` 结果为 -10。
* 乘法 `expr $a \* $b` 结果为 200。 # *需要转义符
/ 除法 `expr $b / $a` 结果为 2。
% 取余 `expr $b % $a` 结果为 0。
= 赋值 a=$b 将把变量 b 的值赋给 a。
== 相等。用于比较两个数字,相同则返回 true。 [ $a == $b ] 返回 false。
!= 不相等。用于比较两个数字,不相同则返回 true。 [ $a != $b ] 返回 true

相关引用

菜鸟驿站-shell教程

本文主要记录正则表达式的一些具体的应用,因为实在太容易遗忘,而且在工作上的作用很大。

阅读全文 »

什么是优质的代码,如何编写出优质的代码,在Coding的时候要做什么才能让自己的代码更为优雅简洁,本文落足实际,为编写出优秀的业务的代码而服务。

表格驱动法

核心:拆分业务逻辑和具体数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// 同样一段业务代码 如果在需要增加数据的时候,代码就会特别冗杂
function contry_initial($country){
if ($country==="China" ){
return "CHN";
}else if($country==="America"){
return "USA";
}else if($country==="Japan"){
return "JPN";
}else{
return "OTHER";
}
}
// 然而将数据和逻辑分离之后,数据可以单独增加,不影响业务逻辑,代码的可重用性更高。
function contry_initial($country){
$countryList=[
"China"=> "CHN",
"America"=> "USA",
"Japan"=> "JPN",
];

if(in_array($country, array_keys($countryList))) {
return $countryList[$country];
}
return "Other";

}

在实际的多人开发的项目中,表格驱动法可以使得在添加相对应功能的时候,只需要修改数据而非变动逻辑,使得代码的维护性大大增强,风格统一。数据易于变动,逻辑相对而言更为稳定。


相关引用

表格驱动法

在项目中从零构建P2P网络时,遇到了许多问题,如TCP长连接为何断开,Client访问Server 6420端口,为什么实际上建立的端口连接是其他端口,等等问题。

这才发现个人的计网能力非常表面,在应对面试时尚可,一旦到了生产环境中就远远不足了,因此以TCP协议为主,将仔细研读《计算机网络—自顶向下方法》 一书,扩充个人Blog的计网相关知识文章。

阅读全文 »

Java已经有了非常成熟性能监控工具,然而Go在这一方面还很欠缺,pprof(Program Profile)是Golang自带的性能分析工具。本文记录了这两天使用pprof包遇到的一些问题和经验。

阅读全文 »

加密货币三角定律

任何一个加密货币不可能在交易速度,安全性,去中心化程度三者都做到完美,都是一定程度上的妥协。——-Vitalik Buterin (以太坊创始人)

  • 交易速度
  • 安全性
  • 去中心化程度

进入区块链方向已有两月,在总结加密货币的特点而言,虽有大概的想法,却没有这句话这么精准。

这个世界上的所有加密货币都是如此的,一如比特币的POW公链,彻底的去中心化和安全性,然则TPS有限。而Ripple的TPS虽高,然则基于DPOS的策略,实则有52个中心节点存在,并不完全去中心化。倘若不需要安全性,当然可以有较高的TPS,去中心化。但失去安全性的加密货币还有其价值吗,因此加密货币往往在TPS和中性化之间做出一个妥协。



0%