且行善举,莫问前程。

0%

学习是个由浅到深的过程,这个过程是比较困难的。有很多人在到深的过程中就放弃了。人都是有惰性的,会知难而退。能不能深入要看这个人的毅力如何,是否可以抵制诱惑。如何确定要学习的内容,这是很大的话题,暂且不谈。聊一聊该怎么学习,怎么由浅到深。

看了编成随想的文章,大致是分为三个过程,也就是What、How、Why学习法,比如我要学习Python编成语言该怎么学习。

What

首先,什么是Python,Python是一门脚本语言,应用在众多方面,比如运维,后端开发,爬虫,数据分析,机器学习等。学习Python的基础语法,然后可以用它写一些小的程序。能够熟练使用Python中的内置方法和第三方包等等。

这些都是初级的,不管使用Python还是其他语言,这些只能是浅层的学习。

How

其次,再来深入,比如再去了解Python的底层实现,built-in内置函数的实现,了解其中的算法实现,一步步深入。

在这个层次,你是要搞懂怎么做,怎么实现。也是下一步的关键。

Why

最后,当了解了内部实现后,你就会有疑问,为什么是这么做,你会有所思考。当你知识量足够大时,你就会有所比较,比如,Python的gc为什么要使用引用计数器,而不像ruby使用预先创建的链表方法。

在这一步,才会有质的提升。也会激发自己的创造能力,也就是说读书破万卷,下笔如有神。

虽然说只有简单的三步,但是在其中要付出很多,坚持毅力,还要有一定的自学能力,自主思考的能力,才能将其研究透彻。当然,多加练习,你也会拥有这些能力。

与君共勉。

我们抛开数字货币来谈区块链,区块链技术是非常好的,区块链上的数据有着完整、一致、及时、准确,不可篡改等优点。

如今一项技术火了就会有很多教育机构争相开始培训课程。其实很多技术没有必要花钱去学,只要有心,网络上就可以搞到。一些专有课程除外。

我是比较不喜欢写网络上都有的东西的。google搜一下全都是的我就没必要再去多写一份了。所以我来列一些不错的区块链学习网站。

资料分享

Awesome Blockchain

最快的当属 Awesome 系列

比特币

《精通比特币》,这本书讲解了比特币的相关知识,有能力的同学最好读英文原版,这本书的第二版已经出来了。

精通比特币

以太坊

《精通以太坊》,该书还未写完,不过现在已经可以在github上看了。

ethereumbook

《以太坊白皮书》,官方文档。

以太坊白皮书-中文

智能合约(Dapp)

如果学习智能合约只推荐“CryptoZombies”,这个网站会带你学习solidty,并带你使用siolidty来写一个区块链小游戏。目前出到了第五章,第六章会讲解如果将智能和约部署到以太坊。学完你就可以做一个区块链养猫了。

还有一个学习的网站,朋友推荐给我的,纯英文而且后期需要付费。

newline

社区

EthFans

结语

先分享这些,后续再补充。

疯狂的是数字货币,随之是区块链,与后者相比前者疯狂到无法形容,这是我的人生经历中让我咋舌的事件。我没经历过郁金香事件,也没有领略过股灾的残酷,但是身在数字货币前沿,作为一个数字货币从业者,我却感受到了他的疯狂。

2016年末,我加入到比特别中国,曾经的比特币价格大概8000元,我没有币圈信仰也不能预测今后比特币是跌是涨,所以一直没买入比特币,因此将公司发的比特币都直接兑现了。因为比特币升值过快,政府也约见了三大交易所的管理层,这才稍稍降温。

但是人们的疯狂是压不住的,这也只是政府的缓兵之计。而这个缓兵之计把比特币推上各大媒体,让资本开始关注比特币。马克思曾说过:资本如果有百分之五十的利润,它就会铤而走险;如果有百分之百的利润,它就敢践踏人间一切法律;如果有百分之三百的利润,它就敢犯下任何罪行,甚至被绞死的危险。然而比特币利润远远高于百分之三百。

大概17年中旬币价飞涨,政府和媒体更加关注了,于此同时以太坊以及山寨币趁着东飞连涨一波。

资本靠买卖套利,收益更高的还有圈钱,以太坊的ERC20为圈钱提供了更好的工具,只要写一个白皮书就可以做到一本万利,也是这波ICO让政府放弃了监管数字货币,而是直接宣布ICO是犯法的,交易所也紧接着被关停。比特币从此去中国化,也是在此我卖出了所有的数字货币。这之后也是让人感觉到疯狂的是,比特币连涨到10万人民币,这也是币圈在去中国化时坚信的。

如果你看一下比特币的价格曲线,你会为此感到震惊。人民会为了资本变得疯狂。进来的还想投入更多,没进来的疯狂挤入。然而庄家一波波的割着韭菜,一些不贪心的赚到了满意的钱早早离场。有入场后悔的,有没入场后悔的。我也后悔,后悔币卖早了,后悔没有买更多,心是会红的,明明知道是骗局也想要进去,无非是还没有财务自由,还得努力多打拼几年,可是最终我能得到是不浮躁心。怎么说,算是安慰自己吧。所以在去中国化后,就再也没有买过,虽然已经有很多c2c平台。

资本主义,财富不能共享。社会主义困苦一起分担。大道之行也,天下为公。这世界就是还真是有趣。

有钱很好,还是脚踏实地的走比较好,一生一辈子做不了多少事情。

0x00

我说,如果想操纵时间那肯定要操纵空间。两量车,出发时间间隔20分钟,那么两车之间距离是是一定的,如果想超过前面的车就要加速度。追上前面车时,可以说空间相同,这时时间是否相同?我想不出来,也不知道该怎么研究,相对论、穿越时间太深奥了,不过相信有一天会做到的。

0x01

搞些区块链的东西,比如做个区块链象棋,发个代币,没给人初始都有一些代币,可以来下象棋,输的人要给赢的人一些代币,而且象棋的棋谱永远保存在区块链上,不会被篡改丢失。也可以搞搞区块链抽奖,用代币买随机号码,每天抽出幸运号码,给幸运者发奖励等等。总之这是个机会。

0x02

你能想多远就能走多远,比如我下象棋只能像后想三步,我看数字货币只能看到眼前的涨跌,自主思考才是最重要啊。走路走多了,停下来思考思考。

0x03

观察力还是很重要的,这个和个人脑力也有关,有的人一篇文章要看十分钟,有些人只要看五分钟,还比前者提取到到信息多,主要是人家还思考了呢。

0x04

羡慕那些有梦想的人。

0x05

羡慕那些有梦想,而且仍然在努力的人。

0x06

羡慕那些已经深陷梦想,而且仍然努力着的人。

有一个很经典的故事,斯坦门次为福特公司画了一条线,收了1000美元,其中画一条线的价值是1美元,知道在哪里画条线值999美元。这个故事让我深有感触。

前些天和同时排查一个问题数据库问题,我们staging环境有一个服务总是卡死,导致一些api超时无法访问,最终排查是数据库死锁,又经过一系列排查,具体到了一个函数内,这个函数中会先去获取一个数据库的advisory lock,然后再执行SQL,这一系列操作都在try cache中,也是为了方便回滚数据库,一切看起来都没问题。

为了复现这种情况,我们手动获取advisory lock,然后触发该函数,结果卡死。找不到具体原因,另一个同事看我们讨论激烈,过来询问并一语道破,这个数据库驱动是C写的,Python并不能抓取到C中的异常,所以会一直等待释放。

真是直接命中问题所在,和这个同事相比,不是经验问题,和我同岁,工作年限比我少,为什么他可以很快解决,而我并不能。

这是一个值得思考反思的问题。

偌大的上海繁华的不着边际,随便找出个的地方也能比我家强一些。

毕业两年,加上实习也有两年半了,待过北京跑过上海,浑浑噩噩的,我也许是在互联网圈子的朋友中混的最差的了,有过太多的错误决定,不成熟也不稳重。时间推移,急躁的心也变得平静。

没有例外,只能默默自许,还年轻,急躁不得。人生不公平,理想奢侈,遥不可及。

偌大的上海,在繁华的中心,来来往往的人,不知要走向何方。记不起当初的理想,也不知该走向何方。

最后只剩

低落

低落

低落。

然后又抬起头微笑。

人生公平,有失有得。人生苦短,唯有珍惜。何必羡慕,唯有努力,即便没有方向。

2016年的最后一篇文章,势必赶在最后的两小时前写完这篇文章。

ARP 欺诈

ARP 欺诈主要是在局域网内,通过伪造 IP 地址和 MAC 地址来达到欺诈的目的,并且会在网络中产生大量的 ARP 通讯,使网络瘫痪。攻击者只要持续不断的发出伪造的 ARP 响应包就能更改目标主机 ARP 缓存中的 IP-MAC 条目,造成网络中断或中间人攻击。

怎么实现 ARP 欺诈

在网络上搜索还是能搜到具体的方法的,在此只做总结,具体实现目前也没有研究过。仅供娱乐切勿违法。

欺诈前准备

一台接入路由器的电脑,路由器会分配给你内网 IP。电脑系统最好是 Linux ,如果是 windows 大概软件会更多。

一些软件

  • ettercaps,ARP 欺诈发包软件
  • driftnet,数据包图片显示软件

在 Ubuntu 下可以直接使用 apt 来安装

使用方法

ettercaps ARP欺骗之会话劫持

加入你连接路由的网卡是 eth0,网关为 10.0.0.1,那么

1
2
ettercap -i eth0 -T -M arp:remote /10.0.0.1/ // # 欺骗局域网内所有主机
ettercap -i eth0 -T -M arp:remote /10.0.0.1/ /10.0.0.12/ # 欺骗IP为10.0.0.12的主机

这是可以使用 tcpdump 对欺诈成功后发过来的包进行抓取,使用 tcpdump

1
tcpdump -i eth0

也可以使用 driftnet 实时显示图片。

如何防御

防御还是比较棘手的,造成网络拥堵的情况下只能找到发包的主机,还有就是要绑定自己电脑的网关地址。

Python解释器

有时候我们会把 Python 的 REPL (命令行下Python的交互环境)当作解释器,它会将源代码编译为字节码并执行。Python 解释器是一个模拟堆栈机器的虚拟机,仅使用多个栈来完成操作。也可以看看 500行实现一个解释器

在解释器接手之前,Python 会执行其他3个步骤:词法分析,语法解析和编译。这三步合起来把源代码转换成 code object,它包含着解释器可以理解的指令。而解释器的工作就是解释 code object 中的指令。

code object

Python字节码

在我们导入 python 脚本时在目录下会生成个一个相应的 pyc 文件,这是 python 解释器生成的字节码,是为了加速下一次的装载。

我们写一个简单的函数,并打印其字节码

dis

1
2
3
4
5
def sample(n:int) -> bool:
if n >= 1: return True
return False

print(sample.__code__.co_code)

sample.__code__ 是与其关联的 code object,而 sample.__code__.co_code 就是它的字节码。

输出:

b’|\x00\x00d\x01\x00k\x05\x00r\x10\x00d\x02\x00Sd\x03\x00S’

这是字节码组成的字节串,让我们把它转换成二进制

list(bytearray(sample.__code__.co_code)) [124, 0, 0, 100, 1, 0, 107, 5, 0, 114, 16, 0, 100, 2, 0, 83, 100, 3, 0, 83]

看,这写依然无法理解,这时我们借助标准库 dis(自节码反汇编器) 来查看字节码

dis.dis(sample)

1
2
3
4
5
6
7
8
9
10
2           0 LOAD_FAST                0 (n)
3 LOAD_CONST 1 (1)
6 COMPARE_OP 5 (>=)
9 POP_JUMP_IF_FALSE 16

3 12 LOAD_CONST 2 (True)
15 RETURN_VALUE

4 >> 16 LOAD_CONST 3 (False)
19 RETURN_VALUE

总共分为五列,分别是

  • 字节码对应的在源代码中的行号
  • 该字节码在字节码串中的第几个字节,也就是该字节码的索引
  • 字节码的人类可读的名字
  • 字节码参数
  • 字节码参数的内容提示

再看

dis.opname[124] ‘LOAD_FAST’ dis.opname[100] ‘LOAD_CONST’

这样我们就可以和之前的字节码对应了。当然这还没有完,我们还不理解这些操作码代表什么含义,打开 python文档 搜索 LOAD_FAST,你可以看到是将 co_varnames[var_num] 放进堆栈中(更高级的目前我也是看不懂),

Python 使用两个字节表示指令参数,如果Python使用一个字节,每个 code object 你只能有256个,而用两个字节,就增加到了256的平方,65536个

Frame

Frame 包含了一段代码运行所需要的信息与上下文环境。Frame 在代码执行时被动态地创建与销毁,每一个 Frame 的创建对应一次函数调用,所以每一个 Frame 都有一个 code object 与其关联,同时一个code object 可以拥有多个 Frame,因为一个函数可以递归调用自己多次。

比如你有一个函数递归的调用自己10次,这时有11个 frame。总的来说 Python 程序的每个作用域有一个 frame,比如每个 module、每个函数调用、每个类定义。这跟数据栈是不同的。

未完待续

It’s interesting

Python 扩展

Python 和 C 粘合性很好,用 C 给 Python 添加扩展一般是性能问题,另外就是想要加密部分可以编译成二进制,保证源码不会泄露。

C Extending Moudle

C 扩展大概就是使用 Python 提供的方法将 C 代码在封装一遍。Python 提供了 Python.h 头文件,使用这些接口将 C 进行包装,最后编译成 so 文件(在windows下是dll)

编写 C 扩展需要三部分,缺一不可。

  • 导出函数
  • 方法列表
  • 初始化函数

Example

最主要的是先封装C函数,接下来举个例子,我的系统是 Ubuntu 14.04,Python2.7

定义函数

比方用 C 写一个两数相加的方法 plus,文件名为 sample.c

1
2
3
4
int plus(int n, int m)
{
return n + m;
}

导出函数

将该方法使用 Python 提供的API封装,首先导入头文件 Python.h

1
2
3
4
5
6
7
8
9
10
#include <Python.h>

static PyObject* wrap_plus(PyObject* self, PyObject* args)
{
int n, m, result;
if (!PyArg_ParseTuple(args, "ii:plus", &n, &m))
return NULL;
result = plus(n, m);
return Py_BuildValue("i", result);
}

所有的导出函数都返回一个 PyObject 指针,如果对应的C函数没有真正的返回值(即返回值类型为void),则应返回一个全局的 None 对象(Py_None),并将其引用计数增 1

1
2
3
4
5
PyObject* method(PyObject *self, PyObject *args)
{
Py_INCREF(Py_None);
return Py_None;
}
  • PyObject 是一个能表示任何Python对象的C数据类型
  • PyArg_ParseTuple() 函数被用来将Python中的值转换成C中对应表示
  • Py_BuildValue() 函数被用来根据C数据类型创建Python对象
  • 更多接口查看文档

PyArg_ParseTuple 更多类型请看文档, ii,表示args的长度必须为2,且必须为int类型

方法列表

1
2
3
4
static PyMethodDef sampleMethods[] = {
{"plus", wrap_plus, METH_VARARGS, "Return n plus m"},
{NULL, NULL}
}
  • 方法列表中的每项由四个部分组成:方法名、导出函数、参数传递方式和方法描述
  • 方法名是从Python解释器中调用该方法时所使用的名字
  • 参数传递方式则规定了Python向C函数传递参数的具体形式,可选的两种方式是METH_VARARGS和METH_KEYWORDS
  • {NULL, NULL} 标识结束

初始化函数

1
2
3
4
5
void initsample()
{
PyObject* m;
m = Py_InitModule("sample", sampleMethods);
}

构造 module 也可以使用 PyModuleDef_HEAD_INIT 和 PyModule_Create(官方这么写的)

编译链接

gcc -fpic -c -I/usr/include/python2.7 -I /usr/lib/python2.7/config-x86_64-linux-gnu sample.c gcc -shared -o sample.so sample.o cp sample.so /python/python/site-packages/

或者使用 distutils 安装

参考

rsync 使用

当我还在使用 pycharm 做开发的时候,经常会使用 rsync 来同步本地和服务器上的代码,因为比传统的 scp 更为节省流量,只上传有改动的部分。

Usage

只简单介绍,毕竟文档是最好的老师。rsync 包括服务器端和客户端,服务器可以指定相应配置文件。

rsync –daemon –config=/path/to/rsyncd.conf

可以配置权限以及应用的启动信息。使用默认配置即可。

rsync 支持 ssh、scp 等文件传输方式,也可以直接使用 socket 连接来传输。那么举个例子(Unix 环境下)

rsync -avz -e “ssh -p $portNumber” user@remoteip:/path/to/ /local/path/

我使用 ssh 协议,将本地的 /local/path/ 同步到 远端服务器 /patg/to/ 下。

  • a 相当于 rlptgoD,r 是递归、l 是链接文件、p 表示保持文件原有权限、t 保持文件原有时间、g 保持文件原有用户组、o 保持文件原有属主、D 相当于块设备文件
  • z 传输时压缩
  • v 传输时的进度信息
  • e 制定使用 rsh,ssh 方式进行数据传输

rsync 算法

rsync 核心算法是 rolling checksum,核心在 rolling 上,把文件按照相同大小分块,然后分块 checksum,来比较每一块的 checksum 有没有改变。

如果这样,改变文件中间的一个字节,后面的每块都会改变。所以关键在意 rolling 上。当找不到匹配时,算法就要向后移一个字节。知道找到匹配为止。

不盗图了,传送门 https://coolshell.cn/articles/7425.html

如果是这样的话,当文件越多时,所需要花费的时间越长。同步代码使用还是可以的。如果是需要发布的代码还是建议使用 git hook。