很多编程语言对比的文章, 总喜欢比较各种编程语言的性能, 语法, IO 模型. 本文将从心智负担这个角度去比较下不同的编程语言和技术. 因本人所擅长的编程语言有限, 如有不对的地方, 欢迎指正.
内存越界
如: C 语言, C++(C with class)
C/C++ 可以直接操作内存, 但编程必须要面对内存越界问题. 发生内存越界后, 程序会直接 core dump, 开发者需要使用 gdb 工具分析内存错误的原因, 如果内存越界是偶发的, 比如由于数据同步问题造成, 数亿次中会出现一次, 解决起来非常困难, 甚至需要顶级专家才能找到问题原因.
心智负担: 10
现代 C++ 提供了 STL 库包含大量容器, 另外 C++ 支持引用语法, 不再需要直接操作指针, 降低了内存错误读写的风险. 使用现代 C++ 的编程风格可以避免此问题. 但由于 C++ 没有完全从语法层面移除指针, 不够彻底.
宏
C/C++ 程序中经常使用预定义宏实现一些逻辑, 导致可读性变差. 有些情况下会嵌套多次宏的使用, 展开后变得极其难读. 心智负担: 6
因此在 C/C++ 中建议使用 enum 或 static inline 函数代替宏.
内存管理
如: C 语言, C++
C/C++ 语言, 需要手工管理内存, malloc/new 申请的内存要与 free/delete 成对使用. 申请的内存忘记释放, 就会出现内存泄漏. 心智负担: 8
Java/PHP/Go 等有 GC 的编程语言, 不需要手工管理内存, 不会因为代码错误引起内存泄漏. 心智负担: 0
数值类型
C/C++/GO 等编程语言, 提供了有符号, 无符号整型和浮点型, 8/16/32/64 不同尺寸的整型. 编程时需要额外处理, 避免数值溢出. 心智负担: 6
PHP/Java 等编程语言, 默认整数为有符号 int64, 降低了心智负担. 一般业务项目中很难有超过 2^63 的数字, 不会遇到问题. 但如果是做科学计算, int64 就难以满足需求了. 在 PHP 中超过 2^63 底层会转为浮点型, 计算将丢失精度. 心智负担: 1
而 Python 整数是不限长度的, 可以做任意位数的数值计算. 心智负担: 0
类型约束
Java 是静态强类型编程语言, 因此在编程中存在类型约束, 某些情况下可能不是特别方便. 如 JSON 序列化. 不同类型的变量互相操作时可能需要进行显式类型转换. 心智负担: 2
PHP/JS 是动态弱类型编程语言, 底层自动进行隐式类型转换. 编程更方便. 心智负担: 0.
项目维护
在大型项目, 或对已有系统进行代码重构, 以及项目代码更换开发者时, 弱类型动态语言会带来可维护性的难题. Java/Go/C++ 这样的静态强类型编程语言在编译期就可以发现问题. 而动态, 弱类型语言可能会因为重构或其他维护操作产生运行时错误, 增加了心智负担. 心智负担: 5
多线程编程
Java/C++/Go 提供了多线程并行编程, 无锁编程, 在编程中会存在数据同步问题. 因此需要对临界资源进行加锁. 而错误的锁操作又会带来, 死锁和热点争抢问题. 需要开发者具备极高的素质, 否则难以做到正确无误并性能良好, 这可能需要耗费大量心智. 心智负担: 10
内存泄漏
除 PHP(PHP-fpm) 之外的其他编程语言和技术 (包括 PHP + Swoole), 在服务器端程序中均为长生命周期. 对全局 / 静态变量操作可能会导致内存或资源句柄泄漏. 编程时需要注意. 心智负担: 3
而 PHP(PHP-fpm) 是短生命周期的, 在请求结束后会立即释放所有内存和句柄, 无需担心泄漏. 心智负担: 0
IO 超时
同步阻塞 IO 模型的编程语言和技术, 在遇到某个慢 IO 会导致整个进程或线程挂起. 极端情况下会出现所有进程 / 线程挂起, 引起线上服务不可用. 开发者需要格外注意设置 IO 操作的超时时间, 避免慢请求带来进程 / 线程阻塞. 心智负担: 2
而且异步 IO 的 Go/Node.JS/Swoole 等无需担心此问题. 心智负担: 0
汇总
来源: https://segmentfault.com/a/1190000017411420