N体问题是指找出已知初始位置、速度和质量的多个物体在经典力学情况下的后续运动。
这个问题虽然在数学上还没有满意的解答(N≥3时),却比较容易用数值计算进行模拟。简单来说就是把时间离散化,在每一时刻,根据物体的受力和速度来确定速度和位置的变化量。
这个问题常用来做基准测试,因为它涉及大量浮点数运算和大量的循环步骤(模拟长时间的运动)。
想起这个测试是因为我正在看Zig语言的文档,发现它原生支持向量运算。例如,我可以定义含有3个分量的向量:
const Vec3 = @Vector(3, f64);
并对它们进行四则运算。
继续阅读 →迂腐的文人常拿没有用的知识当学问,比如“回字有几种写法?”这种问题,对于现代人来说,除非博闻强记,否则实在难以回答。最近几年,人工智能 (AI) 特别是大语言模型 (LLM) 的快速发展,给我们带来了了解各种冷门小知识的新办法。
两年前的人工智能回答这些问题时或许大多是胡编乱造(所谓“幻觉”),但现在它们已经可以给出相当可靠的回答了。看来,靠人脑记忆这些没用的小知识更加没有价值了,即便是拿来炫耀——对方只要问一下AI,就能得到解答,没你什么事了。
有一类“问答网站”,用户发帖提问,其他用户回答,大家一起互动,传播知识。这曾经是学习各种小知识的好地方,但我想他们以后逐渐会被AI代替了吧?也许在情感类或者社会学类的问题上还能坚持一段时间。
但是,归根结底,AI的知识也是靠训练获得的,其中大部分内容大概是来自于互联网?如果以后大家都用AI来做问答,没有人输出新知识的话,AI又怎么进步呢?(也许这个问题本身可以拿来问AI,看看它们会怎么回答)。
继续阅读 →(按:以下皆由 Gemini 2.5 Pro 生成。)
余从业代码之事久矣。所谓码积如山,会海滔滔者,诚非虚言也。日则伏案疾书,夜则寻瑕索瘢。星月为伴,灯火为朋。偶有所成,不过千行之码;顷刻对接,动辄百口之端。殚精竭虑,寒暑不辍,而发顶日稀,镜中之影,已非少年。
然上官者,不明技艺之精微,不明架构之肯綮,徒好高谈阔论,口若悬河,唯“新潮”是尚。或朝令而夕改,或纸上而谈兵,吾辈下属,唯唯诺诺,言听计从,实则苦不堪言。指鹿为马,尤令人啼笑皆非。
长此以往,身心俱疲,志气渐磨。与其在此耗神,不如归去!人生几何?韶华易逝,岂能久困于此方寸屏幕之间,受此无谓之煎熬乎?
遂决意挂印而去。临行之际,将最终之稿,入库封存。回望此鏖战数载之所,百感交集,既有怅然,亦有释怀。拂袖转身,顿感体轻,前路纵有未知,亦胜于此无望之内耗也。
此中滋味,非亲历者不能知。唯作俚语小诗一首,聊以自嘲,亦以志今日之决绝也。诗曰:
码积如山会海滔,
纠错常致发际高。
千行代码半天搞,
百个接口随意调。
不懂技术瞎指导,
张口闭口新风潮。
代码入库呈终稿,
键盘鼠标皆可抛!
继续阅读 →我上高中的时候曾经自己总结出了一个不等式:
\[\frac{a^{n+1}}{c^n}+\frac{b^{n+1}}{d^n} \geq \frac{(a+b)^{n+1}}{(c+d)^n}\]
其中\(a,b,c,d>0\),且\(n\)为正整数。取等号的充分必要条件是\(\frac a c = \frac b d\)。
当时发现有若干问题,采用这个不等式可以迅速得到答案,比使用导数求极值的方法少了许多计算量。我自己琢磨了一阵子,终于证明了这个不等式,并记录在了自己的笔记本上。我以为我发现了什么了不起的结论。今天才知道,其实它叫权方和不等式,早就有人研究过了。而我在整个高中从未听说过它。
我的笔记本也早已丢失。这两天沿着之前的思路重新证明了一遍。
继续阅读 →2015 年的时候,我设置了 Wercker 工作流。每次本站的源代码仓库更新时,Wercker 的工作流会自动做两件事:1) 由 Markdown 源码构建静态网站;2) 发布到 github.io 上去。
时过境迁,Wercker 从某一年开始被 Oracle 收购了,直到去年的某个时候,我的工作流似乎不再工作了。wercker.com 现在会自动重定向到 Oracle Cloud 的网站;我甚至没法登录原来的 Wercker 账号。因此我需要找新的方法。
Github 在这些年也改变了很多,新增加的 Github Actions 功能在我看来就是一个抄袭了 Wercker 的功能。由于跟 Github 整合的更好,想必拉拢到了不少的用户群(拥有用户群的平台就是可以占便宜推广自家产品)。我也把自动构建的工作流迁移到了 Github Actions。
继续阅读 →长期以来, Go 语言缺乏泛型 (Generics) 的支持。曾经有人认为在 Go 2.0 问世前都不会支持泛型。我很久没有关注 Go 语言的动态了(最后一次写的 Go 项目还没有用 module 机制),今天才发现一年前的 Go 1.18 就已经增加了泛型。
简单地说,泛型可以将同一段代码作用在多种数据类型上。C++ 里的模板 (template) 就是一种泛型编程的方式。下面的 max
函数返回两个参数中较大的那个。不论 a
b
是什么类型,只要支持 <
运算符,就可以用这个函数。
template <typename T>
T max(T a, T b) {
return a < b ? b : a;
}
// max(1, 2) == 2
// max(2.5, 3.1) == 3.1
在 Go 中,一直没有比较好的方法实现这个效果。像 max
这种简单的函数,一般可以用的时候现场写一个,只是不太方便。
现在,可以在 Go 写一个泛型函数来实现:
import "golang.org/x/exp/constraints"
func max[T constraints.Ordered] (a, b T) T {
if a < b {
return b
}
return a
}
// max(1, 2) == 2
// max(2.5, 3.1) == 3.1
// max("abc", "def") == "def"
constraints.Ordered
包括有能比大小的类型(数值类型和字符串)。目前为止,constraints
还没有正式加入标准库中,只能从 golang.org/x/exp
这个实验性质的 module 中获取。
继续阅读 →这一篇研究怎样使用PIC控制彩色LED。
彩色LED可以使用4引脚的RGB共阴发光二极管。
阴极接Vss,RGB三个阳极经过限流电阻分别接三个GPIO引脚。PIC的GPIO可以输出25mA电流,足够直接驱动LED,无需额外的晶体管。
继续阅读 →微控制器 (MCU) 也叫单片机,指把处理器、内存、各种外设集成在一块芯片内的计算机。现在的个人计算机的数据总线宽度已经达到64位,而微控制器一般还停留在8/16/32位。可见,微控制器的功能相对有限,但对于一些简单的控制系统来说已经足够。由于微控制器价格低廉、简单易用,它也常常被用在一些业余硬件项目中。
这个系列将要讨论的是8位微控制器,属于微控制器中的底层。常见的8位微控制器有:
继续阅读 →《高等算术》第六章主要研究二元二次型 ax²+bxy+cy² 的理论。这一章主要研究了等价二次型、正定二次型的约化等价形式,以及二次型的表示问题(这是二平方和问题的推广)。
继续阅读 →《高等算术》第五章研究将自然数表示为平方和的方法,讨论了三种情况:
- 二平方和:所有形如 4k+3 的质因子的次数必须为偶数(可以是 0);
- 四平方和:任意自然数都可以表示为四平方和;
- 三平方和:除了形如 4l(8k+7) 外的自然数都可以表示为三平方和(未给出证明)。
对于二平方和问题,书中给出了若干构造方法。
继续阅读 →