摸鱼精选第 1 期
1. Node.js 的底层原理
Node.js 主要是由 V8、Libuv 和一些第三方库组成。
其中 libuv 是异步任务的核心,本文探讨了 epoll 的模型与限制,无法读写文件、不适合 CPU 大量计算等操作,于是 Libuv 引入线程池解决这几个问题,最后作者梳理了 Libuv 的事件循环。
从三个方面介绍 V8:
- 介绍 V8 在 Node.js 的作用和 V8 的一些基础概念
- 介绍如何通过 V8 执行 JS 和拓展 JS
- 介绍如何通过 V8 实现 JS 和 C++ 通信
Node.js 中有五种模块加载器。
- JSON 模块加载器
- 用户 JS 模块加载器
- 原生 JS 模块加载器
- 内置 C++ 模块加载器
- Addon 模块加载器
2. 从根本上了解异步编程体系
作者从 CPU 调度的源头上开始 梳理同步、异步的区别,异步的收益。
异步并不会让逻辑上串行的任务变快,只能让逻辑上可以并行的任务执行更快
异步操作离不开操作系统的底层支撑,目前三大 OS 都有自己实现机制,原理也不尽相同:
- Linux: select、poll、epoll
- Mac: kqueue
- Windows: IOCP
Linux 的 epoll 的设计和性能都不如 windows 的 iocp,最新的 5.1 内核加入了 io_uring,算是向 windows 的 iocp 致敬了。
- 为了让程序在同一时间内处理更多的请求,我们采用多线程。多线程虽然编写简单,但是对内存和 CPU 资源消耗大,因此我们考虑利用系统的异步接口进行开发;
- 我不知道异步操作什么时候结束,只能不停的轮询它的状态。当有多个异步操作,每个的响应时间都未知,不知道该去先轮询哪个。我们利用操作系统提供的能力,把异步事件加入全局监听队列,然后通过 wait_until_some_of_them_get_ready 来等待任意事件就绪,所谓的 EventLoop;
- 当事件就绪后 EventLoop 不知道该执行什么逻辑,只能进行一个非常复杂的判断才能确认后续逻辑该执行哪个函数。因此我们给每个异步事件注册回调函数,这样 EventLoop 的实现就高效而清爽了;
- 所有异步程序都需要在最后执行 EventLoop 等待事件就绪然后执行回调,因此可以把 EventLoop 这块逻辑放到语言自身的 runtime 中,不需要每次自己写。
read_async_v2('qq.com', function (data) {
send_to('pony@qq.com', data);
});
read_async_v2('jd.com', function (data) {
write_to('jd.html', data);
});
// 编译器帮我们把while循环自动插到这里
// 或者什么异步框架帮我们做while循环
用回调来处理异步就会遇到“回调地狱”的问题,JS 为了解决这个问题引入 Promise 范式。作者从 0 开始梳理 Promise 的实现过程,遇到的问题以及解决办法。
关于 Linux io_uring 异步 IO 接口的资料:
3. Rust 是 JavaScript 基础设施的未来
Rust 在底层编程上有安全优势,但是并不是说只适合干 C/C++的活。上层应用方面现在也用的很多,尤其是做一些 cli 工具的时候。
4. RabbitMQ 七种消息传递形式
5. 彻底搞懂容器技术的基石: cgroup
6. Flutter 中 TextField 组件必然会遇到的问题
本文提到两个 TextField
需要注意的问题:字数统计和文字居中。
-
在 iOS 的中文输入法下,由于拼音联想功能,点击字母,输入法会给出联想中文预览,但实际上用户还没有确认,所以
TextField
会计算正在编辑的拼音字母的数量,而不是实际的中文数量,这是不符合需求的。官方没有解决这个问题,但是作者通过一种巧妙的办法可以解决。 -
文字居中可以通过修改
InputDecoration
里面的contentPadding
字段达成,但是当TextField
高度有变化时,居中效果没有跟着变化,所以要动态计算高度。主要难点是计算出字体的高度,这里可以使用TextPainter
来计算高度。