May 18, 2019

为什么说执行 996 工作制的脑力劳动者非蠢即坏

抱歉我用了这么个吸引眼球的标题。但我其实是想分析一下 996 工作制度到底存在怎样的问题。注意,我说的是身体力行执行 996 工作制的人,而非要求员工进行 996 工作的老板,这是两类人,今天我想骂的是前一类。

如果让我给执行 996 工作制下个定义,我想不能把全身心投入到工作和事业上的工作方式等同。它并不指工作时长;而是指刻意的制度性的把工作安排在非正常工作时间段。对待工作,不是以是否完成计划内的工作为衡量标准;而是本末倒置的先预设工作时长,然后想办法填满这些工作时间。

对于我最熟悉的游戏软件行业,它的工作本应该是脑力劳动为主。尤其对于程序员来说,主要的工作应该是在你的脑子里通过思考完成的,如果你的工作效率受限于每天不停的敲打键盘、移动鼠标、那么就变成了一项体力劳动。不久的将来,猴子和 AI 都能替你把事情干了。体力劳动或许可以通过制度性的延长工作时间来加快进程,可硬生生的脑力劳动变成体力劳动,只能用蠢来解释了。

如果工作的重点是通过大脑思考完成的,那么就不在乎你在什么时间,坐在哪里进行这些思考。甚至入睡前的那段时间都能想很多,限制每天在办公室坐上 10 多小时没有任何意义。那为什么说起来简单,996 反而成了国内程序员工作的普遍状态呢?我以最大的善意揣测人性,若他们不是心眼坏的话,那只能是大多数从业程序员能力欠缺了。

从游戏行业看,投资做游戏的人最期盼的是什么?并不是压榨你用更短的时间把游戏做出来,而是你能给个明确的计划时间表,在这个时间内保证质量的完工。这个时间可以比较长,但只要计划是明确的,就能估算出未来的收支情况。成功的游戏利润率非常之高,如果游戏能成功,用暴力手段压缩制作时间而减少的成本简直无足轻重。所以,游戏产品上线前,一改再改,无限延长开发时间反而是常态。

健康的项目,计划的落实是第一位的。那么最影响计划安排的是什么?不是工作时长,而是开发中的不确定因素:

阅读全文 "为什么说执行 996 工作制的脑力劳动者非蠢即坏" »

May 16, 2019

通过对缓存测速提取信息的旁路攻击

最近爆出对 Intel 系 CPU 的新的安全漏洞。MDS 攻击 可绕过安全屏障,取得同一个核心上运行的其它进程(或其它虚拟机)处理的数据。安全界的建议是暂时关闭超线程,避免泄露信息。

我对这个安全漏洞颇感兴趣,花了一些时间研究,弄明白了来龙去脉。

其实,新的 MDS 攻击的思路继承至更早发现的 Meltdown 攻击方式。除了原始论文,我找到了 这篇 blog 把其原理介绍的非常清晰。

如果不介意我可能有理解偏差,那么可以看看下面我对其原理做的一点中文复述:

阅读全文 "通过对缓存测速提取信息的旁路攻击" »

May 11, 2019

Windows 下 UTF-16 的坑

最近帮多个活跃的开源项目改了同一个 bug : 完善 Windows 下的 Unicode 支持。

问题源于 Windows 和其它平台不同,它有悠久的历史包袱。和现代大多数操作系统对 Unicode 支持的共识不同,它的 API 不是基于 UTF-8 而是基于 UTF-16 的,且还遗留了一套过去对 ANSI 支持的兼容 API 。

最近我接触的几个活跃开源项目,都是西方人主导开发的,他们维护者似乎对 UTF-16 均有所误解,或是懒得做全面的支持。我认为罪魁祸首就是微软自己把 ANSI 编码称为 MBCS 多字符编码字符集,和 WideChar 宽字符集对应起来,暗示 WideChar 是单字编码。而事实上 UTF-16 方案应该成为 MWCS 才合理。

Unicode 虽然常用的只有 BMP ,也就是 U+0000 到 U+FFFF 部分的字符集。但是随着 Emoji 的普及,SMP 也变得非常常见了。其实 Unicode 目前的标准有 17 的 Plane ,需要 21bit 才能表示完全。而很多人直观的觉得,UTF-16 每一个字 ( 2 字节 )表示一个码点。这是不对的,像 Emoji ,一些罕见汉字(SIP)需要用两个字来表示。这个叫做 surrogate pair ,对于 Unicode ,U+D800 到 U+DFFF 这个区段是不存在的,专门用于实现 UTF-16 中的 surrogate pair 。

阅读全文 "Windows 下 UTF-16 的坑" »

April 14, 2019

并发 Hash Map 的实现

Lua 中的短字符串做了 string interning 的处理,即在同一个虚拟机内,值相同的字符串只存在一份。这可以极大的提高用字符串做 key 的 hash 表的查询速度。因为字符串比较的时间复杂度从 O(n) 下降到 O(1) ,比较查询的 key 和 hash 表内的 key 是否一致,只需要对比一下对象的指针是否相同即可。

我在解决多 Lua 虚拟机共享字符串对象这个问题时,合并了不同的 Lua 虚拟机中的短字符串表。让同一进程所有虚拟机共享一个短字符串表( SSM )。

我最初在实现 SSM 的时候,考虑到多虚拟机 GC 的复杂性,采用了只增不减的方案。即让部分短字符串进入 SSM ,设置一个上限,避免 SSM 无线膨胀。但 Lua 并没有把经过 interning 处理的字符串作为独立类型,目前只用字符串长度作为区分,也就是无法和不 interning 的短字符串共存。所以,那些已存在本地虚拟机短字符串表中的字符串,就不从 SSM 中获取对象。

修改过 Lua 的 string interning 算法是这样的:

  1. 查看字符串是否存在于本地字符串表 (LSM) 如果存在,就立刻返回。这一步和原版 Lua 一致。

  2. 查看字符串是否存在于 SSM ,如果存在,就返回。

  3. 检查是否 SSM 上限已到,如果不能再增加新字符串,把字符串添加到 LSM ,返回。

  4. 将字符串添加到 SSM ,返回。

阅读全文 "并发 Hash Map 的实现" »

April 11, 2019

不同虚拟机间共享不变的 Table

这几年,我一直在寻找不同 Lua 虚拟机间共享大量不变的结构化数据的方法。因为这对于游戏这类数据驱动的软件是非常重要的需求。我们现在正在运营的游戏“风之大陆”,服务器上的策划生产出来的数据表格,转换为 Lua 源文件后,就已经达到了 300M 之巨,全部加载到 Lua 虚拟机中,会消耗 700M 内存。

我为这个需求实现过好几套方案:最初是 Sharedata 这个模块,后来又实现了一个叫 DataSheet 的替代品。

过去的方案用的思路都是把数据表放在 C 对象中 。Lua 中建立一个 proxy 对象去访问它。C 对象可以跨虚拟机共享,proxy 对象则在不同的虚拟机中各创建一份。

阅读全文 "不同虚拟机间共享不变的 Table" »

April 03, 2019

为 bgfx 设计了一个 IDL

上个月为 bgfx 贡献了一周多的工作时间,起因是 bgfx 的作者在我的 sproto 项目下发了个 issue (现在已经转到 bgfxidl 项目下)。他想为 bgfx 的接口设计一个 Interface Description Language ,这样可以避免手工维护多语言接口文件,还可以方便做许多代码生成的工作。

我在 2006 年左右尝试利用 COM 的 IDL 做过一些工作,想来这和 COM 面临的问题是一样的。我认为 lua 是一个可以用来做 DSL/IDL 非常好的工具,所以我向 bgfx 项目推荐了它。而且 bgfx 用的构建工具 Genie 就是基于 lua 的,这样工具链就比较统一。

阅读全文 "为 bgfx 设计了一个 IDL" »

March 19, 2019

数学运算模块的改进

我为我们正在研发的 3d 引擎设计了一个非常规的数学运算模块

它和很多为 Lua 封装的数学运算模块不同,并没有用 userdata 或 table 来实现矩阵向量对象,而是采用了 64bit 的整数 id 。其生命期管理是模拟了一个堆栈,我称之为数学栈,和程序运行时存放临时变量的堆栈以示区分。数学栈上存在过的矩阵向量对象的生命期都会维持一个固定周期,通常是一个渲染帧。每帧主动调用重置指令刷新。这个设计减少了在 lua 层面使用矩阵向量对象的心智负担。你不必担心运算产生的临时结果会增加过多 gc 的负担。构造新的矩阵向量对象的成本也非常的小。

阅读全文 "数学运算模块的改进" »

Misc

Categories

Archives

Recent Comments