单核上的多线程-Python中的 GIL
GIL (Global Interpreter Lock)的存在虽然无法利用多核,但是可以勉强让系统在在单核上,任何一个线程使用过多时间片/主动放弃 CPU 的时候,让其他线程上下文切入进来。算是尽量跑满CPU吧。Python中的对象很多都是默认线程安全的,GIL的这种不可见的特性,让很多旧的程序依赖起 GIL,以至于无法从Python中移除掉它。GIL 的存在,让 Python 特别适合跑 Nodejs 爬虫一样的 IO 密集型(IO-bound)任务,反而不适合跑CPU 密集型任务(CPU-bound)。但实际上这种混蛋多线程的形式,恐怕还不如 EventLoop 的 Nodejs,因为多了很多 Context Switch 的代价。
面向对象范式的历史
引言:面向对象,聚讼纷纷 面向对象编程(Object-Oriented Programming, OOP)是计算机科学史上最具影响力、也最具争议性的编程范式之一。从 1960 年代 Simula 语言的诞生,到今天几乎所有主流语言都或多或少地支持面向对象特性,OOP 走过了超过半个世纪的演化之路。 然而,"面向对象"这个概念本身从未有过一个被所有人接受的统一定义。Alan Kay 认为 OOP 的核心是消息传递(messaging);Bjarne Stroustrup 强调的是数据抽象与类型层次;Luca Cardelli 和 Peter Wegner 在其经典论文中将 OOP 定义为封装、继承与多态的组合(Cardelli & Wegner, 1985)。不同的语言设计者对 OOP 有着截然不同的理解,这些理解的差异直接塑造了各自语言的面貌。 本文试图以时间为轴,以语言为线索,梳理面向对象范式从萌芽到成熟、从正统到变异的完整历史。我们将看到:每一门语言在设计 OOP 特性时,都在表达力、性能、安全性与简洁性之间做出了不同的取舍,而这些取舍本身就构成了...
Java中的幽灵类型
什么是幽灵类型 先上结论:幽灵类型(Phantom Type)顾名思义,就是幽灵般的类型,这种类型往往在运行时可以消失,因为在运行时没有任何作用,它们最大的特点就是没有任何实例(Java 的 Void 就是一个不可实例化类型的例子,常被用作幽灵类型的类型参数,如 Future<Void>)。幽灵类型是一种可以把有些运行时才能检测到的错误,在编译时检测出来的技巧。按照有些老外的观点,就是"Making Wrong Code Look Wrong"。在面向对象的编程语言之中,幽灵类型的实现,往往与状态模式较为接近,但比状态模式提供了更强的纠错功能。在 Java 5 以后的版本里,程序员可以使用泛型。通过泛型的类型参数,Java 中也拥有了幽灵类型的能力。 上面的阐述是不是很难看懂?直接进入具体的例子。假设有一个飞机控制程序,操作飞机起飞或者落地。这个程序有一个非常强的业务约束,就是必须保证飞机一开始必须出现在地上,只有在地上的飞机可以起飞,只有起飞的飞机可以落地,那么应该怎样设计程序(主要是类型关系),来保证这个约束必然成立呢? 定义状态接口 先来定义...
一段改写的超级账本的链码
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174/* * 改编自 IBM 的源码示例。 */package mainimport ( "bytes" "fmt" ...
OOM Killer
Linux 内核有个 OOM (Out of Memory) Killer 的机制,可以在系统内存不足的时候,通过主动杀死一些进程来释放更多的内存空间。 很多时候,可以 ping 通一台服务器,但无法 ssh 上去,因为 sshd 被 OOM Killer 杀掉了。ping 能 ping 通,是因为处在内核态协议栈还能工作,发出回送报文。sshd 则因为是用户态进程,直接被干掉了。 OOM Killer 工作流程 OOM Killer 的完整工作流程如下: graph TD A[系统内存不足] --> B{是否触发 OOM?} B -->|是| C[遍历所有进程] B -->|否| Z[继续正常运行] C --> D[计算每个进程的 oom_score] D --> E[应用 oom_score_adj 调整] E --> F[选择分数最高的进程] F --> G{是否启用 OOM Killer?} G -->|否| H[系统挂起...
支付业务
支付牌照是金融体系里唯一还在卖的交易拍照。 金融业务分为三大类:银行、保险、证券。 银行业分为表内和表外的业务。支付是银行业的一部分。 是不是计入资产负债表–表内、表外业务。 表外业务是银行的服务业务,毛利高。 支付是表外业务。 互联网三大赚钱业务(变现场景对应支付的三个工具): 游戏(支付工具)。 广告(大数据量级几张)。 互联网金融(电子账户和实名认证)。把银行账户体系电子化了。 货币最终是由国家发行的,铸币权是国家权力的体现。后来出现电子化货币,简化了票据类银行业务。 支付基础概念 电子支付是在付款银行和收款银行之间的货币债权转移。 支付体系的构成–基于银行卡体系的四方模式: 发卡方(服务商户,提供银行卡/二维码) 商户 收单方(服务商户。老式的 pos 机是要拓片留印记的。pos 机/摄像头) 清算方(卡组的清算机构,国内是银联,国外就是 VISA 和 MASTARCARD。银行之间形成交易指令集–形成记账。央行的清算系统来调拨真正的钱的流动。头寸只要足够,不需要准备足够多的现金。)。 四方模式既涉及支付体系,也涉及金融...
破解本博客不能部署的问题
试着生成公钥,然后一定要记得把 pubkey 粘贴到 github 的 setting 里然后用ssh ping github ssh -T git@github.com,即使返回错误也不要紧。 改用这个github 的部署地址: repo: git@github.com:magicliang/magicliang.github.io。
Linux hypervisor
hypervisor 可以被认为等于 virtual hardware。他们的出现,可以有效减少硬件服务器数量。 常见的 hypervisor 分成两类: 直接运行在硬件上的,基于内核的虚拟机。 OS as hypervisor。典型例子是 KVM。KVM 是被集成到 Linux 内核之中的完整虚拟化解决方案。 运行于另一个操作系统之上。典型的例子是 QEMU 和 WINE。 hypervisor的实现,总是要映射一些磁盘设备和网络设备的。
MariaDB 调优相关
本文主要摘译自这里。 MySQL 曾经有独立的公司。但那间公司后来被 Sun 微系统公司获取了。 Sun 微系统公司又被 Oracle 获取了。原 MySQL 开发者担心 MySQL 成为闭源软件,因此成立了一家SkySQL 公司维护开源的 MySQL 分支–MariaDB。 MariaDB 支持的存储引擎包括: InnoDB/XtraDB 后者是前者的加强版,属于事务性存储引擎,也叫 ACID-compliant(ACID 遵从的)。XtraDB 是 Percona 开发的存储引擎,整体向下兼容。使用普通的 mysqldump 会耗尽 cpu(因为要把数据库转化成正经的 SQL 语句)。而 xtrabackup 在大库上的备份、还原、冗余都表现得更好(因为像 Oracle 一样是二进制备份吗?)。 TokuDB。另一个事务性存储引擎。以高压缩率著称(最高25倍压缩)。适合小空间存储大数据。 MyISAM。MySQL 上最古老的存储引擎。非事务性存储引擎,只支持表级锁,不支持 MVCC。 SphinxSE。非事务性存储引擎。这名字和古希腊猜谜语的怪兽,斯芬克斯一样。本以上是用...
KOA 初探
KOA 是 express 的进化版。都是被作者玩腻了扔掉的东西。 它简化了各个中间件层面的工作,提供了高级的“糖”,把各个中间件转化为了函数。 123456789101112131415161718192021222324252627282930313233const Koa = require('koa');const app = new Koa();// x-response-timeapp.use(async (ctx, next) => { const start = Date.now(); // 到这里就停住了运行,让下一个中间件函数运行。 await next(); // 从下一个中间件函数那里返回 const ms = Date.now() - start; ctx.set('X-Response-Time', `${ms}ms`);});// loggerapp.use(async (ctx, next) => { ...














