开发者
2021-07-21
常见的进制:
- 二进制, Binary /ˈbaɪnəri/, bin /bɪn/
除了苏联设计过的一种计算机系统采用了平衡三进制(-1, 0, 1), 所有计算机系统都是采用的二进制, 二进制计算是程序员的一种必备技能, 其重要性不言而喻。
常见的数字 16(四位), 256(八位), 1024(十位)等。
- 八进制, Octal /ˈɒktl/, oct /ɒkt/
- 十进制, Decimal /ˈdesɪm(ə)l/, dec /dek/
十进制普遍认为是基于人类手指数量来设计的, 其深深的影响了我们的计算方式, 已经作为人类基本的数学认知。
- 十六进制, Hexadecimal /ˌheksəˈdesɪml/, hex /heks/
二进制计算机系统中, 一个字节定义为八位, 那么通常的选择是采用两个十六进制数来表示, 在记忆成本和便捷性方面达到一个最好的平衡。
CPU 位数、地址总线宽度等, 通常是 4 的倍数, 比如:16 位的 8086 / 8088 有 20 位地址总线, 32 位的 386 / 486 / 奔腾 有 32 位地址总线, 64 位酷睿系列有 64 位地址总线。
那么,八进制用来干嘛?
刚才在维基百科上找到了答案:
Octal became widely used in computing when systems such as the UNIVAC 1050, PDP-8, ICL 1900 and IBM mainframes employed 6-bit, 12-bit, 24-bit or 36-bit words.
就是说早期大量机器采用了 6 位,12 位,24 位,36 位的实现,都是 3 的倍数,所以取八进制(3 位二进制数一组)来表示比较通用。
Python PythonSourceCode
2021-07-20
经过源码分析,可以得知,所有类型的定义都是通过 object.c
中的 INIT_TYPE
语句,比如 INIT_TYPE(&PyLong_Type, "int");
然后,可能是通过 SETBUILTIN("int", &PyLong_Type);
设置成内置方法。
int
类型最后就指向了一个叫做 PyLong_Type
的 PyTypeObject
类型变量。
PyTypeObject
Objects/longobject.c
PyTypeObject PyLong_Type = {
PyVarObject_HEAD_INIT(&PyType_Type, 0)
"int", /* tp_name */
offsetof(PyLongObject, ob_digit), /* tp_basicsize */
sizeof(digit), /* tp_itemsize */
0, /* tp_dealloc */
0, /* tp_vectorcall_offset */
0, /* tp_getattr */
0, /* tp_setattr */
0, /* tp_as_async */
long_to_decimal_string, /* tp_repr */
&long_as_number, /* tp_as_number */
0, /* tp_as_sequence */
0, /* tp_as_mapping */
(hashfunc)long_hash, /* tp_hash */
0, /* tp_call */
0, /* tp_str */
PyObject_GenericGetAttr, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
Py_TPFLAGS_LONG_SUBCLASS, /* tp_flags */
long_doc, /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
long_richcompare, /* tp_richcompare */
0, /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
long_methods, /* tp_methods */
0, /* tp_members */
long_getset, /* tp_getset */
0, /* tp_base */
0, /* tp_dict */
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
0, /* tp_init */
0, /* tp_alloc */
long_new, /* tp_new */
PyObject_Del, /* tp_free */
};
其中所有的方法就在 PyMethodDef long_methods
、PyNumberMethods long_as_number
中。
尤其是 long_as_number
可能就是那些重载操作符的基础。
long_new
和 long_new_impl
可能是 int
方法对应的实现。
OpenStack
2021-07-19
部署方式汇总
- 手动部署
- 部署脚本,也就是将手动部署的过程转化为脚本
- 使用自动化工具部署
而工具又有很多,比如:
- openstack-chef
- openstack-ansible
简称 osa
- puppet
- Fuel 很早的一个解决方案,
- Kolla
采用 k8s 技术
- DevStack
- PackStack
来自红帽的 rdo 项目,用于 OpenStack 在 RHEL 系统上的部署。
以最新的 wallaby 为例。
通过 DevStack 来弄。
就体验来说,在 devstack 的使用上,有需要改进的地方:
- 离线安装(提前准备好安装包和仓库)
- 出现异常的重试
- 日志还是写到文件中去的好
- 进度不友好
如果要开发有一定规模的相关项目,还是自己维护一组脚本,或者定制某个部署工具比较合适。
个人
2021-07-19
最近看了腾讯课堂和开课吧的几个 IT 方面的教学课程,都是视频 + 资料分享,可能还有课后作业之类的。
最后我的感受就是,这种学习方法非常不适合我,有可能是不适合大多数人。
如果我看书,当然,应该是合适的书,效率会更高。我浏览目录就可以知道应该重点看哪里,而跳过我知道的,或者对我帮助不大的地方,而现在的视频却很难做到通过一个大纲来实现跳转。更要命的是培训方希望教学能够覆盖更多的人,往往在一些基础知识方面花费太大力气,而直播又无法跳过,简直是谋财害命。更更要命的是,经常在深入之后,对正式的专业知识的讲解,进度又拉的很快,几句话带过(可能体验课也就只能这样吧)。
我也看到有一些课程是类似抖音短视频的风格,一个短视频一个知识点,然后通过播放列表可以实现跳转,我觉得这种方式会好的多。
经过反复思考,我觉得适合我的学习方式,还是先整理出一个大纲,然后找到合适的资料,一边看资料,一边敲代码。
如果有第三方组织真的有真材实料,然后可以给我合理的建议,设计出恰当的学习计划,给我做答疑和指导,我会付费,价格合理的话。
在自学方面,往往会摸索很久才会找到一条合适的路,如果可以得到正确的引导,那么效率就会提升很多。
requests
2021-07-15
今天使用 requests 时发现居然报错:Failed to parse: http://xxxxx
重要的是我不是直接是用 requests,而是使用另一个工具库,然后它来使用 requests 发起网络请求,所以我就完全没有想到着一层。更重要的是代码之前运行的好好的,没有任何问题。而且 requests 这样一个通用的库,谁能想到它会有问题呢?
我怀疑了好多情况,比如防火墙,代理,网络环境等等,但是没有找到原因。最后开始看工具库的源码,看到头都大了,也没有一点发现。
最后还是在 StackOverflow 上看到有人提醒,可能是 requests 下面的 urllib3 依赖里面有点什么问题,建议先升级一下看看。一试果然好了。
我没有仔细分析其具体原因,留给记录,下次遇到类似问题要小心。
服务器 Redis
2021-07-15
先将命令写在 commands.txt 中,一行一个,不用分号结尾,然后:
echo commands.txt | redis-cli -h 127.0.0.1 -p 6379
Linux scp
2021-07-15
背景:有一个服务会定时读某个目录下的文件,然后逐个进行处理。
今天出于某些原因,我通过 scp 拷贝文件到那个目录下,结果意外的发现服务挂掉了,就是因为读到了一个空文件,抛出一个没有被处理的错误。
我知道这是程序设计上存在的一个缺陷,但之前我们一直通过 rsync 在传输文件,从来没有遇到过这样的问题。
我查了文档并进行了实验,确认了 rsync 会在文件传输时创建一个 .文件名.随机串
的临时文件,然后在传输完成后重命名。而 scp 则不会这样做,它会创建空文件,然后逐渐填充内容。
If the target file does not yet exist, an empty file with the target file name is created, then filled with the source file contents. No attempt is made at "near-atomic" transfer using temporary files.
我的理解是,文档里面说的 near-atomic
应该就是指 rsync 那种模式,而 atomic 的意思应该是指连临时文件都不用创建的模式。也不知道有什么文件系统支持这种模式。
服务器 操作系统 Linux CentOS Debian Ubuntu
2021-07-15
列一下常见的服务器操作系统。
开发者 Copilot AI
2021-07-14
七月二号发了一篇《吊炸天的 GitHub Copilot》,我表示非常期待这种技术的到来。
但是我并不知道他们是怎么弄的,没有考虑到其 AI 采用的训练集可能涉及的版权问题。
可以看到最近针对 Copilot 产生了巨大的争议,当前开发者社区的这种申讨氛围可能会让 GitHub 放弃 Copilot。
首先,GitHub 承认 Copilot 采用公开仓库代码做训练,不论其授权协议是 GPL 还是啥。
这里面有巨大的版权风险,虽然 GitHub 官方声称不会直接复制粘贴代码,但这种可能看起来就是 “洗代码” 的行为,无法说服别人他们拥有新代码的支配权。
更何况有人拿出了一些证据来证明 Copilot 会直接 Ctrl C + Ctrl V。
最近我使用 vscode 的时候,可以看到有时它会给我一些提示,真的感觉很棒。我不想 Copilot 被抛弃,希望 GitHub 或者 Google、IBM、阿里,或别的公司或组织,能解决所有争议,提供类似的产品,更好的服务开发者。
supervisord 服务器
2021-07-13
线上服务日志中看到 Too many open files,于是检查了一番。
一、过程
确认:进程最大打开文件数
首先确认了系统没有限制最大打开文件数,但进程的最大打开文件数是限制的:
ulimit -a
core file size (blocks, -c) unlimited
data seg size (kbytes, -d) unlimited
scheduling priority (-e) 0
file size (blocks, -f) unlimited
pending signals (-i) 30007
max locked memory (kbytes, -l) 64
max memory size (kbytes, -m) unlimited
open files (-n) 655350
pipe size (512 bytes, -p) 8
POSIX message queues (bytes, -q) 819200
real-time priority (-r) 0
stack size (kbytes, -s) 10240
cpu time (seconds, -t) unlimited
max user processes (-u) 327675
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited
cat /proc/29749/limits
Limit Soft Limit Hard Limit Units
Max cpu time unlimited unlimited seconds
Max file size unlimited unlimited bytes
Max data size unlimited unlimited bytes
Max stack size 10485760 unlimited bytes
Max core file size 0 unlimited bytes
Max resident set unlimited unlimited bytes
Max processes 30007 30007 processes
Max open files 1024 1024 files
Max locked memory 65536 65536 bytes
Max address space unlimited unlimited bytes
Max file locks unlimited unlimited locks
Max pending signals 30007 30007 signals
Max msgqueue size 819200 819200 bytes
Max nice priority 0 0
Max realtime priority 0 0
Max realtime timeout unlimited unlimited us
解决方法
最后网上搜索之后,有人说 supervisor 有限制,我一检查果然是 supervisor 服务器的最大打开文件数问题:
[supervisord]
...
minfds = 65535
...
改成 655350,之后再看 proc 信息,就好了。
PS: 好像 reload
,reread
,restart
都没用,需要关闭 supervisor 重启服务才能生效。(有待进一步确认)
二、minfds
配置
官方解释:
The minimum number of file descriptors that must be available before supervisord will start successfully. A call to setrlimit will be made to attempt to raise the soft and hard limits of the supervisord process to satisfy minfds. The hard limit may only be raised if supervisord is run as root. supervisord uses file descriptors liberally, and will enter a failure mode when one cannot be obtained from the OS, so it’s useful to be able to specify a minimum value to ensure it doesn’t run out of them during execution. These limits will be inherited by the managed subprocesses. This option is particularly useful on Solaris, which has a low per-process fd limit by default.
Default: 1024
Required: No.
Introduced: 3.0
这个名字很有迷惑性,怎么看也想不到进程的最大打开文件数上面去,不过官方文档也能自洽:这是保证 supervisor 正常启动的一个最小值,相当于一个检查点。然后它会调用 setrlimit 设置子进程的最大打开文件数。