技术分享 其他 查看内容

黑死 java 不商量

老高 | 发布于 2022-02-13 18:49| 浏览()| 评论() | 收藏() | 点赞() | 打印

摘要: 很久很久以前, 我学习了一门叫 C++ 的语言。那个时候我在写一个叫 Emacs 的软件的变种。源于对 C 和 C++ 的厌恶, 我把我的厌恶都发泄到了用户身上。 如果用户做错了什么,程序会侮辱他,把他叫做火鸡,并把屏幕填满垃圾。

很久很久以前, 我学习了一门叫 C++ 的语言。那个时候我在写一个叫 Emacs 的软件的变种。源于对 C 和 C++ 的厌恶, 我把我的厌恶都发泄到了用户身上。 如果用户做错了什么,程序会侮辱他,把他叫做火鸡,并把屏幕填满垃圾。

后来 这个 Emacs 版本没人用了,我于是去了 DIM 公司混饭吃。 在那里, 我遇到了同样一群讨厌 C++ 的人 。C++是如此的难用,我们决定设计一个更简单的 C++。

我对 C++ 的第一个讨厌的地方就是 他的内存管理。 太讨厌了! 我得不停的写 new delete, 还得操心 new [] 和 delete [] 的区别。 还得时刻关注一个对象的生命周期,一不小心忘记了就要内存泄漏了。

编写 Emacs 的经历让我很快的想到了 lisp 语言, lisp 语言里带有一个垃圾收集器, 于是,我就把垃圾收集器带到了我的语言里。

因为有了垃圾收集,程序就非常简单咯~ 在也不用操心内存管理了。

等等, 用户要是把指针存到 int 里, 然后再 cast 出来咋办? 垃圾收集没办法对付这种情况啊! 简单! 废了指针不就好了啊~ 。

好的, 我有了一个初步设想了,这个语言应该是

    自动的内存管理 (GC)
    不需要指针

等等, 对象要是分配到栈上和堆上, 又要不同对待了~ 栈对象肯定和堆对象不一样啊! 如何引用对象成员呢? GC如何区分他们? 哎呀, 好麻烦, 没指针好像就没法区别对待 栈对象肯定和堆对象了! 咋办? 好吧,不允许栈对象就是了嘛! 所有的对象都从堆里分配就好了嘛!真好啊,既然所有对象都是在heap上分配的,区分stack和heap的分配就没有必要了。我可以轻易说 Cat x = Cat() 或者 Cat x = Cat("mittens")。

好的, 我有了一个初步设想了,这个语言应该是 - 自动的内存管理 (GC) - 不需要指针 - 所有的对象都从堆分配,变量只是一个引用

那么接下来是 对象的设计了。面向对象的语言是潮流!

C++ 居然支持 C , 所有的东西不都是对象, 这太恐怖了! 面向对象的语言是潮流!怎么能不面向对象呢? 没对象怎么行! 所以 我的语言必须得是 面向对象的语言! 这个是潮流! 既然面向对象, 就要真正的面向对象 所有的东西都是对象 , 哈哈,这是我从 UNIX 那里学来的,我厉害吧!

啥? main() 函数咋办? 切, 放到一个对象里, 做成 static 成员函数就好了 。。。。。。

为了面向对象的时候, 用起来方便, 我决定,所有的对象都继承字一个叫 Object 的对象! 这样才好! 这才漂亮! 这样不用那难学的模板了, 诶, C++ 的模板太难学了, 肯定大家都和我一样学不会的! 我都学不会,别说一般的程序员了!是吧。 只要大家都是一个根出来的, 用不着写模板, 你的算法就是通用的啦~

而且单个根继承下来, 对 GC 来说也变得容易实现了嘛!

好的, 我有了一个初步设想了,这个语言应该是

    自动的内存管理 (GC)
    不需要指针
    所有的对象都从堆分配,变量只是一个引用
    所有的东西都是对象
    所有的对象都直接或者间接继承自 Object
    所有的方法都是虚的

恩,看起来这样的特性不错, 肯定比 C++ 简单啊~ 大家肯定用的比较 happy 的~ 性能这种东西嘛,丢了丢了, 只要写程序快多好,足矣弥补运行效率的损失了, 再说, 就一个默认虚函数而已, 有啥效率损失。 GC 又不是时刻跑,偶尔出来跑一下啦! 这点效率损失是可以接受的! 带来的好处不用多说, Better C++ 啊!

等等, 异常忘记加了, C++ 都有异常, 咱家咋能没有! 靠!加了加了 !

好的, 我有了一个大概设想了,这个语言应该是

    自动的内存管理 (GC)
    不需要指针
    所有的对象都从堆分配,变量只是一个引用
    所有的东西都是对象
    所有的对象都直接或者间接继承自 Object
    所有的方法都是虚的
    支持异常处理

不错, C++ 还有 RTTI , 我的语言怎么能没有? 加了! 还得加的更厚道!

好的, 我有了一个大概设想了,这个语言应该是

    自动的内存管理 (GC)
    不需要指针
    所有的对象都从堆分配,变量只是一个引用
    所有的东西都是对象
    所有的对象都直接或者间接继承自 Object
    所有的方法都是虚的
    支持异常处理
    支持运行时类信息

哈哈! 这语言已经和 C++ 在特性生很接近了, 差不多了, 但是我需要推出一个 杀手级 的特性! 保证把 C++ 秒到棺材里。

他 C++ 不是号称 “跨平台” 么? 我去! 要到处编译的, 每个平台的编译器还都不一样! 算你妹的跨平台! 咱这语言, 必须真正的跨平台!一次编写, 处处运行!

这TMD的有点意思哈!恩,简单, 咱设计个虚拟机不就完了么! 把咱这个语言的程序用虚拟机跑起来, 只要移植虚拟机就可以了。

恩,最终的语言应该这样的

    自动的内存管理 (GC)
    不需要指针
    所有的对象都从堆分配,变量只是一个引用
    所有的东西都是对象
    所有的对象都直接或者间接继承自 Object
    所有的方法都是虚的
    支持异常处理
    支持运行时类信息
    程序运行在虚拟机上,一次编写处处运行,真正的跨平台

拍屁股决定了语言特性后, 咱就马上开始实现这个语言了! 当然, 实现这个语言还得靠 c++. 否则咱拿什么编译这个语言啊!

这语言写着写着, 咱又发现了几个问题, 首先 int char 这类的类型, 他放到堆上不太好啊!

好吧,打个补丁, 把这几个类型叫做 primitive 类型, 和 C 一样, 分配在栈上好了。

过了一段时间后, 我的主管大力的称赞了我的新语言,然后它被推向了市场, 冠名为 Ksbs 语言。

这个语言引起了很大的轰动, 我很自豪, 因为我把 C++ 所有不好的地方都消灭了, 哈哈哈! 我伟大~

至于 GC 和解释执行导致的效率问题, 我也开始通过更厉害的 GC 算法和 JIT 编译器来弥补了。 我找了几个 benchmark , 证明 GC 比 手工管理内存还快, 另外找了写枪手来批评一下 C++, 整个市场接受度良好! 哼~

在多年的实践里, 我发现了这么一个事实, GC 虽然能管理内存, 但是管理不了其他资源, 比如文件描述符。这些资源程序员必须小心管理, 否则容易发生资源泄漏问题。

我了个去!! 这是很严重的问题! 靠! 怎么没有人告诉我 !! 我听说 C++ 发明了 RAII 机制, 可以自动的管理包括内存在内的一切资源。 这不科学! C++ 一定是垃圾的语言! 我的语言才是最优秀的!

好吧, 加入 finalize 机制好了! 恩恩, 对, 用 finalize 释放其他资源。 哈哈, 我真聪明! 有了 finalize 机制就可以释放其他资源了嘛! 一般的对象都只有内存的啦,所以多一个机制并没有引入太大的复杂度, 对吧?

我很不安, C++ 发明了 sharedptr , 这玩意, 一下子让我的 GC 黯然失色! 靠, 得想个办法诋毁! 动员公司的力量, 创造舆论! sharedptr 有原子操作, 多核情况下性能不行!!shared_ptr 无法处理循环引用!

恩恩, 就这样攻击一下, 另外再找几个例子, GC 的性能比 shared_ptr 高的。

果然, 大家都开始唾弃 shared_ptr 了, 说 GC性能更好 ! 恩恩, 我安心了。

但是, 我对摩尔过于乐观了, 我的语言时不时的遭到 “被彻底抛弃,使用 C++ 重写” 的威胁, 我得想个办法!

对! 支持调用 C++ 的程序不就好了! 让他们把比较性能敏感的部分用 C++ 给重写就好了, 别整个重写啊!

对啊, 我还得教育大家, “把性能关键的部分用 C++编写, 其他部分用 ksbs 写” 这样的观念给植入大众的脑袋!总之不能让大家觉得全部用 C++ 写是个更好的选择!

以上就是我设计 Ksbs 语言的历史, 哈哈, 我是 Ksbs 之父!膜拜我吧!

发表评论(对文章涉及的知识点还有疑问,可以在这里留言,老高看到后会及时回复的。)

表情