Hypercube's Channel
22 subscribers
19 photos
1 video
2 files
6 links
随便搞的一个 channel,还不知道会变成什么样
Download Telegram
to view and join the conversation
才知道 apt 对于一些 meta package 会自动把它的所有依赖标记为手工安装的。换句话说,不能相信 apt install foo 这条命令最多只会给 apt-mark showmanual 的结果增加一行。实际上可能增加任意多行你不认识的东西。

这个设计的本意是避免用户逐渐习惯某个软件,但因为没有标记为手工安装,后续被 autoremove 了。(autoremove 都不仔细检查列表的吗???)不过感觉好反直觉,给我管理系统带来了很多麻烦。现在我不得不自己追踪我“真正”想安装的包了,不能相信 showmanual 的输出。
试用 Pico Neo 3,感觉分辨率很好,可以用来浏览网页/写代码😃
今年 Hackergame 中有一道题“马赛克”,我本来以为很简单,但这两天写得挺折腾的,过程如下:

首先,当然是要存储对每个二维码块的知识(已知黑/已知白/未知),并计算出每个马赛克块由哪些二维码块按多少权重构成。其次,对每个马赛克块,尝试其下未知的二维码块的所有可能性,看是否只有一种可能性算出来的颜色和实际颜色匹配,如果是则将相关二维码块记录为已知。

这个思路解出的块太少,因为每个马赛克块都覆盖 9 个二维码块,如果全部未知的话有 512 种可能性。但马赛克块的颜色只有 256 种可能性,多数情况下都不能解出。改进方案:不断迭代,用已知信息进一步求解未知信息。

迭代几步后就无法取得进展了,此时仍然有很多块没有解出。我尝试把结果画出(试了两种画图方案,1. 未解出的块画成原始马赛克的颜色 2. 将 1 的结果二值化)并扫描,发现无法成功识别。

想到几个进一步优化的思路:
1. 马赛克遮住了 4 个小牛眼,它们可能对于识别更有帮助,所以手工在程序开始前标记为已知。
2. 对于某个马赛克块下方的二维码块,即使存在多种合理的可能性,无法唯一确定整个解,但只要某个二维码块在所有这些可能性中都是同一个颜色,就可以将它单独标记为已知。
3. 当迭代无法取得进展时,找出第一个仍未解出的二维码块,猜测它分别是白色和黑色,进一步求解。求解过程中如果再次无法取得进展就递归再猜,如果发现某个马赛克块无解就返回,如果成功解出就输出并返回。

把这几个优化都实现了,发现 1 和 2 能帮助多解出一点,但还是无法识别。3 比较成问题,应该是因为很多地方理论上就是无法确定,无论猜测成什么都不会有冲突,它们的笛卡尔积非常巨大,所以程序会输出成百上千个可能的解。因此不得不再加入一个功能,直接将每个解送入一个马赛克识别程序,识别成功才输出。跑了几分钟后终于解出了。

回去读官方题解,发现官方题解并没有做这些优化。研究了一番发现问题在于:
1. 给二维码加上正确的白边有助于提高识别成功率
2. 即使是未解出的块,整个方块内部也应该显示成一个统一的颜色,否则难以识别成功。例如将未解出的块全部显示成白色或者全部显示成黑色都可以识别成功。但我在这个阶段,只尝试了将未解出的区域显示原始马赛克颜色,或者二值化的结果,这都会导致一个二维码方块内部颜色不统一(因为马赛克的边界可能发生在二维码块内部),可能影响了边界判断相关的逻辑,导致一直没有识别成功。

(怪不得解出人数这么少,比赛过程中我一直好奇来着)
Telegram Web 有 z 和 k 两个版本,我目前注意到的区别:
- k 支持拖动选择多条消息,z 不支持
- k 支持选择多条消息后在右键菜单中转发或删除,z 不支持
- z 似乎无法显示 YouTube 等链接的预览,k 没有问题
- z 不显示每个会话是否被静音,并且对于新创建的会话可能有问题
- k 在网络切换/长时间断网后无法自动重新连接,必须刷新网页。z 可以自动重连

2021-12-20:
- k 会给长宽比不接近 1 的图片显示一个模糊的背景,z 不会
- z 会丢消息,刚刚有消息的频道和群,没有出现在会话列表中该在的位置
我觉得有很多情况下存在这种需求:在一个全新 clone 得到的 git 仓库中做某件事情(比如编译或者 docker build 或者测试),以避免 untracked files 和 ignored files 的干扰。虽然我知道很多人用 CI 解决这种问题(CI 自然会在全新的 clone 后做),但如果不想用 CI,我整理了 3 种比较简单的在本地的做法:

1. git clean 加合适的参数,可以删掉 untracked files 和 ignored files。我觉得这种做法并不吸引我,因为随意删掉这些文件会有坏处。有人可能会说 git stash 是一个替代方案,但如果文件比较大/有 git 无法保留的元信息(比如权限、属主等),也不好用。

2. git archive 可以产生一个包含 git 管理的文件的压缩包,很适合用于一些场景(比如你就是想做一个代码压缩包发给别人,不希望带上别的文件),但如果想作为一个目录使用就不得不再解压开,有点曲线救国。

3. git worktree add --detach <tmp path> 是我觉得最理想的选择,它可以在指定的目录 checkout 一份内容,里面只多了一个 .git 文件。如果目录被删除,之后这个 worktree 相关的配置信息会被 gc,不会对原本的项目目录产生任何影响。
关于 locale 和时区

首先,每台机器上都要安装一些 locale。有两种安装方法,一种是 apt install locales-all,这会安装上所有的 locale,然后就可以随便选用了,但会占用几百 MB。另一种是 apt install locales,这会安装上所有 locale 的源代码,只有几十 MB,但需要编辑 /etc/locale.gen 文件,取消注释自己需要的 locale,然后运行 locale-gen 命令,才会按需编译出选择的 locale。

其次,需要通过环境变量指定自己要用的 locale,有多个变量负责不同方面,参见 https://wiki.archlinux.org/title/locale 。这些变量在 login 过程中会被自动从 /etc/default/locale 设置,但也可以覆盖,一般 ssh 也会传输它。只有当设置的 locale 是机器上已经安装的时才有用。

我的结论是给我所有机器装 locales-all,然后在自己的 bashrc 中配置喜欢的 locale:
export LANG=zh_CN.UTF-8 # 按拼音排序、公制单位、数字格式、A4 纸张……
export LANGUAGE=en_US:en:zh_CN:zh # 接受的语言列表
export LC_MESSAGES=en_US.UTF-8 # 首选语言
export LC_TIME=en_DK.UTF-8 # ISO 8601 日期和时间格式

时区首先看 TZ 环境变量,如果没有的话会看 /etc/localtime 或 /etc/timezone。最好配置 TZ 环境变量,否则性能较差(而且 bashrc 是跟着我的,这才正确,即使我在用一台海外的机器,我也还是想看北京时间):
export TZ=Asia/Shanghai
今天升级了 Debian 11,顺便学习了一下怎么确保所有程序都拿到一些环境变量(如 locale 相关环境变量)。以下说明虽然并不完全精确,但或许会让理解相关概念简单一些。

环境变量应该在进程树中尽可能高的地方被设置一次,之后不要重复设置,一直从父进程继承。.profile 文件一般是用来做这件事的。在 sh 的时代,实现这个目标比较简单:如果 sh 发现自己是 login shell,说明用户刚刚登入,自己是这个用户的进程树中最高的进程,所以应该加载 .profile 文件。如果不是 login shell,则不加载。

在 bash 的时代,为了和 sh 保持一致,虽然可以有 .bash_profile,但 bash 也读属于 sh 的 .profile。因此无须专门创建 .bash_profile,用 .profile 即可。

但是 bash 还有另外一项功能,就是在每次启动时(如果是交互式)执行 .bashrc,以便设置一些无法从父进程继承的配置,例如 PS1 或 alias。不知由于什么原因,bash 被设计为如果读了 .profile,就不会读 .bashrc,虽然 .bashrc 的内容明明应该是每次交互式执行都需要的。为了解决这个问题,一般都在 .profile 中检查当前进程是不是 bash,如果是,就读 .bashrc,这样恰好修复了 bash 的这个问题。其他 shell 如果有类似问题,也应当这样修复。

这时,.profile 和 .bashrc 的区别就很明确了,前者应该存放环境变量等“只需设置一次,所有程序都要用”的信息,后者则仅仅是 bash 这一个软件内部的配置,和各种其他软件的 rc 文件类似。这样编写内容后,如果有软件不按这样的思想工作,应该设法修复。

例如,在桌面系统中,从图形界面登录后,会发现 .profile 没有被加载过,那就要设法让 display manager 程序(用户的进程树的顶端)加载 .profile。有的系统中相关软件被配置为会读取 .xprofile 文件,Debian 系统则规定一律使用 .xsessionrc 文件。因此对于我来说,在 .xsessionrc 文件中写上一行载入 .profile 的命令即可。

如果通过 ssh 连接远程机器,因为登录后启动的第一个进程会是 bash,所以它会作为 login shell 读取 .profile,没有问题。

如果把这些文件放进了 docker 中(虽然这样做有点奇怪👀),然后直接在 docker 中启动 bash,会发现 bash 并不读取 .profile,因为不是 login shell,这又违反了上面说的思想。可以通过以 root 身份执行 login -f username 解决,这会启动一个 login shell,确保读取 .profile。这还有额外的好处,login 会设置一些基础环境变量,例如 USER SHELL 等(不走这个流程的话默认是没有这些变量的),还会进入用户家目录,产生一个相当正常的环境。
访问百度统计后台页面,发现到处都是 Noto Serif CJK SC 字体(serif 表示衬线字体,一般对应中文宋体,sans-serif 表示无衬线字体,一般对应中文黑体),好难看,分析了一番发现是我没装微软雅黑,于是命中了 SimSun 这一项(虽然我也没装 SimSun,但它被配置为衬线字体的别名了)。

想了一会要不要修改字体配置,把微软雅黑作为非衬线字体的别名,这样只要微软雅黑在前面就会命中,然后选中 Noto Sans CJK SC。但忽然又开始想,我们为什么要花这么大力气在网页上指定字体列表,再在自己的电脑上配置字体规则呢?对于多数对字体没有特殊要求的网站(“选用户设备上最好看的非衬线字体就行”,这是绝大多数网站其实在追求的目标),为什么不能在字体列表中只写 sans-serif 一项,靠用户设备来决定最佳的字体呢?

例如,对于中文字体,一些网站会先放苹果的字体,再放微软雅黑,再放 Linux 常见的字体。这里主要的考虑是苹果用户可能会安装微软雅黑,但还是苹果的字体渲染效果更好。Windows 用户可能会安装 Linux 上常见的自由字体,但因为有 ClearType 加持,Windows 上微软雅黑的效果还不错。然而这样配置的一个问题就是,Linux 用户如果安装了微软雅黑,会被优先命中,它在非 Windows 上显示效果不好。

为什么网站要负责做这件事??每个设备被配置了其上最好看的字体,然后被一个通用的规则(比如 font-family: sans-serif)选中,不是很正常的事情吗?如果这样并不会选中最好的字体,导致网站必须“帮”用户选,那是哪个环节出了问题呢?
试用 Oculus Quest 2 + Immersed,设备不如 Pico Neo 3 舒适,但 Immersed 体验不错并且运行流畅。鼠标移动时有一点延迟导致的滞后,但其他操作几乎感觉不到延迟。
认真试了试在 Immersed 中工作,其实感觉还不错。为了舒适(减轻压脸感),我是仰躺着用的,把电脑放在腿上使用键盘和触摸板。天空上有一个巨大的显示器,宽度略大于 VR 的视角。在这个条件下文字很清晰,而且比较大。一个小问题是如果开两个窗口,在一侧写代码,参考另一侧,眼睛需要左右移动的距离有点长,比较累。另外,如果把一个 terminal 窗口最大化(比如我每次执行 docker ps -a 或 docker images 时都会最大化),就太大了,看边角上的信息不舒服。

做了一些工作后退出来休息,发现虽然我的笔记本的 13 寸显示屏很小,但很清晰,感觉不比 VR 中那个巨大的显示屏差。另外,由于 VR 设备太重了,戴着时不是很喜欢四处转头,其实视角反而是更小了。

结论:如果 Immersed 将来支持其他更高端/更舒适/分辨率更高的 VR 设备(目前只支持 Oculus Quest 1&2)的话可以考虑,另外 Linux 上虚拟显示器的支持也值得期待(目前 Linux 只支持投射物理显示器,不支持创建虚拟显示器)。但在目前这个条件下,感觉没有带来什么额外价值。
感觉 Telegram 更新有点太多了😅跟不上节奏。不过最新的更新似乎还是挺香的,我一直希望能直接翻译消息,之前调研过别的 bot,也想过自己写 bot 实现,现在直接原生支持了。reaction 这个功能也是有很多人在用 bot 实现,而且是其他一些软件中我很喜欢的功能(比如 slack 可以给一条消息点“👌”),终于原生支持了。至于 spoiler,嘛,感觉不怎么常用,但也是一个“大家一直在用 bot 解决的事情被官方支持了”的例子。

(什么时候把中文搜索解决了就更好了)
每年发红包的时候都在想,这种发红包形式有两个问题:
1. 没有匿名性,各种意义上的。比如能看到别人的支付宝账号,能知道谁领了谁没领,能知道哪些支付宝账号背后的人关注了这个频道等等。
2. 没法防止一人领多次(例如通过小号或者把口令转发出去)

密码学和加密货币在理论上可以完美地解决这两个问题,可惜每年调研的结果都是相关工具太不成熟了,没什么方便的方法搞。

大概思路是,首先需要确定有权领红包的人的范围,假设为 n 个人,获得每个人的公钥。把 n 份钱放进类似 tornado cash 的混币池里,并把每个收据加密发给一个人。(这样有个问题是发红包者可以悄悄把一些人的红包领了,谁也没法证明是谁领走的。如果直接用公钥做成 merkle tree 让大家领的话可以避免这个问题,但谁领了谁没领就变成公开信息了。)
嘿嘿嘿,麻将好玩
得到了罕见的纸钱(激动)

终于抽时间去退了地铁卡,去之前就在想,会以什么形式给我结算呢,结果果然是纸币。这是我非常久以来第一次遇到用纸币结算的情况了。

不过问题来了,怎么才能把它们变成电子的钱呢?好不方便的样子。
若饭给我发来的货只剩 1/3 保质期了,好坑啊。我知道理论上只有销售过期食品才是被禁止的,保质期内一般都视为质量合格可以销售,但网购而且大宗购物这种场景确实比较特别,既不能自己主动挑选,又受保质期影响明显。发来的食品还有多少保质期才算合理?这个问题好像确实比较复杂。

咨询了一下京东客服,答复说一般来说分界线是 1/3,就是说剩下不到 1/3 的话是不行的。那估计若饭是专门卡着这条线发货了(查了一下,上次发的也是这样)。

注:两次遇到刚好 1/3 都是桑茶味若饭,保质期只有 6 个月。原味若饭目前没发现过这种行为。