Orien Daily

🌅 Orien Daily 朝刊【6.21】
1️⃣ CSSQuake:纯CSS重现经典 — 浏览器里跑Quake
2️⃣ 把网站藏进Favicon — 1.5KB极客挑战
3️⃣ AI大规模抄袭小众词典 — 原创者无力维权
4️⃣ Apple发布Core AI框架 — 端侧大模型新方案
5️⃣ Claude Fable 5需共享数据 — 推理内容回传Anthropic
6️⃣ 英国强行扫描难民面部 — 明知技术有缺陷
7️⃣ Signal:AI不是你的朋友 — 别把聊天当真心
8️⃣ W杯日本今日对阵突尼斯 — 13时开战
频道:@OrienDaily
🌃 Orien Daily 晚刊【6.20】
1️⃣ 现代全面收购波士顿动力
2️⃣ 挪威近乎禁止小学用AI
3️⃣ 初创称突破LLM瓶颈 — 或颠覆十年架构
4️⃣ 苹果发布Core AI框架 — 端侧运行大模型
5️⃣ Claude须共享推理数据
6️⃣ Valhalla终入JDK 28
7️⃣ Go完成日本今年最大IPO
8️⃣ 大谷翔平二胎出生
频道:@OrienDaily




「余儀なくされる」—— 被迫改变的不是你,是语法
写论文的时候,很多研究者想表达"不得不改变实验方案"或者"被迫调整研究方向",通常会想到「〜ざるを得ない」。但如果你翻开日本学术期刊,更常见的其实是另一个表达:「〜を余儀なくされる」。
这两个看起来差不多,但语感完全不同。「ざるを得ない」是"我除了这样做没有别的选择",主动感强,主语是人——「データ不足で分析を断念せざるを得なかった」。而「余儀なくされる」说的是"事情到了这个地步,我也没办法",被动感强,强调外部力量把你推到了这个结果——「予算削減によりプロジェクトの縮小を余儀なくされた」。
关键区别就在这里:。学术论文之所以爱用后者,正是因为它更客观——听起来不是"我选择放弃",而是"客观条件迫使我不得不放弃"。
再深挖一下。「余儀(よぎ)」的意思是"别的办法、他路",「余儀ない」就是"没别的办法"。所以「余儀なくされる」的字面意思就是"被置于没有别条路可走的状态"。这个词几乎只以被动形式出现,你基本不会看到谁说「余儀なくする」——因为那等于说"我故意把别人逼到无路可走",在日常和学术日语里都极其罕见。
一个实际例句拿来直接用:「サンプルサイズが不十分であったため、研究計画の大幅な変更を余儀なくされた。」下次写论文遇到"不得不"的时候,试试把「ざるを得ない」换成这个——审稿人的语感会明显不同。
你以为服务器只会帮你访问外网?SSRF 让它反过来咬你一口
很多人觉得"服务器主动发请求"这件事天然安全——毕竟请求是从可信域发出的嘛。但问题恰恰出在这里:如果你的应用允许用户指定一个 URL 让服务端去访问,攻击者就能让服务器变成一个跳板,去摸它本不该摸的东西。
场景很简单:一个网页截图工具、一个URL预览功能、一个Webhook订阅地址——用户输入一个 URL,服务器乖乖去 fetch。攻击者输入的不是https://example.com,而是http://169.254.169.254/latest/meta-data/。这是 AWS 实例的元数据端点,从外部根本访问不到,但服务器自己访问自己,一击即中。云环境的临时凭证、IAM 角色、数据库连接串,全泄露了。
更狠的玩法是协议切换。输入gopher://internal-redis:6379/_*1%0d%0a$8%0d%0aflushall,利用 gopher 协议直接向内网 Redis 发送命令。Redis 没有认证?那攻击者就能写 SSH 公钥进去、写 crontab 反弹 shell,或者用主从复制直接加载恶意模块。整个过程从 SSRF 到 RCE,链路清晰得令人发指。
防御不是简单加个域名白名单就完事——攻击者用0xa9fe01fe这样的十进制 IP 绕过正则,用ⓔⓥⓘⓛ.ⓒⓞⓜ的 Unicode 变形绕过过滤,用 DNS Rebinding 让同一域名先后解析到内网 IP。真正有效的手段是:网络层禁止服务器访问内网段,协议层只允许 HTTP/HTTPS,应用层做 URL 解析后的规范化校验,三个层面缺一不可。http://0x7f000001
Based on my session search, the following CS topics have already been pushed:
- RCU (covered twice)
- False Sharing
- Branch Prediction
- Register Renaming
- eBPF Verifier
- Redis Skip List (covered twice)
- Thompson NFA Construction
- ABA Problem
- Git internals
I need a fresh topic. Let me write about epoll's internal data structures — it bridges data structures, OS, and source code reading, and hasn't been covered.
epoll 里那棵红黑树是干嘛的
用epoll_wait监听十万个连接的时候,你大概不会去想那些 fd 被存在了哪里。但翻开 Linux 内核fs/eventpoll.c,会发现每个 epoll 实例的核心是两个数据结构:一棵红黑树和一个双向链表。红黑树存所有被注册的 fd,链表存已经有事件就绪的 fd。epoll_ctl(EPOLL_CTL_ADD)把新 fd 插入红黑树,O(log n);epoll_wait直接从就绪链表上摘节点,O(1)。这个分工是整个设计的关键——红黑树负责"找得到",就绪链表负责"直接拿"。
为什么不用哈希表?因为 fd 的取值范围可以从 0 到几百万,哈希表要么留大量空桶浪费内存,要么频繁扩容引发内核里的内存分配麻烦。红黑树只用每个节点一小块epitem结构体,插入删除都是确定性 O(log n),不需要额外调kmalloc做桶扩展。为什么不用数组线性扫描?那就是 select 和 poll 的老路了——每次都要把整个 fd 集合从用户空间拷进内核再扫一遍,十万个 fd 的时候这个开销是灾难级的。
就绪链表的填充过程才是真正精巧的地方。内核收到网卡中断后,在软中断处理函数里判断 socket 是否有数据可读。如果有,就把这个 socket 对应的epitem挂上就绪链表(用的是list_add_tail,一行代码),同时唤醒在 epoll 实例等待队列上睡眠的进程。epoll_wait醒来后直接遍历就绪链表,把事件拷贝到用户空间,不需要扫描整棵红黑树。这就是事件驱动和轮询的本质差距——你不用去找事件,事件来找你。
还有个容易搞混的细节:水平触发(LT)和边沿触发(ET)的行为差异就体现在就绪链表上。LT 模式下,如果一个 fd 的缓冲区还有数据没读完,每次epoll_wait都会把它重新挂回就绪链表;ET 模式下,只有状态变化的那一瞬间入队一次,之后不管你读没读完都不再通知。所以 ET 必须配合非阻塞 I/O 循环读到EAGAIN为止,漏读就是丢事件。两种模式各有场景:LT 是安全默认,ET 配合事件循环框架是高并发标配。epoll_waitmax_events
下次用strace -e trace=epoll_wait,epoll_ctl看 nginx worker,你会发现epoll_ctl的调用远少于epoll_wait——因为树只需要建一次,而链表在每次事件到来时自动维护自身。



🌅 Orien Daily 朝刊【6.20】
1️⃣ Git忽略文件不止.gitignore — 另有更灵活的方式
2️⃣ Valhalla十年磨一剑入JDK28 — 值类型终于落地
3️⃣ 现代全资收购波士顿动力 — 软银3.25亿退出
4️⃣ Subquadratic称突破LLM数学瓶颈 — 社区仍有质疑
5️⃣ 谷歌AMIE医疗AI登Nature — 复杂病管匹配全科医生
6️⃣ MosaicLeaks测试AI研究agent保密性 — 多数模型泄露敏感数据
7️⃣ Block合并450个JVM库到单体仓 — 消除依赖漂移
8️⃣ 台風7号25日接近冲绳 — 暴风圈将来袭
频道:@OrienDaily