面向对象范式的历史
引言:面向对象,聚讼纷纷 面向对象编程(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 中也拥有了幽灵类型的能力。 上面的阐述是不是很难看懂?直接进入具体的例子。假设有一个飞机控制程序,操作飞机起飞或者落地。这个程序有一个非常强的业务约束,就是必须保证飞机一开始必须出现在地上,只有在地上的飞机可以起飞,只有起飞的飞机可以落地,那么应该怎样设计程序(主要是类型关系),来保证这个约束必然成立呢? 定义状态接口 先来定义...
支付业务
支付牌照是金融体系里唯一还在卖的交易拍照。 金融业务分为三大类:银行、保险、证券。 银行业分为表内和表外的业务。支付是银行业的一部分。 是不是计入资产负债表–表内、表外业务。 表外业务是银行的服务业务,毛利高。 支付是表外业务。 互联网三大赚钱业务(变现场景对应支付的三个工具): 游戏(支付工具)。 广告(大数据量级几张)。 互联网金融(电子账户和实名认证)。把银行账户体系电子化了。 货币最终是由国家发行的,铸币权是国家权力的体现。后来出现电子化货币,简化了票据类银行业务。 支付基础概念 电子支付是在付款银行和收款银行之间的货币债权转移。 支付体系的构成–基于银行卡体系的四方模式: 发卡方(服务商户,提供银行卡/二维码) 商户 收单方(服务商户。老式的 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) => { ...
把 Unix 的 Domain Socket 转成可本地访问的 TCP 端口
使用管道命令的做法: 1socat -d TCP-LISTEN:2376,range=127.0.0.1/32,reuseaddr,fork UNIX:/var/run/docker.sock 简洁的做法(使用守护进程而不是使用管道命令) 1docker run -d -v /var/run/docker.sock:/var/run/docker.sock -p 127.0.0.1:2375:2375 bobrik/socat TCP-LISTEN:2375,fork UNIX-CONNECT:/var/run/docker.sock 从容器内往外看的主机,对应外部主机就是 127.0.0.1的端口 ping docker.for.mac.localhost 通常结果是192.168.65.1。 值得参考的文: http://brieflyx.me/2015/linux-tools/socat-introduction/
银翼杀手
2049没好人。
JVM 与编译优化
Java 的编译分期,至少可以分为两个阶段(有些情况下还有额外的第三种编译过程): 编译前端(前端编译):把 *.java 变成 *.class 文件的过程。也就是把源语言文件变成中间语言文件的过程。典型的例子有:javac、Eclipse 的 ECJ 的工作过程。 编译后端(后端编译):由 JIT(Just In Time Compiler)把中间语言(字节码)转换成二进制目标体系结构机器码的过程。典型的例子有 HotSpot 的 C1、C2 编译器的工作过程。 AOT(Ahead Of Time)编译器直接把源代码编译成二进制目标体系结构机器码的过程。 早期(编译)优化 javac 自从 1.3 版本已经不再支持 -O 的优化了。所有的优化策略集中到后端编译里。这样没有经过 javac 编译的 JRuby、Jython 程序,也可以享受到 JVM 的优化福利。 javac的编译过程,大致上是: 解析和填充符号表(Parse and Enter)。 注解处理(Annotation Processing,Java 5以后加入的过程)。 分析与字节码生成(Analyze an...





