摸鱼精选第 26 期

1. React Native 工程 Monorepo 改造实践

Monorepo 就是把子仓库都放到一个仓库来管理。本文作者是网易云音乐团队,采用 yarn workspace 方案来管理 Monorepo。

对于多个功能类似的工程采用 Monorepo 的管理方式确实会方便代码复用和调试,提高我们的开发效率。

2. Tao of Node - Design, Architecture & Best Practices

Node 之道:关于设计、架构与最佳实践 — “全图鸟瞰” 式的总结是非常受欢迎的。我们都在为架构设计探索新的设计思路、处理之道。作者在文中总结了在构建高质量 Node 应用程序时,所获得的所有来之不易的最佳实践。

作者在 2021 年还写了 React 之道:Tao of React - Software Design, Architecture & Best Practices

3. 十个有用的软件开发原则

集中精力学习概念,而不是技术

不要太关心技术的复杂细节,因为你可以随时查阅它们。你要学习底层的基本概念。

技术会变化,概念却是永恒的。你学到的概念将被用在更新的技术中,你就可以更快地学会新技术。 例如,不要太关注 React、Kubernetes、Haskell、Rust 的表面细节。 重点学习:

  • 纯函数式编程
  • 关系型模型
  • 规范的方法
  • 逻辑编程
  • 代数数据类型
  • 类型类(通用的和特定的)
  • 借位检查器(仿射/线性类型)
  • 依赖类型
  • Curry-Howard 同构
  • 同像性(Homoiconicity)
  • VirtualDOM
  • 线性回归
  • ......

4. CFS 组调度

本文介绍了 CFS 组调度功能引入的原因,配置方法,和一些实现细节。此功能可以在高负载下"软限制"(相比与 CFS 带宽控制)各分组任务对 CPU 资源的使用占比,以达到各组之间公平使用 CPU 资源的目的。在老版原生 Android 代码中对后台分组限制的较狠(甚是将 background/cpu.shares 设置到 52),将 CPU 资源重点向前台分组进行倾斜,但这个配置可能会在某些场景下出现前台任务被后台任务卡住的情况,对于普适性配置,最新的一些 Android 版本中将各个分组的 cpu.shares 都设置为 1024 以追求 CPU 资源在各组之间的公平。

5. 多线程开发中,多用消息传递,少用锁

Chrome 具有多进程架构, 并且每个进程都具有大量多线程。每个进程共享的基本线程系统。主要目标是使主线程(浏览器进程中又称为“ UI”线程)和 IO 线程(用于处理 IPC 的每个进程的线程 )保持响应。这意味着将任何阻塞的 I / O 或其他昂贵的操作分配到其他线程。

实现方法是使用消息传递作为线程之间进行通信的方式。不建议使用锁定和线程安全的对象。相反,对象仅存活在一个(通常是虚拟的)线程上,并且在这些线程之间传递消息进行通信。

6. sqlite wal 分析

sqlite 提供了一种 redo log 型事务实现,支持读写的并发,见 write-ahead log

本文将介绍 wal 原理,并源码剖析 checkpoint 过程,同时讨论下 wal 使用中的一些注意点。由于 sqlite 的复杂性,会省略掉一些细节,重点放在核心流程和 wal 并发的实现。

7. 教你实现一个 iOS 重签名工具

重签名 IPA 包主要用于给同一个应用设置不同的 bundle id,这样两个 app 都可以同时安装在手机上,方便对比测试,比如 ad-hoc 或 app store,测试环境或生产环境。另外就是针对大型 App ,可以避免再次全量编译,耗时比较久的问题。

作者对比各种工具之后,发现 xcodebuild -exportArchive 命令是最稳妥的。

下面是作者的打包脚本思路:

#!/bin/sh
set -e

# 这里只列出重签名脚本的大致流程
# 基本可以分为以下 5 个步骤


# 1. 解压游戏包,删除包内无用内容(.DS_Store,__MACOSX等),如需要,修改Info.plist参数和图标等资源
unzip "ipa路径" -d "目标路径"
find -d "解压后的路径" -name .DS_Store -o -name __MACOSX | xargs rm -rf


# 2. 对需要重签的内容并重签名
find -d "包体路径" \
-name "*.app" -o \
-name "*.appex" -o \
-name "*.framework" \
-o -name "*.dylib" \
| xargs -I {} /usr/bin/codesign --continue -f -s "证书名称" {}


# 3. 找出 appex 里面的 bundle id
find -d "包体路径" -name "*.appex" \
| xargs -I {} /usr/libexec/PlistBuddy -c "Print :'CFBundleIdentifier'" {}/Info.plist


# 4. 修改 xcarchive 模板信息
#    复制 .app 文件到 xcarchive 的 Products/Applications 目录下
#    修改 xcarchive 内的 Info.plist 和 ExportOptions.plist 包名,证书名称,描述文件名称等信息


# 5. 导出ipa包
xcodebuild -exportArchive \
-archivePath "xcarchive路径" \
-exportOptionsPlist "ExportOptions.plist路径" \
-exportPath "导出路径"

8. Disconnect your app from unit testing

Xcode 启动单元测试 Target 的时候,通常会把主工程也先编译启动。如果你不想启动主工程,比如你只需要做一些网络 Mocking 的话,可以通过下面这种方式:

  1. 移除 AppDelegate@UIApplicationMain@main
  2. 添加 main.swift:
import UIKit

private func delegateClassName() -> String? {
    if NSClassFromString("XCTestCase") != nil { // Unit Testing
        return nil
    } else { // App
        return NSStringFromClass(AppDelegate.self)
    }
}

UIApplicationMain(CommandLine.argc, CommandLine.unsafeArgv, nil, delegateClassName())

本质就是通过运行时判断当前的环境是否测试环境,生成不同的 delegate,如果是单元测试就返回 nil。

当然如果你需要 UI 测试,那就必需 AppDelegate 了。

9. 中信建投 | 从 CHAT-GPT 到生成式 AI(Generative AI):人工智能新范式,重新定义生产力

从券商报告里学习知识,我也是醉了,不过这篇确实是非常全面的 AIGC 报告。

此前的决策式 AI 模型(Discriminant Model)是根据已有数据进行分析、判断、预测,典型应用为内容的智能推荐(短视频)、自动驾驶等; 而生成式 AI 更强调学习归纳后进行演绎创造,生成全新的内容,本质是对生产力的大幅度提升和创造,已催生了营销、设计、建筑和内容领域的创造性工作,并开始在生命科学、医疗、制造、材料科学、媒体、娱乐、汽车、航空航天进行初步应用,为各个领域带来巨大的生产力提升。

10. Learn CSS

Google 官方出的免费 CSS 教程,相对比较基础,英文版。

其实我更推荐 Firefox 的 CSS 教程,还有中文翻译。

11. Object Oriented C Programming

C 语言面向对象编程,本质上还是充分利用 struct 当 class 使用,函数指针的高阶使用

12. 「React 深入」一文吃透 React v18 全部 Api

本文将会全面总结所有的 ReactApi,包含组件类、工具类、生命周期、react-hooks、react-dom 五大模块,并配带示例,帮助大家更好的掌握。

13. iOS 远程推送--APNs 详解

算是比较全面介绍 APNs 。

14. Practical Go Lessons

又一个实用 go 教程。

15. 学习一下 nowinandroid 的构建脚本

本文主要介绍了 nowinandroid 项目构建脚本中的一系列小技巧,具体包括以下内容

  1. gradle.properties 中的配置
  2. 自动安装 git hook
  3. 使用 includeBuild 而不是 buildSrc
  4. 如何复用 build.gradle 代码?
  5. 使用 Version Catalog 管理依赖
  6. 代码格式检查
  7. 自定义 lint 检查

16. How to build your own React: Didact 解析

一个简易版 React 框架 —— Didact 功能较简单,而在 React 中做了大量的优化工作,如顶层事件代理机制、Fiber 的 bailout 机制,此框架只是沿用了 React 中的设计理念和思想,希望可以为大家学习 React 源码做一点铺路的工作。

17. 吊打高斯模糊的 StackBlur 来了!

Stackblur 是一种高斯模糊的快速近似,由 Mario Klingemann 发明。其计算耗时不会随着 kernel size 的增大而增加,专为大 kernel size 的模糊滤波场景量身定制。

OpenCV 4.7 版本提供支持。