自增人生

何以解忧,唯有 i++

Large Interconnected Data Belongs to a Database

如果你的应用程序要处理一个大型、持久、互联的数据集,毫不犹豫地把它们存到关系型数据库里。在过去,RSBMS(关系型数据库)使用起来很昂贵、稀缺、复杂,且最为笨重。但这已经不在是问题了。现如今,关系型数据库系统非常容易找到——就像你的系统里已经安装了一到两款。一些非常强大的RDBMS,如MySQL和PostreSQL,都是开源软件,所以开支不在是问题。更有意思的是,嵌入型数据库系统可以作为一个库链接到你的应用程序里,几乎不需要安装和管理——其中著名的开源软件是:SQLite和HSQLDB。这些系统都非常之高效。

如果你应用程序的数据已经大到超过系统内存了,RDBMS表的索引表现将比映射集合类型的库要快出几个数量级,这将破坏虚拟内存页。现代数据库产品可以根据你的需求轻松扩展。只要你需要,可以将嵌入型数据库扩展到大型数据库系统中。之后,你还可以从免费、开源的产品切换到支持更好或更强大的专有系统中。

一旦掌握了SQL,编写以数据库为中心的应用程序将会很愉快。当你正确规范地将数据存储到数据库之后,就可以通过高效可读的SQL查询来提取内容了;不需要写任何复杂的代码。同样的,单条SQL命令也可以做到复杂的数据改变。对于一次性修改——比如组织持久化数据的改变——你甚至不需要编写代码:只需启动数据库直观的SQL界面。相同的界面还允许你试验性查询,以避免常规编程语言的编译-编辑循环。

围绕RDBMS建立的代码还有个优点,就是处理数据元素间的关系。你可以通过声明的方式描述数据的一致性约束,以避免在边缘情况下忘记更新数据而获得悬空指针的风险。例如,你可以指定,当一个用户被删除后,那个用户发送的消息也应该被删除。

任何时候只要你想,都可以在数据库的实体间创建链接,简单地通过创建索引即可。不需要对类型字段做昂贵又大范围的重构。此外,围绕数据库的编程还支持多应用安全访问。这就可以很轻松地更新应用以实现并发访问,也可以使用最适合的语言和平台编写程序的部分代码。例如,你可以在JAVA中编写基于WEB的XML后段,在Ruby中审计脚本,在Processing中编写可视化界面。

最后,记住RDBMS会使尽浑身解数优化你的SQL命令的,让你专注于应用程序的功能优化,而不是算法调优。高级点的数据库甚至会充分发挥多核性能优势。随着技术的提升,你的应用程序表现也会更好。

本文源码:https://github.com/philon/rpi-drivers/tree/master/00-hello

最近打算利用手里的树莓派3B+及各种丰富的扩展模块学些一下嵌入式Linux驱动开发。我计划实现LED、温湿度传感器、陀螺仪、PS遥感、红外模组、超声波模组、光敏传感器等驱动,其目的是为了学习嵌入式Linux驱动开发的思想,以及常见的接口及模块的原理。我会把整个学习过程整理为《树莓派驱动开发实战》。当然,我的初衷是学习ARM-Linux驱动开发,如果不是必须,我不会可以强调硬件平台,而是更侧重于驱动编程和电路设计。

我的开发环境如下:

  1. 宿主机:华硕A55VM | Ubuntu18.04
  2. 开发板:Raspberry 3 Model B+ 2017
  3. 编辑器:Visual Studio Code | C/C++扩展

由于文章中会存在大量命令脚本的引用,先做个声明:

1
2
3
philon@a55v:~$ # 表示在宿主机敲出的命令

philon@rpi:~$ # 表示在开发板敲出的命令

此外,如果不是必须,我不会拿串口调试开发板,一律ssh!

准备工作

Linux驱动开发需要准备几样东西:

  • Datasheet:硬件手册,用于了解目标平台的规格/寄存器/内存地址/引脚定义等
  • 编译器:用于编译目标平台的驱动源码,嵌入式开发,一般用交叉编译器
  • 内核源码:编译驱动依赖于内核,且必须与目标平台系统内核版本一致
  • 外围电路原理图:连怎么走线都不知道,还开发个球啊!

本文不涉及真实的模块驱动开发,因此具体的外围电路等实际开发的时候再看吧,先把前三样搞到手。

树莓派3B+硬件资料

由于官网没有配套的树莓派3B+Datasheet,我只能尽可能从官网其他地方把硬件资料凑齐。任何有关硬件的资料都优先从官网找:https://www.raspberrypi.org/documentation/hardware/raspberrypi/

树莓派3B+硬件介绍

  • 处理器是BCM2837B0,64bit四核1.4GHz的Cortex-A53架构
  • 双频80211ac无线和蓝牙4.2
  • 千兆有线网卡,且支持PoE(网线供电)

电路原理图下载:https://www.raspberrypi.org/documentation/hardware/raspberrypi/schematics/rpi_SCH_3bplus_1p0_reduced.pdf

宿主机安装交叉编译器

交叉编译器选择是有套路的:<arch>-<vendor>-<target>

例如:

  • arm-linux-gnueabi-gcc 表示arm32位架构,目标可执行文件依赖Linux+glibc
  • arm-linux-gnueabihf-gcc 表示arm32位/硬浮点数处理架构,其他同上
  • aarch64-linux-gnueabi-gcc 表示arm64位架构,其他同上

所以在选择交叉编译器之前要先确定开发板的处理器及操作系统环境:

1
2
philon@rpi:~ $ uname -a
Linux rpi 4.19.42-v7+ #1219 SMP Tue May 14 21:20:58 BST 2019 armv7l GNU/Linux

注意最后的armv7,尽管RPi-3B+的处理器平台是64位4核,不过它的操作系统是32位的,所以应该安装arm32位glibc的交叉编译器。

1
philon@a55v:~$ sudo apt install gcc-arm-linux-gnueabihf

宿主机构建内核源码

Linux驱动模块的编译依赖于内核源码,而且要注意版本问题。之前在开发板上查看Linux版本时已经知道其运行的内核是Linux rpi 4.19.42-v7+。所以最好是去官网下载对应版本号的内核源码。

1
2
3
4
5
6
7
8
9
10
# 下载内核源码
philon@a55v:~$ wget https://github.com/raspberrypi/linux/archive/rpi-4.19.y.tar.gz
# 解压,进入内核目录
philon@a55v:~$ tar xvf rpi-4.19.y.tar.gz && cd linux-rpi-4.19.y
# 清理内核
philon@a55v:~/linux-rpi-4.19.y$ make mrproper
# 加载RPi-3B+的配置
philon@a55v:~/linux-rpi-4.19.y$ make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- bcm2709_defconfig
# 预编译
philon@a55v:~/linux-rpi-4.19.y$ make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- modules_prepare -j8

【题外话】:很多教程都是先把内核完整编译一遍,再拷贝各种头/库文件到目标平台,其实没必要,预编译内核即可。从内核官方文档可以看到这样一段话:

=== 2. How to Build External Modules
To build external modules, you must have a prebuilt kernel available
that contains the configuration and header files used in the build.
…
An alternative is to use the “make” target “modules_prepare.” This will
make sure the kernel contains the information required. The target
exists solely as a simple way to prepare a kernel source tree for
building external modules.
NOTE: “modules_prepare” will not build Module.symvers even if
CONFIG_MODVERSIONS is set; therefore, a full kernel build needs to be
executed to make module versioning work.

简而言之,如果要构建外部驱动模块,内核必须有相关的配置及头文件。可以用“modules_prepare”准备内核源码树,这也仅仅用于构建外部驱动模块,但不会生成“Module.symvers”。

第一个树莓派驱动

入门例子当然是留给HelloWorld啦!

创建工程目录:

1
2
3
4
# 创建目录,进入
philon@a55v:~$ mkdir -p drivers/00-hello && cd drivers/00-hello
# 创建驱动模块源码及Makefile
philon@a55v:~/drivers/00-hello$ touch hello.c Makefile

hello.c

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <linux/init.h>
#include <linux/module.h>

static int __init hello_init(void)
{
printk("hello kernel\n");
return 0;
}
module_init(hello_init);

static void __exit hello_exit(void)
{
printk("bye kernel\n");
}
module_exit(hello_exit);

MODULE_LICENSE("GPL v2"); // 开源许可证
MODULE_DESCRIPTION("hello module for RPi 3B+"); // 模块描述
MODULE_ALIAS("Hello"); // 模块别名
MODULE_AUTHOR("Philon"); // 模块作者

Makefile

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# 模块驱动,必须以obj-m=xxx形式编写
obj-m = hello.o

KDIR = ../linux-rpi-4.19.y
CROSS = ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf-

all:
$(MAKE) -C $(KDIR) M=$(PWD) $(CROSS) modules

clean:
$(MAKE) -C $(KDIR) M=`pwd` $(CROSS) clean
````

```sh
# 编译内核
philon@a55v:~/drivers/00-hello$ make
# 将内核模块ko远程复制到开发板
philon@a55v:~/drivers/00-hello$ scp hello.ko rpi.local:/home/philon/modules/

# 开发板加载hello模块
philon@rpi:~/modules $ sudo insmod hello.ko
# 卸载内核
philon@rpi:~/modules $ sudo rmmod hello
# 查看内核打印信息
philon@rpi:~/modules $ dmesg | tail -5
[ 1176.602268] Under-voltage detected! (0x00050005)
[ 1182.842326] Voltage normalised (0x00000000)
[ 4731.671023] hello: no symbol version for module_layout
[ 4731.671042] hello: loading out-of-tree module taints kernel.
[ 4731.672307] hello kernel 👈看到没,就是它了!
[ 5010.908453] bye kernel

Know Your Next Commit

我轻轻拍着三个程序员的肩膀并问他们在做什么。“我在重构这些方法”,第一个程序员说。“我在为这些web动作添加一些参数”,第二个程序员说。而最后那个程序员却说:“我正在研究这个用户故事。”

前两个程序员貌似都专注于细节,只有第三个能看到更大的画面,显然后者的聚焦更棒。然而,当我问何时提交什么,情况就发生了变化。前两个十分清楚会涉及到哪些文件并在一小时左右完成。第三个程序员的回答基本上是这样的:“噢!我应该要准备几天时间。我可能要增加几个类,并改变现有的服务机制”。

前两个缺乏全局视角。他们选择由生产方向引领的任务,并可以在几小时内完成。完成这些任务后,他们会选择实现新功能或者重构。所有代码都有明确的用途、范围、可实现的目标。

第三个程序员没有分解问题,同时处理所有部分。他无法采取任何措施,基本上只能投机性的编程,寄希望能够让某些点达到可以提交的程序。最终这个花长时间讨论后才开始写的代码,极有可能与终极解决方案相差甚远。

如果前两个程序员的任务会花费两小时以上,他们会怎么做?意识到自己承担太重后,他们最有可能抛弃他们的变更,定义更小的任务,然后重新开始。因为保持原样的话会找不到重点,从而导致投机性代码提交进仓库。相反,变更被抛弃了,但对其中的洞悉却得到保留。

第三个程序员则可能继续瞎猜,拼命尝试给他的变更打补丁,以拼凑成可以提交的内容。毕竟,你又不能抛弃已经完成变更的代码——那就等同于之前的努力白费了,不是么?悲剧的是,不抛弃这些代码将进一步导致那些目标不明确的诡异代码提交到仓库。

某些时候,即使“聚焦提交”的程序员也可能无法找到自认为可以在两小时内完成的有用内容。然后,他们会进入投机模式,开始调戏代码,一旦有所洞悉,他们就会回到正轨,并抛弃之前的变更。即便这些看似凌乱的黑客会议也是有目的的:为了了解定义出能够形成高效任务的代码。

知道你的下次提交。如果你无法完成,就抛弃这次变更,然后通过你的见解,定义靠谱的任务。如果有需要,就做那些投机性上演,但要注意别掉到投机模式的坑里。不要提交猜测性的工作到你的仓库里。

隋唐(581年-907年),是中国经历了400年的长期分裂后迎来的一次大统一,而且是享誉古今中外的大唐盛世。那么,为什么是唐朝?这个时代具有什么样的特色让它不可一世?这一切都值得我们去探索。

隋唐接力棒

隋朝之前是南北朝,南北朝是一个统称:

  • 南朝是之前西晋的延续,由汉人统治的中国,包括宋、齐、梁陈等四朝;
  • 北朝是五胡乱华的后续,包括北魏、东魏、西魏、北齐、北周等五朝;

上述的朝代即包括同时期的不同地方分裂,也包括不同时期的朝代更迭。还有,晋朝传递下来的分封和士族世袭等制度或观念,在南朝得到延续,导致贵族越来越昏庸无能,政治腐败,国家战乱连连。所以说就一个字——乱!

混血儿杨坚

杨坚是鲜卑化的汉人,效力于北周皇帝,各种南征北战,之后升官拜相。集军政大权于一身后,逐步废掉北周皇帝,自立为帝,建立隋朝。接着北灭突厥,挥师南下,伐西梁、亡陈朝,自此统一全国。

一统江山之后,隋文帝杨坚还干了几件了不起的事:

  • 【府兵制——军改】平时为民,战时为兵;兵不识将,将不知兵。既解决了绝响,由杜绝了军阀。
  • 【五省六部制——权利制衡】:废除九品中正制,各省间负责最高指示,各部负责国家业务划分,没有谁能独揽大权。
  • 【科举制——人才选拔】:通过考试选拔人才,不问出身门第。
  • 【施仁政——利国利民】:通过再三减税、罢盐/酒专营,推行均田制,导致经济和人口大幅增长。

这是从人治到法治的转变,通过各种制度与制衡确保国家行政机器能有效运转。隋文帝杨坚淡化了统治阶级的存在感,换而言之,不论谁走马上任,只要不昏庸至极,都能在流程制度上不出什么大乱子。

李唐登场

隋文帝死后,儿子杨广即位,也就是大名鼎鼎的隋炀帝,“炀”这个溢号是唐朝李渊给封的,意思就是昏庸无能至极的暴君,是对死后皇帝最狠的差评。当然,这里有刻意抹黑对手的嫌疑,杨广没有那么不堪,但他真的很像秦始皇。

具体说来,隋炀帝在位时,打通南北大运河(从杭州到北京,全场2700多公里),重建东都洛阳,东征西讨,西至如今的新疆,东至如今的朝鲜,北至如今的蒙古,中华版图翻倍。然而,这一切丰功伟绩的背后是无数百姓的世故血汗。

如此激进又冷血的皇帝,对于当时的人来说,只能是民怨四起,本效力于隋朝的李渊反了,在晋阳发起兵变。晚年的隋炀帝已无力控制全国,李氏父子出生入死一口气推翻了大隋政权。

自此,李渊称帝,国号为唐。但是在立太子问题上出岔子了,唐高祖立嫡长子李建成为太子,从自古继承规矩而言没问题。可大唐的江山有一半是他李世民打下来的,结果便宜了哥哥,有没有搞错!所以李世民一手炮制玄武门之变,手足相杀,逼父禅让。此后便是唐太宗李世民的时代,华夏文明也迎来自古以来的最强时代!

开放,是一种大国自信

隋唐和秦汉发展轨迹太像了,秦、隋都作为巨大革命的试验品二世而亡,紧随其后的汉、唐不但继承了他们的衣钵,更是迎来了空前盛世。最强大唐帝国的版图比现代中国还要辽阔。周边的蛮夷戎狄无不臣服于大唐,当年的李世民不仅仅是中华的天子,更是周边游牧民族心中的天可汗(可汗是最高领袖的意思,而天可汗似乎更上一层)。

当然,这仅仅是唐朝在军事和外交方面的成绩,在笼络人才方面也真是做到极致了。举个例子:日本的仲麻吕、阿拉伯的李彦升、朝鲜的崔致远都先后在中国考取进士…一个国家的重要公职人员居然是个老外,放在今天你能想象吗?关键人家对中华的儒家思想、文化历史了解的比你还深,吟诗作对更是信手拈来。能多次出现这种现象绝非偶然,是整个中亚圈对中华文明的崇敬与向往,实际上唐朝年间有大批的国外使者留学生常驻中国,学习中华文化(这背后也可能是大唐常年对外国使者高规格免费招待的政策所赐)。

民间社会呢?丝绸之路的强盛,国土向西的扩张,对外来人口的宽松政策,导致整个长安城直接进化为全球最强悍的国际大都市,不会两句外语都不好意思和人打招呼。长安街有两个商圈,一个叫东市一个叫西市,全球的奇珍异宝不在东便在西,老百姓的日常购物也被称为“买东西”。唐朝女子穿起胡服,尽显婀娜曲线,后来更是学着波斯、吐蕃、中亚等异国风情,戴耳环、梳髻堆、化面赭(一种脸妆),穿着也越露越多。不论男女都喜欢骑马踏青打马球。长安街边各种老外开的西餐厅,各种高档会所组织派对,跳着胡旋舞,奏起龟兹乐。酒过三巡,还有一个个名闻天下的诗人慷慨激昂,真是葡萄美酒夜光杯啊~

唐朝的开放是什么?政策的宽松,思想的解放,身份的认同,文化的融合。是的,唐朝总体上给人一种“来者不拒”的感觉,不论你要吟诗骂国、诵经传教、纸醉金迷、偷师学艺、悬梁刺股,请自便。大唐不介意文化输出还是输入,也许来者不善各怀鬼胎,但民间盛世空前,一路路金戈铁马,英姿煞爽的天子/天可汗,你奈我何?是的,唐朝不是因为开放而强大,相反,是强大的唐朝自然而然走向了开放。开放,是一个国家对自己富强的认同,是最低调的炫富行为。

大唐的漏洞

我们知道,唐朝实行的三省六部制,分权制衡的策略,是站在法治的角度把国家看错是一部高效运转的行政机器。所以各种政策的制定都有一个宏观目标,即不论职位上的人是谁,包括皇帝在内,他的权力都会受到相应的制约,以确保不会范下滔天大罪。相比于隋唐之前,这明显是从人治到法治的进化。但唐朝的制度却留下了三大bug:女人、宦官、藩镇。

我们把天下比做一个家,家里的兄弟就好比整个朝廷官僚体系,唐朝的制度就是为这些兄弟量体裁衣制定的,就是为了防止将来分家产鱼死网破。结果到好,兄弟们的行为都被限制住了,家里的儿媳妇开始冒头。到了后期,家里的保姆管家也开始气焰嚣张了。紧接着各方亲戚也上蹿下跳,这个家也就摇摇欲坠了。

女人就如武则天这类的后宫儿媳妇,保姆管家就是朝内的太监宦官,亲戚就是藩镇到军阀。

其实可以这么理解,在古代,天下的产权都归皇帝一个人,但产权是产权,使用权是使用权啊。皇帝可以把自己的权力分给朝臣们代理行使,唐朝的制度只是避免了名以上的产权拥有者和代理行使者的纠纷,实际上参与代理皇权的人还有很多,一句枕边话,一个确认过的眼神,都可以对皇帝的决策产生重心偏离。久而久之,皇帝被架空,重臣也可以被架空。

我们不好这件事是对是错,但也幸好这样,中国才得以有个女人当皇帝,为整个中华历史涂抹一些不一样的色彩。

武则天

我个人觉得看待武则天需要分两个角度:

  • 她是一个心狠手辣的政客,但凡敢挑战她权力地位的人,必将遭到最阴毒的攻击,在她实质掌权期间,被迫害致死的官员怕是上千了,不论这些人是君子还是小人,挡武者死!
  • 她是一代圣明君主,在她掌权下的中国大力推动科举,消灭门阀,让社会底层人才有了出头之日;同时轻徭薄赋,社会人口和经济都出现高速增长;中国的文化思想也在该时期得到最大限度的绽放。

可以说是历史选择了武则天,因为我们知道这个刚入宫的小姑娘野心勃勃,但她伺候的却是唐太宗李世民,在这个胸怀天下的天可汗眼里,一个女人算什么。李世民驾崩后,武则天被迫削发为尼进入感业寺,这就相当于政治生涯到头了。幸好她把赌注押向了那个唯唯诺诺的青少年李治,李治登基后,她按部就班回到宫中,迫害王皇后和萧淑妃,自己终于成为武皇后,这真是绝处逢生啊。

武皇后得势,以她的政治野心及权谋,搞定一个李治跟玩儿似的。于是她逐步从幕后到台前,与皇帝并称“二圣”。抚皇帝、扰后宫、废太子、杀宰相、用小人,从此平步青云,朝堂之上被儒家思想熏陶的大臣胆敢看不惯,直接把他废了。人是越杀越多,到最后整个朝廷都被她杀得没脾气了,唐高宗李治也嗝屁了。她的亲儿子立了又废,废了又杀,直到后来她的小儿子磕头认怂不敢当皇帝。只见她大喝一声:还有谁!!

一代女皇帝闪亮登场了,她机关算尽为自己的天子之路扫清障碍。上位后,武则天接着杀人,但杀的是那些曾今用过的小人。是的,当上皇帝后,她慈眉善目菩萨心肠,要还世间一个公道。所以武则天的政治生涯可分为两部分,前半生尔虞我诈,后半生安邦定国。大唐在她的手上照样太平盛世,和男性皇帝相比,恐怕只是少了些许残暴,多了几分仁慈吧。

但是,人终有一死。武则天晚年面另一个艰难的抉择:是武周还是李唐?选择改朝换代,她无疑要背上王莽篡汉般的千古骂名;选择还政于李家,那她这辈子又折腾个什么劲呢。不过她最终还是选择做李家的媳妇,给自己立了个无字碑。或许是想把评价留给后人;又或者,一个登峰造极的女人,还有必要为自己论证什么吗?

安史之乱,盛极而衰

女人的戏唱完了,就该轮到宦官和藩镇登场了。其实安史之乱没有太多内容,但它作为大唐盛极而衰的分水岭,自然有特殊的意义。

安史之乱是唐玄宗李隆基年间发生的事情,那个时候的中国幅员辽阔,但与周边少数民族的关系不一定融洽,北面突厥(今蒙古),西面吐蕃(今西藏、新疆),高句骊(朝鲜),以及丝绸之路上的今天阿拉伯、印度等地区,都多少有些摩擦。天高皇帝远,大唐设立藩镇,就是派重兵把守边疆,但赋予军权的同时,还把部分行政权也交了出去,其目的是让指挥官自行解决军饷和当地民生问题,不要让朝廷操心了。想法是好的,可这种行为其实和封建时代的诸侯分封有何区别?不过差了一张产权证而已。而且,边疆的部队及战斗力远远强于朝廷,所谓藩镇,就是军阀。

安禄山和史思明想大唐发动进攻,不过是吹响了大唐时代的战国号角,从此朝廷无宁日。雪上加霜的是,宦官乱政,这便是唐朝制度上的第三个漏洞。宦官们借着亲近皇帝的机会,左右决策。这可比女人干政要恶劣的多,媳妇再霸道好歹也是自家人,多少还会为自己的家着想。这保姆可是领死工资的,他要是掌权,还不能捞一笔是一笔,家庭兴衰,关他屁事。

所以在此后一百多年了,各种傀儡皇帝相继登场,朝廷内部开始搞起派系斗争。为官的目的不是整死各位,就是被各位整死。这样的统治阶层,能够维持一百多年,不惊讶么?其实原因有两方面:一、藩镇军阀间相互混战,给了朝廷苟延残喘的空间;二、唐朝的行政制度设计的却是好,至少在最差情况下还能勉强维持运行。

好了,易中天的隋唐这部分看完了。总而言之,唐的确是个了不起的朝代,在我看到极盛大唐的介绍时,真有一种梦回唐朝的冲动。

Know Your Limits

人需要了解自己的局限性——Dirty Harry

你的资源受限了。你只有那么点的时间和钱去工作,还需要保持你的知识、技能和工具更新迭代。你也只能是更努力、快速、灵活、更长时间地工作。你的工具也如此而已。你的目标平台性能也就如此。因此你不得不敬畏这种资源限制。

如何敬畏呢?了解你自己,了解你周围的人,了解你的预算,了解你所拥有的。尤其是作为一个软件工程师,应该了解你的数据结构和算法的时间/空间复杂度,你系统的架构及典型性能。你的工作就是创造一次软件和系统的最佳结合。

时间和空间复杂度函数给出的O(f(n)),这个n等同于输入参数趋近于无穷时,n增长的时间和空间的情况。主要的f(n)复杂度类别包括:ln(n)、n、n*ln(n)、n^e、e^n等。如下图所示,这些函数表明,档n越大,O(ln(n))总是小于O(n)和O(n*ln(n)),也比O(n^e)和O(e^n)要小得多。正如Sean Parent所说,对于可实现的n,所有复杂度类别中,要么接近常数,要么接近于线性增长,要么接近于无穷。

复杂度的分析是根据抽象机器来衡量的,但软件却运行在真实的机器上。现代计算机系统被组织为物理机和虚拟机两种架构,包括运行语言、操作系统、CPU、缓存、RAM、硬盘、网络等。下表展示了一个典型的网络服务的随机访问时间和存储能力的限制。

类型 访问时间 存储容量
寄存器 < 1ns 64b
缓存 64B
- 1级缓存 1ns 64KB
- 2级缓存 4ns 8M
RAM 20ns 32GB
磁盘 10ms 10TB
局域网 20ms > 1PB
互联网 100ms > 1ZB

要注意(不同设备)存储能力和访问速度会有几个数量级的差异。但在我们系统的每个级别都采用大量的缓存和预测来隐藏这种差异,可惜它们只有在访问可预测时才能正常工作。当缓存未命中,系统将发生颠簸。例如,随机检查硬盘的每个字节要花费32年。甚至随机检查RAM的每个字节都要花费11分钟。随机访问时不可预测的,那什么可以?这依赖于系统,但重新访问最近使用和顺序访问才是常态。

算法和数据结构所使用的缓存在效率方面各有不同,例如:

  • 线性搜索有比较好的预测,但需要O(n)次比较。
  • 二分法搜索排序数组需要O(log(n))次比较。
  • van Emde Boas树则需要O(log(n))次和cache-oblivious模型。

如何选择呢?通过最后的分析测量。下表显示了在我的电脑上,通过这三种方法搜索64位整数数组所需时间(纳秒):

数组长度 线性 二分法 vEB
8 50 90 40
64 180 150 70
512 1200 230 100
4096 17000 320 160
  • 线性搜索在小数组时很有竞争力,但在大数组情况下就不行了。
  • vEB凭借可预测访问模型赢得胜利。

1980年代,我们的编程环境没有比文本编辑器更好的了…如果我们幸运的话。现如今是被认为理所当然的语法高亮,是一种奢侈品,不是每个人都能享用的。漂亮打印器为了把我们的代码格式化好看,通常不得不运行外部工具来纠正间隔。调试器也是单独的程序,用于逐步调试代码,但需要使用很多隐秘的快捷键。

来到1990年代,为程序员提供更好和更实用的工具,驱动着公司们开始挖掘潜在收入。继承开发环境(IDE)把编译器、调试器、漂亮打印器、以及其他工具整合进之前编辑器。在此期间,菜单概念和鼠标也开始流行起来,这就意味着开发者不再需要掌握那些隐秘的组合键。他们通过菜单就可以非常容易地选择他们的命令。

21世纪,IDE已经很普遍了,公司们为了获取其他市场份额甚至免费赠送它们。现代IDE都具备一组令人赞叹的功能。我最喜欢的就是自动重构,特别是“提取方法”,我可以在方法中选择和转换一个代码块。重构工具将提取所有方法需要的参数,让修改代码变得非常简单。我的IDE甚至会检测其他的代码块是否能够替换成此方法,然后问我是否也将它们替换。

现代IDE另一个惊人的功能是可以在公司内部强制风格样式。例如Java,一些程序员开始将所有参数都设置为final(在我看来,这是浪费时间)。总之,自从它们有了样式规则,我就需要在IDE中设置它:不然我会收到任何关于non-final的警告。样式规则也可以用于找出可能的bug,比如比较自动装箱对象,确保引用的一致性,又或者,使用==会参考自动装箱的引用对象原始值。

不幸的是,现代IDE不再需要我们花精力去学习怎样使用它们。我在Unix平台完成第一个C程序时,不得不花点时间学习如何使用vi编辑器,因为它的学习曲线很陡。几年之后来看,这些时间花得很值。我甚至是用vi来起草的这篇文章。现代IDE学习曲线非常平滑,结果就是我们对其背后大量工具的基本用法上,再也得不到进步。

我学习IDE的首要任务是记住快捷键。当我手指放在键盘上敲代码时,用鼠标切换导航菜单时会中断敲代码,所以我会按下Ctrl+Shift+I来内联变量防止动作流被打断。这些中断会导致不必要的上下文切换,如果每件事都用这种笨办法,那会让我生产力非常低。同样的规则也可以用于键盘技能:学习快捷键模式,你不会后悔这次早期投资。

最后,作为一个程序员,我们拥有久经考验的Unix工具,来帮助我们操作代码。例如在代码审查期间,我要关注一个程序员是否有大量相同的类命名,我可以通过find、sed、sort、uniq以及grep等工具非常简单地实现,就像这样:

1
find . -name "*.java" | sed 's/.*\///' | sort | uniq -c | grep -v "^ *1 " | sort -r 

我们请一个管道工到家里来,是因为我们需要的是它的喷灯。所以让我们花点时间学习如何更高效地使用我们的IDE。

秦汉历时410年,之后便进入了长达400年的大分裂时期,分别是三国、西东两晋、五胡十六国、南北朝。这是怎样一个混乱的年代,而这样一个乱世又演绎了多少成王败寇,为后世留下了多少华夏精神?貌似除了三国,我们对这段历史知之甚少,大概因为太混乱了,都没人想提起。这个时期上演了无数次兵戎相见、尔虞我诈、谋权篡位、倒行逆施、改革换血,那主旋律是什么?没有,或者说混乱与迷茫本身就是这个时期的标签。还好,当新的中华文明迎来破晓,方知这是一场伟大的洗礼,是中国历史的必经之路。

不一样的三国

大概每个中国人都知道三国,但绝大部分人耳熟能详的应该是罗贯中的《三国演义》。很可惜,三国演义不过是民间文学,源于历史而高于历史。按照易中天在书中的观点,三国在整个中国历史上根本不重要,它不过是东汉末年由于王朝衰败而导致的军阀割据,只是一个顺理成章的步骤,很多朝代更迭时都会经历的短暂时期。

此外,我们津津乐道的草船借箭、温酒斩华雄、桃园三结义、关羽华容道放走曹操、诸葛亮空城计骗司马父子等等。都是虚构的!事实上,曹操是宦官养子,孙策是寒门子弟,刘备是没落贵族之后。三人的开局都不怎么样。而各种士人将军也没有那么神乎其神。赵云后期被刘备冷落无所作为,诸葛亮治国有方但军事上没有太多业绩,而关羽的各种奇迹完全是后人吹出来的,刘禅也并非窝囊废。还有曹操,少年放荡不羁,曾和袁绍一起去偷别人家的新娘子……

其实历史是这样子的,汉朝由吕后(刘邦媳妇)开辟了一种传统嘛,皇帝掌权—>太后掌权—>宦官掌权—>又回到皇帝手里,宫廷内的权力争夺就这么循环着。于是东汉末年,何太后掌权,但并不打算对宦官赶尽杀绝,于是大将军何进就把董卓拉拢过来,准备威胁太后。结果请神容易送神难,董卓一来就只手遮天,胡作非为,皇帝是废了又立立了又废,从此朝廷暗无天日。

于是大豪族袁绍出场,利用自家的名望号召全国各大门阀,准备团战讨伐董卓。结果一呼百应,各大军事力量集结,那场面之吓人。话说曹操也跟来了,军队区区五千人,在联军当中连个座次都没有。但真的讨伐董卓时,唯有曹军奋勇厮杀,却是孤军奋战,联军们在干嘛?纸上谈兵,夜夜笙歌。一心想要复兴汉室的曹孟德明白不能与这帮乌合之众为伍。他准备自己单干,招兵买马,攻下兖州,有了自己的地盘,开始屯田治理,做大做强。

董卓死了,吕布杀的。但各方势力继续窝里斗,皇帝却因此而颠沛流离。于是毛玠给曹操提了个建议:奉天子以令不臣(也就是后来所说的挟天子以令诸侯)。即打着皇帝的名义,以合法的方式讨伐那些不听话的集团势力。就这样,曹操手握天子逐步拿下长江以北,最终改国号为“魏”,其子曹丕更是逼献帝禅让,直接称帝。曹魏一度雄霸北方,算是三国在军事上最成功的。

刘备呢,一个被遗忘的皇室之后,常年寄人篱下,后来军败曹操,不得不投奔荆州刘表。荆州可是战略要地,而刘表晚年病重时将荆州托付于刘备(此段历史存疑),他算是捡到大便宜了。而诸葛亮与孙吴的鲁肃都看到汉室已衰,三分天下是大势所趋,二人几乎想到了一起,于是孙刘联盟,共御曹敌。此后在刘备称帝,改名蜀汉,在诸葛亮的儒法并用的管理下,这个国家内政最稳。但连年征战却无功而返,并不得民心。

孙吴是典型的墙头草,因为他们执政者根本不在意复兴汉室,他们只在乎活下去,然后一统天下。所以可以看到孙家一会联刘,一会媚曹。说白了都是权宜之计,政治需要罢了。但孙吴的内政不稳,窝里斗很严重,吴国之所以最后灭亡,完全得益于他们见风使舵的外交政策。

总之,三国的故事每个人都耳熟能详,是真是假我就不好多言。我觉得大概记住几场战役:

  • 官渡之战:袁绍伐曹,曹操大胜,从此确定曹魏的北方霸主地位。
  • 赤壁之战:曹操伐刘,刘备联合孙吴来了个火烧连营,从此刘备稳坐荆州,三足鼎立之势凸显。
  • 夷陵之战:刘备伐吴,一是为关羽报仇,二是抢回荆州,结果孙权大胜。正式开启三分天下模式。

晋,是福是祸?

晋似乎不被认作一个朝代,司马家族从曹操时代一路辅佐曹家一统天下,先是干掉最弱的蜀汉,逼得刘禅在洛阳装疯卖傻乐不思蜀才能苟且偷生;而后收复孙吴。待帝国的版图基本构建完成时,又效仿当年曹丕,逼迫魏元帝曹奂禅让(不知道曹操的棺材板还压得住不),改国号为“晋”。

就我个人觉得,司马家族本可以成为中国历史上一个响亮的朝代,中国历史也会因为他们而改写。因为晋完成了统一大业,剩下的就是安抚贵族,与民休息。但他们偏偏开了历史的倒车,居然效仿周人,发扬封建主义。周朝验证了长期封建制会带来凌驾于天子的诸侯,西楚霸王验证了短期封建制会内乱不止。而司马家族偏不信邪,搞什么以郡建国,果然,短短几十年的稳定后引来了八王之乱。

其次,晋的世族制,实际上就是贵族体系,高官世袭,致使那些官二代们毫无上进心,整日高谈阔论,甚至发展为酗酒、嗑药、娘炮文化。这样的人群管理国家,能走向富强么?

封建招致国家内忧外患,世袭搞的政治风气败坏,也才能有后来的五胡乱华。而南北朝时期,自诩为华夏正宗的汉人把南方搞的是乌烟瘴气,而北方胡人却真正继承了华夏的衣钵。

这些是晋之过,却并非历史之错,毕竟这个时期为中华文明留下了遗产。西晋好比春秋,东晋好比战国。前者给了中华思想一次井喷的机会,正如春秋的诸子百家;后者给中国的政治体制来了一次全面反思,正如战国的秦并天下。

先说思想,魏晋时期,人们不在关注儒家的繁文缛节,而更在意一个人的气节,这个人是否获得漂亮与洒脱。这当然都拜世袭所赐,大家的前途都被一眼看到底,就不在务实了,尽搞那些虚的东西。所以这个时期的世族阶级喜欢高谈阔论,出现了玄学(中国的早起哲学)、琴棋书画盛行,而道家思想更是衍生出了道教,其实就是诸子百家的思想大杂烩。如果想要理解那个时期的晋人,不妨看看日本,因为那个时期中国的木屐和汉子都传入了日本,很多人文思想也连带着过去。总之那个时期的人,讲究事物背后的神形意,喜欢优柔唯美的风景,却又看中个人的率真与敞亮气质。

新战国时代

再谈谈体制,从周开始,中国有皇室、诸侯、贵族、百姓等阶层,有阶级就有矛盾,于是秦汉废除了这些阶层,从此只有皇权和臣民。此外,中国四周是蛮夷戎狄,即汉人与少数民族的矛盾,之前采取的措施一直是御敌,然后采取通婚来换取和平。

从封建制走向郡县制,是为了消除阶级矛盾,消除内战。毫无疑问,秦汉做得非常好,而且经过400多年的和平稳定,汉文明已经彻底融入中国人的骨髓里。阶级矛盾解决了,那么,民族矛盾呢?

少数民族是向往中华文明的,这与西方历史很不一样,古罗马时代,外来入侵者只会攻城略地,根本不在乎罗马文明,他们要重建自己的文化。而华夏的天下观却感染了外族势力,他们和汉人在思想上是一致的,即“我是否有资格继承天子这一角色”。所以,西晋时期各种权利争夺上演了八王之乱,进而招致北方各游牧民族趁乱入侵,逐一建立了各种外族政权,史称五胡乱华。但他们打的旗号都是:“我才是华夏正宗”!

五胡:匈奴、鲜卑、羯、羌、氐。由于文化的落后,基本还停留在部落联盟时代,最高领袖基本就是个大酋长。所谓五胡乱华,其本意就是指外来落后的野蛮文明扰乱中华文明。另外,所谓十六国则是由八王之乱后的内部分裂的新政权。因此这个时期中国的情况是,南有汉人内讧,北有外族乱政,各种分裂与吞并,大大小小何止十六个国家。说它是新战国时代,一点也不夸张。

五胡乱华,是晋的混乱与腐败给了少数民族一次说话的机会,让他们登上历史舞台,与汉人一起思考,何谓华夏文明。不过,这个时期的胡人与汉人一样,打打杀杀,你方唱罢我登场,局面一直持续到鲜卑族。其大酋长拓跋珪甚至先进文明有多重要,因此任用贤能,励精图治,与民休息。待盘踞北方称帝后,他废除了部落酋长制度,改为臣民百姓,迁都平成,让鲜卑一步跨入帝国大门,国号“魏”,史称“北魏”。

此后,拓跋家族的后代逐步汉化,直到孝文帝拓跋宏时,他的言行几乎与汉人无异,而他自己也认为天明在即,也许有了一统天下的野心。于是拓跋宏先是迁都洛阳,而后改用汉族祭祀礼仪、改汉姓、禁胡语、禁胡服、加强胡汉通婚。易中天的点评很合意:鲜卑像盐一样把自己溶化在汉民族的水中。

南北朝,即以长江淮河为界,以北的拓跋家族统治政权,称为北朝;以南的汉族政权,称为南朝。这个概念对后世的影响极大,因为此前中国人的观念里,只有中原没有南北,因为东南西北都是野蛮文明。此后中国人眼里,没有中原却有了南北方的概念,比如北方豪爽,南方温和等。

说会南朝,这些自诩正宗的汉人还在忙于内乱,还没争出个老大。因为封建制的诸侯依然顽固,世袭制养的窝囊废还在腐败。这便是南朝之乱。

历史车轮滚滚向前,直到北方的鲜卑人汉化的够彻底,汉人也足够认同鲜卑文化,中华文明才真正迎来的破晓时分。因为鲜卑化的汉人杨坚登场了,我们都知道他便是之后的隋炀帝。北朝探索了民族融合的道路,南朝验证了阶级矛盾的根源,经过这样的洗礼,中华文明才探索出了一条同时搞定民族与阶级矛盾的新方向。而这一些便以隋朝拉开帷幕,稳定持续了唐宋元明清五朝,一千多年。

Know Well More than Two Programming Languages

编程人员心理上都达成一个共识很长时间了,那就是编程专业技能的高低,与程序员所知道的不同编程范例的数量直接相关。这里说的知道不是简单了解,或者略懂略懂,而是能真正的编程。

每个程序员开始采用一门语言编程后。这门语言就会影响程序员对软件的思考方式。如果他们仅停留在这门语言,不管有多少年的编程经验,他们都将只会这门语言。一个只会一门语言的程序员,他的思维将被这门语言彻底限制住。

程序员学习第二门语言将会是一种挑战,尤其是当这门语言的计算模型与之前的大相径庭。C、Pascal、Fortran,都有相似的计算模型。选择从Fortran转到C带来的挑战并不会太多。从C或Fortran转到C++或Ada所带来的挑战主要是编程思想。从C++转到Haskell是一次很有意义的改变,当然其挑战也很有意义。从C转到Prolog将会带来非常明确的挑战。

我们可以列举一些计算机编程范式:面向过程、面向对象、函数式、逻辑式、数据流,等等。在两个不同范式间切换,就会产生最大的挑战。

为何这些挑战是好的呢?这与我们思考对算法实现、风格、适合的实现模式相关。其中,交叉受益是专业的核心。适用于一门语言的解决问题的风格,或许拿另一门语言就行不通了。尝试不同的风格,从一门语言到另一门语言,才能真正教会我们这两种语言,以及问题是如何被解决的。

采用不同的编程语言交叉受益将会带来巨大的影响。或许最为明显的就是采用命令式语言实现的系统中增加了或正在增加很多表达式声明。任何精通函数式编程的人都能轻松地适应声明式,即便是使用C这样的语言也如此。采用声明式方案一般会让程序更短或更易于理解。例如C++,几乎是为了表达式声明,肯定会全力支持泛型编程。

说了这么多,每个程序员都应该掌握至少两种不同的编程范式,理想情况下应该掌握上述五种。程序员始终应该对学习新语言感兴趣,最好从陌生的范式学习。即使他们的日常工作中使用相同的编程语言,当一个人能够从其他范式中交叉受益时,为这门语言带来的进步也是不容小觑的。雇主应该考虑到这点,并为员工学习当前未使用的语言留出培训预算空间,作为进步的一种方式,该语言要使用起来。

即便已经开始了,一个礼拜的培训课程是不足以学习一门新语言的:它通常需要几个月的实践,哪怕是兼职,也是为了获得一门语言真正意义上的工作知识。方言的使用,不仅仅是语法和计算模型,这一点很重要。

现如今,很多软件开发工具都被打包成集成开发环境(IDE)。微软的VisualStudio以及开源的Eclipse就是两个非常主流的案例,尽管还有很多其他的。IDE有很多让人喜爱的地方。不仅仅是它们简单易用,还包括它们能不需要程序员去考虑很多构建的细节过程。

易于使用,然而,这也算个缺点。具体来说,一个工具如果容易上手,是因为它替你做了决策,并在后台自动完成了大量的事情。如此依赖,如果你从来都只用某个IDE作为开发环境,那你永远都无法完全理解这个工具到底做了些什么。你点击一个按钮,魔法开始了,然后一个可执行文件就这么出现在工程文件夹下。

用命令行构建工具来工作,当你的工程编译时,你可以学到很多有关这些工具具体做了什么。编写自己的构建脚本(Makefile)有助于理解生成可执行文件的所有步骤(编译、组装、链接等等)。在命令行下尝试使用这些工具也是一种非常有价值的学习经验。刚开始使用命令行构建工具时,你可以选择像是GCC这样的开源命令行工具,也可以是IDE专门提供的那一套。当你全部尝试一遍后就会发现,好的IDE只是一套集成了命令行工具的前端界面。

除了提高你对编译过程的理解,相对于IDE,使用命令行工具还会带来一些更简单有效的地方。例如,在查找替换时,grep和sed所提供的功能,往往要比在IDE中查找要有用得多。命令行工具原生支持脚本,它允许自动完成任务,例如按计划每日构建,创建多版本工程,运行测试套件。在IDE中,由于构建选项往往是通过图形界面对话框制定的,并通过鼠标单击来调用,所以要实现此类自动化就会变得非常困难(如果不是不可能的话)。

且慢。不是说IDE的存在让开发更简单,进一步提高程序员的生产力么?是的!这项建议不是说你应该停止使用IDE。而是说你应该“看看引擎盖之下”,并了解IDE到底为你做了些什么。最好的方式你学习命令行工具,然后,当你再反过来使用IDE时,就可以更好的理解它的所作所为,你也能更好的控制构建过程。另一方面,一旦你掌握了命令行工具,体验过它的强大和灵活之后,你就会发现自己喜欢命令行胜过IDE。

为了便于理解秦汉的发展轨迹,我把秦朝和汉朝两个历史片段比作两家公司的发展历程。先做个简单的前情提要:

在很久很久以前,大周集团成立了,他们的市场叫做“天下”,但是天下实在太大了,于是大周就成立了很多子公司,并划分一部分市场份额给他们,只有一个要求:“独立结算,自负盈亏,你爹姓周”。刚开始这些子公司都很听话,也很努力。随着时间的推移,有的子公司做大做强,但大周本部却日落西山,眼巴巴地看着自己的子公司市场做的比自己还出色,时间一长,子公司们就有些失控了。

此时进入春秋时期,有5家子公司实力最强,俗称春秋五霸。尽管自身实力远超大周,但此时大家还念旧情,礼节上依然拥戴自己的大周母公司。但关系到市场业务的事情,就另说了。各家子公司开始大打出手,抢占对方的市场份额。毕竟对手都是曾今的兄弟公司,彼此竞争基本保持着公平、公证、公开的原则,日子嘛也还算过得去。

随着竞争的白热化,到达战国时代,大家变得心狠手辣,这个阶段完全就比谁更不要脸。于是,春秋五霸正式被战国七雄代替。而天下这个大市场也发生了巨变,春秋时期统治市场的往往是那些做高精尖的公司,他们自诩为华夏文明;战国时代统治市场的却是那些做中下游的低端公司,他们被视为蛮夷。蛮夷虽然技术落后,但在这个尔虞我诈的时期,劣比驱逐良币啊。而我们的主角——秦,就是常年在中下游做着低端业务的蛮夷公司。

大秦发家史

创业之路

秦被贴上低端的标签,他们自己也认,但他们知耻而后勇。这就要从一位职业经理人开始说起——商鞅。秦之所以聘请商鞅经营公司,就是一心想要做出自己的大品牌,他们要证明自己不是山寨。所以秦的高层也求贤若渴,纳谏如流。商鞅也得以在此施展拳脚,他主要采取以下几项措施:

  • 干掉中年油腻无能者(废封建,改郡县)
  • 干掉裙带关系(废世袭,改任命)
  • 严格执行KPI考核
  • 996
  • 老板永远是对的!

政策一出来,当然是怨声载道,但是商鞅发话了:“不听话者,砍了你的狗腿”!总之,公司上上下下的要求就是一切行动听指挥,大赏有功者,严惩有罪人。毫无疑问,在他的带领下,秦彻底变成了一个运转效率极高的大军营,战斗力瞬间爆表,秦王果断开始向中高端市场发起挑战。

变化来得太突然,以至于战国的其他六“熊”不得不建立合作伙伴关系,才能勉强与秦抗衡。但大秦也不是吃素的,此时的富二代(应该叫富N代)已经按捺不住雄霸天下野心——他就是秦王赢政。接手父辈们的家业后,他顺理成章地一块块吞并市场,由于秦走的是军国主义路线,手段之残忍,简直是吃人不吐骨头。但不论如何,在绝对实力面前,你奈秦何?

就这样,秦吞并六国,确切地说是20多国,只不过它们实力太弱而忽略不计,其中包括母公司——周,大周集团正式更名大秦。

反封建有多难

秦抢下了所有市场份额,一统天下,但秦王赢政不想走周的老路线。具体来说,他不打算继承“封建制”,而是想延续之前的“郡县制”,做一个放大版。集团子公司架构已经跟不上时代发展,中央集权才是大势所趋,但摆在秦王面前的一个大难题——如何分赃?

打江山易,治江山难啊。

想当年,大周集团成立,和周武王一起浴血奋战的弟兄们,他们即是合伙人也占股份的好吧。现在公司成功上市,你想独吞?也不怕撑死!所以周武王采取分封制,通过分股份、成立子公司,给每个创始人都封侯封爵,当上CEO走向人生巅峰。这套逻辑已经执行了1000多年,大家都理所当然了。秦王却发话了:“这家公司从此只有一个老板,中高层必须由公司统一招聘和调配,市场财务必须由公司统一结算,所有资产都归公司所有”。说白了,秦王走的是中央集权制,同时非常蛮横地补充了一句——“不听话者,砍了你的狗腿”。

那个时候的人们习惯了封建制,当初和你创业,都奔着上市套现去的,现在你秦王强推郡县制和中央集权,套现之路被堵死,中高层(贵族阶级)当然一肚子火了。

车同轨,书同文,行同伦

秦始皇自然是千古一帝,既然要废除封建,强推中央集权,自然要统一之前众多子公司的业务规则,所以统一交通、统一文字、统一文化、统一度量衡,这些事非常不得了,它为中华文明的稳定打下了坚实的基础。不仅如此,他还修建高速公路、万里长城,巩固了国防部队。当然,这一切也是蛮横强推!

如此这般的结果,加之泯灭人性的条例制度,弄的民怨四起,当年的愤青们就公开写文章各种骂,大秦不施仁政,生儿子没屁眼。秦始皇不乐意了:“你再骂个试试!”愤青们回:“试试就试试!”于是秦始皇就把他们逮起来活埋了——杀鸡儆猴!其实当年被活埋的都是些杠精,只会无脑乱喷,说的话根本没建树。秦始皇是真没想堵住儒家的口,只不过是被喷烦了。

但是焚书是真的,秦始皇的目的也很明确,限制言论自由。但这种一刀切的方式,致使多少绚烂文化,经典古籍就这么被他化为灰烬。罪人啊!

总之,强推各种统一政策,强行各种严苛条例,不顾百姓死活,只看绩效,大秦只是把曾经的军国主义放大到整个帝国版图。自然要失人心的。

中高层被得罪了,基层员工也被惹怒了,秦王朝自然要迅速奔溃,只是看谁负责临门一脚而已。

楚汉争霸

那日天空下起瓢泼大雨,上班途中的陈胜吴广铁定要迟到了,按照大秦律例是要被问斩了。只见陈胜仰天长啸:“横竖都是死,老子还不如造反!”没想到鲜花掌声接踵而至,看来大家的内心都压抑太久了,等这句话等得也太久了。而陈胜也就这么一脸懵逼的走向创业道路。

其实陈胜吴广不重要,只是他们的这一行为成了模范,在全国各地掀起了创业热潮。当然,主要感染了最重要的两个人——项羽和刘邦。

项羽:一个没落贵族,愣头青。
刘邦:一个流氓地痞,乡巴佬。

项羽能成功,主要是因为出场时装备比较好。他叔项梁,眼界格局比他高,做事又脚踏实地,一路带侄儿装X带侄儿飞。他军师范增,老谋深算,各种运筹帷幄,助他杀人于千里之外。而他自己呢,骁勇善战,血气方刚,战场一条龙,政场嘛…毕竟还是个孩子。在英雄联盟里最多算个前期坦克。

反观刘邦,一个混混头,带着屠夫樊哙,刀笔吏萧何,还有什么买菜的拉车的,的出门装也不怎么样,就这么创业了。但刘邦的性格造就了他,此人识时务,听得进忠言,广纳贤才,是个大后期。以至于后来张良、韩信、陈平等人的加入,实力不可同日而语。

所以,项羽是破釜沉舟,逢战必胜,愈战愈勇,每次战斗都打的非常精彩,操作之风骚,意识之精准,无人匹敌。然而他输了正常战争,因为他太任性了,只喜欢战斗,只想恢复秦以前的封建秩序。而封建的弊端就是诸侯群伐,这个西楚霸王自然是屁股没坐热就game over。我们后人也只能感慨一句,他还是个孩子啊!

而刘邦的务实不仅为他赢得了战争,更重要的是坐稳了江山。

基业长青

汉不过是披着儒皮的法

其实汉帝国是继承了秦的衣钵,只不过刘邦深谙管理之道,很多东西是不能硬着来的,所以他背后走的都是大秦的专制路线,只不过策略有所不同:

  • 骨子里是郡县制,但一国两制,部分封建制,先安抚贵族
  • 废除各种酷刑,安抚民心
  • 表面不限制言论,实则独尊儒术,让你没得选
  • 依旧集权,不听话者找茬儿杀掉

因此,汉帝国骨子里是专制集权,只是刘邦的个性让大得了天下,稳坐江山。但汉朝的中央集权也栽培了另外两个政治不稳定因素:外戚势力和宦官集团。

从开国皇帝刘邦的老婆这个苗头就出现,吕后可谓一路出生入死,伴随刘邦成就霸业,她完全配得上老板娘或董事长夫人的名号,她想当个副董事长也具备这样的实力。吕氏集团的崛起是在刘邦死后,自此以后的汉朝总时不时出现这样的循环:先帝驾崩,太后干政,父辈外戚崛起,皇帝拉拢宦官,干掉外戚,宦官崛起,皇帝大权在握,干掉宦官,新外戚诞生。

如果孔子看到这些估计要被气死,真是君不君、臣不臣、父不父、子不子、夫不夫、妻不妻。还有那些道貌岸然的尊儒,根本就是皇权的政治工具,为了巩固自己的地位的合法性,在正儿八经的权力争夺和政治斗争当中,谁会在意你这些礼节。该管制的管制,该强迫的强迫,该霸道的霸道,为啥?有效啊!

汉武大帝

汉武帝是汉朝除了高祖刘邦以后,业绩最出色的一个皇帝。首先,尊儒是从他开始明确的;匈奴是他灭掉的;推恩令几乎彻底消除了封建制;举贤让贵族阶级变成官僚;分天下为十三州部;大汉版图几乎翻倍。

是的,汉武帝刘彻在接过父辈们的家业后,先是干掉外戚势力,手刃宦官集团,然后才真正开始了自己平定天下的千秋大业。他从政治、军事、体制等多方面发起革命,运作的是风生水起。但归根结底,他是为了巩固皇权和政权,我个人觉得,他手里的大汉应该与秦始皇的预期差不多了吧。这个时期的汉朝固然气势恢宏,但内部是无数个酷吏、严刑峻法、连年战争扩张的功劳。

我们显然无法用好或坏来评价汉武帝,因为他和秦始皇一样,为整个中国做了非常了比起的贡献,但对当时的黎民百姓而言,恐怕一点也不仁慈吧。


就写这么多吧,本书是《易中天中华史》的第二部,我只看了一半。书中对秦帝国的描述不多,更多是讲楚汉以及国家制度的,其中花了大量篇幅拿古希腊古罗马做对比,为何集权专制的中华文明能经久不衰,为何崇尚自由的罗马反而轰然倒塌,其中的观点却是值得玩味。

0%