深入了解CPU架构
1. CPU是什么
中央处理单元(CPU)主要由运算器、控制器、寄存器三部分组成,从字面意思看运算器就是起着运算的作用,控制器就是负责发出CPU每条指令所需要的信息,寄存器就是保存运算或者指令的一些临时文件,这样可以保证更高的速度。
CPU有着处理指令、执行操作、控制时间、处理数据四大作用,打个比喻来说,CPU就像我们的大脑,帮我们完成各种各样的生理活动。因此如果没有CPU,那么电脑就是一堆废物,无法工作。移动设备其实很复杂,这些CPU需要执行数以百万计的指示,才能使它向我们期待的方向运行,而CPU的速度和功率效率是至关重要的。速度影响用户体验,而效率影响电池寿命。最完美的移动设备是高性能和低功耗相结合。
2. CPU的架构
从CPU发明到现在,有非常多种架构,从我们熟悉的X86,ARM,到不太熟悉的MIPS,IA64,它们之间的差距都非常大。但是如果从最基本的逻辑角度来分类的话,它们可以被分为两大类,即所谓的“复杂指令集”与“精简指令集”系统,也就是经常看到的“CISC”与“RISC”。
Intel和ARM处理器的第一个区别是,前者使用复杂指令集(CISC),而后者使用精简指令集(RISC)。属于这两种类中的各种架构之间最大的区别,在于它们的设计者考虑问题方式的不同。
我们可以继续举个例子,比如说我们要命令一个人吃饭,那么我们应该怎么命令呢?我们可以直接对他下达“吃饭”的命令,也可以命令他“先拿勺子,然后舀起一勺饭,然后张嘴,然后送到嘴里,最后咽下去”。从这里可以看到,对于命令别人做事这样一件事情,不同的人有不同的理解,有人认为,如果我首先给接受命令的人以足够的训练,让他掌握各种复杂技能(即在硬件中实现对应的复杂功能),那么以后就可以用非常简单的命令让他去做很复杂的事情——比如只要说一句“吃饭”,他就会吃饭。但是也有人认为这样会让事情变的太复杂,毕竟接受命令的人要做的事情很复杂,如果你这时候想让他吃菜怎么办?难道继续训练他吃菜的方法?我们为什么不可以把事情分为许多非常基本的步骤,这样只需要接受命令的人懂得很少的基本技能,就可以完成同样的工作,无非是下达命令的人稍微累一点——比如现在我要他吃菜,只需要把刚刚吃饭命令里的“舀起一勺饭”改成“舀起一勺菜”,问题就解决了,多么简单。这就是“复杂指令集”和“精简指令集”的逻辑区别。
在树莓派arm上运行golang和c程序
transmission编译安装和golang_rpc的调用
golang_runtime函数调用信息
函数的调用信息是程序中比较重要运行期信息, 在很多场合都会用到(比如调试或日志)。
Go 语言 runtime
包的 runtime.Caller
/ runtime.Callers
/ runtime.FuncForPC
等几个函数提供了获取函数调用者信息的方法.
这几个函数的文档链接:
runtime.Caller的用法(常用)
函数的签名如下:
1 | func runtime.Caller(skip int) (pc uintptr, file string, line int, ok bool) |
runtime.Caller
返回当前 goroutine
的栈上的函数调用信息. 主要有当前的pc
值和调用的文件和行号等信息. 若无法获得信息, 返回的 ok
值为 false
.
golang闭包的坑
1. 循环内goroutine使用闭包
1 | func main() { |
改进:
1 | func main() { |
不会rebase就等于没学过Git
什么是rebase
Rebase对于很多人来说是一个很抽象的概念,也因此它的学习门槛就在于如何了解这个抽象的概念。对于rebase 比较恰当的比喻应该是「移花接木」,简单来讲把你的分支接到别的分支上,稍后我们用几个图来示范merge与rebase 的差异。
了解rebase之前,我们必须了解什么是base。对Git的使用者而言,在分支中进行开发活动是稀松平常的事情,也因此在合并管理分支时,也就需要了解分支是在哪个时间点哪个提交点分出来的旁支,而长出旁支来的提交点,对于旁支来说就是base commit,也就是base。所以简单来说,rebase其实就是改变分支的base的功能。
下图是在merge的情况会产生的版本演进的示意图,可以看到在新的分支中所做的变更,在合并之后,一并成为一个新的提交(commit 6)。而commit 1就是New Branch的base。
使用esayrsa生成ssl证书
下载release版本
https://github.com/OpenVPN/easy-rsa/releases
配置公钥基础设施变量
1 | cp vars.example vars |
修改内容示例
1 | set_var EASYRSA_REQ_COUNTRY "CN" |
linux开启ftp服务和golang实现ftp_server_client
linux 安装 ftp 服务
1 . 安装ftp
1 | sudo apt-get install vsftpd |
- 修改配置 sudo vi /etc/vsftpd.con
1 | local_root=/home/ftpuser |
- 添加ftp用户
1 | mkdir /home/ftpuser |
- 调整文件夹权限
1 | chown ftpuser:ftpuser /home/ftpuser/ |
- 修改pam.d/vsftpd
1 | sudo vi /etc/pam.d/vsftpd |
- 连接
1 | ftp://207.246.80.69 //通过浏览器访问 |
golang优雅的关闭channel
- golang 没有简单普遍的方式来检查channel是否已经关闭了
- 关闭已经关闭的channel会导致panic
- 发送值到已经关闭的channel会导致panic
一个channel 关闭的原则是不要从接收端关闭channel,也不要关闭有多个并发发送者的channel。【别人可能还写呢】
换句话说,如果sender(发送者)只是唯一的sender或者是channel最后一个活跃的sender,那么你应该在sender的goroutine关闭channel,从而通知receivers(接收者们)已经没有值可以读了。