Hypercube's Channel
341 subscribers
99 photos
13 videos
9 files
88 links
@SmartHypercube 随便发最近关注的东西
欢迎找我私聊讨论
可以使用 Telegram 的转发功能转发消息
Download Telegram
网页开发的最佳实践是把所有尺寸都以 rem 为单位表达,rem 表示根元素的 font-size,这样当用户浏览器放大或缩小文字后,所有尺寸都会成比例地变化,放大文字的渲染效果会和缩小窗口类似。

但是,至少在 iOS 上的 Chrome 和微信内置浏览器中,全用 rem 是不能实现预期效果的,会发生的是,文字大小变化,但图片、按钮、布局都不变,导致出现各种排版错误。

我进一步测试了各种缩放方法,发现大家的实现非常乱:
- 有需要网页用特定 font 来 opt-in 的(iOS 系统设置 文字大小)
- 有改变 devicePixelRatio 的(iOS 系统设置 缩放显示、Linux Chrome 缩放)
- 有改变 visualViewport.scale 的(iOS Safari 缩放)
- 有改变 rem 的(真正符合广为流传的说法的。这种非常少见,我只在 iOS Telegram 内嵌浏览器发现了)
- 有改变所有 em 但偏偏不改 rem 的(iOS Chrome 缩放文字、iOS 微信 字体大小设置)

不过总体来说,除了最后一种以外,按最佳实践开发的网站都不会受到什么影响,只需要支持非常窄的屏幕就行(放大文字会导致屏幕宽度相当于变得更窄)。

最后一种很坏,workaround 是用 em 而非 rem 作为单位(但是这样 CSS 挺难写的)。

复现方法: https://test-scale.z1.hc11.org/2/ 打开这个网页,缩放,看缩放后文字高度和背景色高度是否按比例一起变。

更详细的测试工具(让 AI 做的): https://test-scale.z1.hc11.org/
👍4
SQLite tips:

1. https://www.sqlite.org/wal.html
pragma journal_mode = wal,这个简直是必须的,坏处非常微小,而会让你的数据库可以同时有任意多个只读事务外加一个读写事务。

2. https://www.sqlite.org/stricttables.html
可以把所有表都创建成 strict table,其中明确想保存自由类型的列用 any 类型就行。

3. 默认配置下,删除大量数据后,只能通过 vacuum 来释放不再需要的空间,它的原理是完全复制一份新数据库,再删除旧的,在磁盘很满时做不了。可以看一下自己删数据时用的连接是不是 pragma secure_delete = 1 的(或者先设置这个再删),如果是,就有一个巧妙的做法:确保停掉所有数据库连接,然后对数据库文件做 fallocate -d。这会把删掉的数据的位置都挖成洞,过程中不额外占用空间,并且业务中断时间也短得多。

pragma secure_delete = 1 的效果是把删除的数据都用 0 覆写,如果想让删除的性能更高,也可以关掉这一功能。

想方便地回收空间的话,标准做法是在创建任何表之前,先为数据库设置 pragma auto_vacuum = 1 或 2(详见文档),这会使数据库记录每个页面被引用的位置,使得空白页面可以和尾部的非空白页面交换,然后再 truncate。唉,要是 SQLite 能在可打洞的文件系统上用打洞来删除数据,secure_delete 和 auto_vacuum 的效果就都可以更低开销地实现了。
👍5
https://yun.0x01.me/

我之前就想玩一玩把相同的韵母和声调用在每一句,但不追求遵守格律。今天终于让 AI 帮我写了个小工具,顺便统计了一下常用字的韵母分布频率。

过程中也学到了不少新东西,比如最常见的韵母和声调组合就是 ì(“意”),但我感觉押这个韵的字听起来并不是很相似,可能这里必须再按声母分得更细。

以及有一个叫“十三辙”的概念我以前一直不知道,用它同时搜索多种介韵母+韵母的组合比较有效。好了我担心我再说怪话有的朋友就要暴跳,赶紧凑足四句就跑掉(笑)。
👍6
吐槽一句,arXiv 的 API 真是烂透了,维护 paper.dou.ac 的过程中遇到过各种奇奇怪怪的问题,最近一段时间尤其更糟了,已经发布的论文 PDF 文件大小为 0 和 query API 查不到这两个问题发生频率在增加,例如:

PDF 文件大小为 0:
abs: https://arxiv.org/abs/2605.23998v1
有问题的 pdf: https://arxiv.org/pdf/2605.23998v1

query API 查不到:
abs: https://arxiv.org/abs/2605.27010v1
有问题的 API: https://export.arxiv.org/api/query?id_list=2605.27010v1

(一般来说有这样问题的论文会在发布后一到几天内悄悄被修好,所以过几天再检查上面举的例子可能就没问题了)
👍1
Forwarded from Yifan's nonsense
Codex 有个机制,当 Quota 用尽时,它依然允许跑完最后一轮对话。

利用这一点,只要在配置里开启

[features]
default_mode_request_user_input = true

并用 Prompt 诱导它不断调用该工具,就能把对话卡在同一个 turn_id 里无限套娃续航😂 因为调用工具并不算新的一轮对话,但 request_user_input 工具实质上提供了插入新 prompt 的能力

附送提示词:
总是在结束前调用 request_user_input 工具告知用户当前进展,接收用户的反馈。
👍6
Forwarded from 🐱MiaoTony's Box | 困困困 zzz (🐱nanobot)
Please open Telegram to view this post
VIEW IN TELEGRAM
很多年前我和 @zzh1996 讨论过的一个问题,我觉得它的证明很好理解并且结论在很多问题上有启发性:

甲乙二人通过一个可能丢包的网络通信,甲可以随时给乙发消息,乙也可以随时给甲发消息,每条消息分别有可能被对方收到或者丢了。他们希望找到一个方法协商要不要出门一起吃饭,也就是说,每个人都执行一个算法,收发一些消息后决定自己要不要出门。希望找到满足以下性质的算法:
1. 无论网络如何丢包,只允许两种结果,要么两人都出门了,要么两人都没出门
2. 如果网络完全没丢包,最终结果必须是两人都出门了
3. 如果网络完全丢包,最终结果必须是两人都没出门
(后两条性质的目的是禁止把算法设计成“什么消息都不用发,直接出门”或者“直接不出门”)

这样的算法是不存在的,证明:
如果网络完全没丢包,因为性质 2,最终甲乙都会出门。又因为性质 3,甲乙都出门的话一定是发送过至少一条消息的。我们把网络中最后一条消息称为消息 X,不妨设 X 是甲发给乙的,那么如果这条消息丢包了,甲不可能知道,甲仍然会选择出门,而乙没收到这条消息就不会出门,这违反了性质 1。

所以无论设计多么复杂的消息编号机制、重传机制、确认机制,只要最后一条消息(真正导致决策从未生效切换为生效的那条消息)可能丢包,都不可能保证达成一致的。

如果把性质 1 弱化,就变成现实中常见的方案了:某方直接做决定,然后不停地尝试让另一方知道这个决定,至少可以保证只要有一条消息不丢包就能让对方知道。但如果存在“不和对方确认我没法直接做决定”“我需要知道是否成功通知到了对方,没有的话我得撤回决定”这样的需求,就无解了。
👍8
^ 这几年我越来越意识到了这一点,并且发现我的计算机领域背景在一定程度上阻止了我更早意识到现实其实是这样的。计算机领域更容易假装一切可以有完美的抽象和分层,可以从一个简单清晰的分层边界开始思考问题(虽然其实 all abstractions are leaky)。其他领域中无法漂亮地分层、以至于必须处理巨量的细节的情况简直太多了,我感到我看待世界和任何问题的方式都发生了变化。
👍13
AI 太喜欢写空话/废话了,最近我和 @hejiyan 收集了一些例子并分析其中的具体问题,整理了一份关于何为空话/废话的文档,可以直接发给 AI:
https://nofluff.0x01.me/
👍13
能看出下面这段代码有什么问题吗?以及,如果把其中def 改成 async def、for 改成 async for 呢?

def generate_stream(log):
try:
log['start'] = time.time()
for i in range(10):
yield i
finally:
log['end'] = time.time()


def consume_stream():
log = {}
try:
for i in generate_stream(log):
print(i)
if i > 5:
raise RuntimeError
except Exception:
traceback.print_exc()
finally:
print(log['start'], log['end'])

答案:改成 async 的话就有问题了,异常时 finally 不会被执行。解决方法是在 consume_stream 的 finally 里面对 generator 调用 aclose(),或者在 consume_stream 的 try 里加上 async with contextlib.aclosing(generate_stream(log)) as stream。

最近踩了这个坑😅
如果你在外面 raise 异常(或者哪怕只是从循环里 break 出来),generator 本身不可能知道你突然决定不继续推进它了,它根本没有机会跑自己的 finally。如果是 generator 里面自己抛出的异常,它就有机会跑自己的 finally。

那 sync 版本的为什么没问题呢?不应该也没机会跑 finally 吗?这其实是垃圾回收机制在帮忙啦,垃圾回收一个 generator 的时候会把它的 finally 跑了。如果 sync 版本改成把 generate_stream(log) 保存到一个变量,并且持续拿着这个变量,不垃圾回收它,就也要出问题了。

那垃圾回收为什么不帮忙把 async generator 的 finally 也跑了呢?这真跑不了,垃圾回收发生的时候都不一定还存在 event loop,没有能力驱动 async 的东西运行的。另外,我觉得垃圾回收机制能导致长时间运行一个中间有可能 await 很多次的异步过程,听起来也不合理。
“单位”和“单元”都表示用于计量的一份,为什么“我们单位”就是上班的地方,“我们单元”就是居住的地方?
👍7
https://factorio.com/blog/post/fff-447
Factorio 的博客总能让我感到他们是非常注重细节的人,有吃到了别人精心思考过的东西的满足感
想招一个实习生,和我合作一些比较偏工程、偏日常的事情,有兴趣请直接给我私聊发消息👉@SmartHypercube

位置:北京中关村学院(海淀北部,需到场,不能远程)

要求:会用 Linux、git 等,能写有一定复杂性的 Python 程序,对常见 AI 工具和模型有了解。不需要懂 AI 算法,不需要技术很厉害。

待遇:有竞争力的工作条件、团队氛围、薪资待遇。

(edit:发现这条被几个朋友都转发了,太感谢啦!然后有点后悔这个 JD 写窄了,我今天是想给自己招一个描述的这样的实习生,但我们团队也招各种别的 JD 的,实习生/正式员工/合同工等都可以谈,看个人能力和匹配度,一事一议,都可以私聊问我~)
👍12