<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="/rss.xsl" media="all"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
<channel>
<title>Roastidio.us Tagged with 技术</title>
<link>https://roastidio.us/tag/2721</link>
<atom:link href="https://roastidio.us/tagged_with/%E6%8A%80%E6%9C%AF" rel="self" type="application/rss+xml"></atom:link>
<description>Roastidio.us Tagged with 技术</description>
<item>
<title>在家里运行网站</title>
<link>https://blog.3qin.us/hosting_web_application_at_home.html</link>
<enclosure type="image/jpeg" length="0" url="https://mail.3qin.us/~derek/blog_imgs/pics/vpn_to_home.png"></enclosure>
<guid isPermaLink="false">u2TRZV4Mqm3osCjjSRh0_OgEK5IGIWIQeisQ3w==</guid>
<pubDate>Thu, 19 Mar 2026 23:06:06 +0000</pubDate>
<description>更准确的说法是web应用。现在大量的应用，例如办公包括G-suite，Office 365，Reddit，Grammarly等其实都是web应用，你只需通过新一代浏览器，无需安装任何客户端软件即可使用。个人可不可以自己架设web应用呢？当然可以。一些web应用是自由软件，可以自行安装架设的。当然，需要做一番手脚。</description>
<content:encoded>&lt;p&gt;更准确的说法是web应用。现在大量的应用，例如办公包括G-suite，Office 365，Reddit，Grammarly等其实都是web应用，你只需通过新一代浏览器，无需安装任何客户端软件即可使用。个人可不可以自己架设web应用呢？当然可以。一些web应用是自由软件，可以自行安装架设的。当然，需要做一番手脚。&lt;/p&gt;
&lt;h2&gt;基础设施&lt;/h2&gt;
&lt;p&gt;首先，你需要注册一个域名。例如本博客使用的域名 &lt;code&gt;3qin.us&lt;/code&gt; 就是属于作者个人。这其中涉及一点费用，但相当廉价，大概每年十几美元左右。在这个网络时代，没有域名都不好意思说自己是网络公民了。&lt;/p&gt;
&lt;p&gt;第二，你需要有一个公网IP，包括v4+v6，和一台公网服务器。最廉价的方法是购买一个vps（虚拟主机）。例如我使用的&lt;a href=&quot;https://hostwinds.com&quot;&gt;hostwinds&lt;/a&gt;就是一个小规模的hosting公司，当然，大公司例如Amazon也提供hosting服务。我这里不建议使用web hosting，不如使用更底层的主机hosting，是因为价钱差不了很多，但你能做的事情多很多。以我使用的hostwinds VPS为例，最低档每月费用五块美元，而基本web hosting费用也要三块多。当然网上还有完全免费的web hosting，但请记住，hosting总要有成本，成本总要有人来负担。长久之计，这点成本还是自己来承担为好。&lt;/p&gt;
&lt;p&gt;第三，你需要有SSL证书。没有证书，人家根本不会上你的网站。好处是在有了域名，VPS之后，可以完全免费地获得SSL证书。不是刚说免费的东西都有问题吗？但在大规模部署，完全自动化的情况下，证书的生成及校验成本已经很低很低，公益机构&lt;a href=&quot;https://letsencrypt.org&quot;&gt;Let’s Encrypt&lt;/a&gt;完全包下来了。所以，任何有域名，有VPS的人都可以享受免费SSL证书，相当简便的初始安装，和完全自动化的更新。&lt;/p&gt;
&lt;p&gt;有了以上三点，你可以架设数量无限的http virtual host，每一个都是正规网站，包括域名和SSL证书，例如本博客。&lt;/p&gt;
&lt;h2&gt;进阶服务困境&lt;/h2&gt;
&lt;p&gt;以上仅是基础服务。廉价vps的问题是资源受限。例如我的5块钱vps来说，只给我单CPU，1G内存，30G SSD存储，每月流量上限1TB。我用它运行emacs和邮件服务没问题，流量也够了，但CPU，内存，存储都很差，想运行大型全栈web app总力不从心。正规的做法是升级你的VPS，大致到每月20块的水平就比较像话了。当然小农如我，是不舍得花这个钱的。怎么办？&lt;/p&gt;
&lt;p&gt;和vps可以对比的是家里的电脑资源。我已经付了家里的宽带费用，家里还有CPU，内存和存储相当不错的台式电脑。可惜，家庭宽带是有问题的：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;没有固定IP。动态IP处于居民区段，也没有信用。&lt;/li&gt;
&lt;li&gt;ISP端有防火墙，限制很多网络行为。&lt;/li&gt;
&lt;li&gt;现在的ISP甚至控制你家里的接入设备，连端口转发都不能搞。&lt;/li&gt;
&lt;li&gt;上下行带宽不均衡。主要限制在上行比较差。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;可见，VPS有的问题家里没有，但家里有的问题VPS也没有。二者要是能结合起来就好了。&lt;/p&gt;
&lt;h2&gt;VPN&lt;/h2&gt;
&lt;figure&gt;
&lt;img src=&quot;https://mail.3qin.us/~derek/blog_imgs/pics/vpn_to_home.png&quot; alt=&quot;vpn tunnel&quot; title=&quot;&quot;/&gt;
&lt;figcaption&gt;vpn tunnel&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;一个自然的想法是架设VPN打通家里和VPS。有了VPN之后，我可以在家里运行大型服务，通过VPS做端口转发，展现在公网上，如下图所示：&lt;/p&gt;
&lt;p&gt;一个相对好用好安装的VPN软件是&lt;a href=&quot;https://openvpn.net&quot;&gt;openvpn&lt;/a&gt;。但这样也有自己的问题：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;VPN导致家里内网门户大开，你还需要周全的防火墙来保证安全。&lt;/li&gt;
&lt;li&gt;所有服务运行在家里，这样家里一旦断网，所有服务全部下线。&lt;/li&gt;
&lt;li&gt;所有服务运行在家里，大大加重了家庭网络的上行负担。&lt;/li&gt;
&lt;li&gt;最后，VPN相对安装维护复杂一点。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;其实我并不需要IP级网络沟通，我所需要的所有网络服务其实都是web服务，全部走HTTP协议。针对这点，有没有更好的方法呢？&lt;/p&gt;
&lt;h2&gt;container + ssh tunnel&lt;/h2&gt;
&lt;figure&gt;
&lt;img src=&quot;https://mail.3qin.us/~derek/blog_imgs/pics/ssh_to_home.png&quot; alt=&quot;ssh tunnel&quot; title=&quot;&quot;/&gt;
&lt;figcaption&gt;ssh tunnel&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;我最后使用的方法是用container + ssh tunnel + proxy caching. 这个架构比较非常规，解释不如看图：&lt;/p&gt;
&lt;p&gt;下面分三部分分别讲述：&lt;/p&gt;
&lt;h3&gt;前端&lt;/h3&gt;
&lt;p&gt;前端在VPS上运行nginx。每一个应用对应一个nginx 上的 vhost。资源要求小的静态网站，例如本博客，直接运行在vps上。资源要求大的应用使用reverse proxy向后端传递。为了尽量降低家庭网络上行瓶颈，在前端的nginx内使用proxy cache来暂存后端响应，主要针对静态资源。&lt;/p&gt;
&lt;h3&gt;后端&lt;/h3&gt;
&lt;p&gt;后端在家里的电脑里。最好使用固网连接的台式电脑，并使用Linux，防止无线网络不稳定，或电脑自动休眠等问题。每一个应用对应一个lxc container。每一个container都是完全自洽的，包含所有数据库等应用的支持在内。这样有利于迁移管理。由于前端已经有nginx和ssl部署，后端直接暴露非SSL的应用服务器，应用服务器直接服务静态资源。&lt;/p&gt;
&lt;h3&gt;隧道&lt;/h3&gt;
&lt;p&gt;从每一个后端容器，向前端vps分别做ssh隧道，打通本服务所需要的端口。映射的端口仅通到vps本机，向外的服务完全由nginx再proxy出去。由于家庭网络断线的概率不小，这里每一个tunnel都有自己的守护进程，一旦断线立刻重连。&lt;/p&gt;
&lt;h2&gt;分析&lt;/h2&gt;
&lt;p&gt;这种部署方式兼顾了安全性和易维护性，同时不需要额外成本。当然缺点还是有：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;系统瓶颈还是在家庭网络上行带宽上。nginx的proxy cache不理解应用逻辑，只能求稳，对带宽的节约有限。&lt;/li&gt;
&lt;li&gt;家庭网络断网，断电等可能性多，整个系统在线率不高，最多99%。网络断线后只剩有限的静态服务。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;由于带宽受限，视频或网盘之类应用恐怕效果不佳。如果想运行更可靠更高速的服务，还是购买高档一点的vps服务为好。&lt;/p&gt;
&lt;p&gt;在这个架构上，我已经可以做一些在廉价vps上做不到的事情。例如我的&lt;a href=&quot;https://discourse.3qin.us&quot;&gt;discourse&lt;/a&gt;。&lt;/p&gt;</content:encoded>
</item>
<item>
<title>2020改版通知</title>
<link>https://blog.3qin.us/face_lift_2020.html</link>
<enclosure type="image/jpeg" length="0" url="https://mail.3qin.us/~derek/blog_imgs/pics/derek.jpg"></enclosure>
<guid isPermaLink="false">1ccizJ1NkuejG-XILGHVgRLS_N39nxID4Fgtrw==</guid>
<pubDate>Mon, 16 Mar 2026 21:01:34 +0000</pubDate>
<description>大家可能已经注意到本博客近期做了改版。速度是不是快的好像要飞起来一样？改版的主要目的是清爽易用，希望大家喜欢．下面逐条这次的改动介绍．</description>
<content:encoded>&lt;p&gt;大家可能已经注意到本博客近期做了改版。速度是不是快的好像要飞起来一样？改版的主要目的是清爽易用，希望大家喜欢．下面逐条这次的改动介绍．&lt;/p&gt;
&lt;h2&gt;RSS2 feed&lt;/h2&gt;
&lt;p&gt;过去本博客只有JSON Feed. 但是，JSON Feed支持的客户端比较少，所以增加了更流行的RSS. 注意，只支持RSS2.0, 1.0版本不支持．目前所有常见的Feed aggregator 都应该可以直接使用，有问题请及时&lt;a href=&quot;mailto:derek@3qin.us&quot;&gt;通知我&lt;/a&gt;。&lt;/p&gt;
&lt;h2&gt;放弃后台加载&lt;/h2&gt;
&lt;p&gt;过去，本博客列表是后台Ajax加载的，其本意是提高用户体验，避免长时间等待．但评估后发现我的内容还很少，后台加载实际上是画蛇添足，并没有提高用户体验，反而增加了复杂度．现在我改成全嵌入在主体HTML里，一次性加载，简化了前后台程序，提高了兼容性．&lt;/p&gt;
&lt;h2&gt;新 CSS&lt;/h2&gt;
&lt;p&gt;这是最大的用户可见改动．过去我出于习惯，一直使用&lt;a href=&quot;https://getbootstrap.com/&quot;&gt;bootstrap&lt;/a&gt;. 但是，本博客使用到的bootstrap功能恐怕还不到1%, 反而带入一个非常大的CSS及Javascript包. 这次改版我改用了精简很多的&lt;a href=&quot;https://purecss.io/&quot;&gt;Pure CSS&lt;/a&gt;. 正如其名，Pure CSS并无javascript部分，仅包含CSS, 而且这个CSS只有Bootstrap十分之一大．排版功能对我来说也够用了．这加快了加载速度．&lt;/p&gt;
&lt;h2&gt;新 Javascript&lt;/h2&gt;
&lt;p&gt;对于前端来说，重头戏永远在Javascript, 虽然用户不可见．过去出于十几年的习惯，我一直使用&lt;a href=&quot;https://jquery.com/&quot;&gt;JQuery&lt;/a&gt;. 但本博客使用到的JQuery功能其实也不到十分之一．由于近几年浏览器的演进，实际上JQuery提供的常见功能如DOM查询修改等等，都可以用标准Javascript API来做了，只是稍微繁琐一点而已．我主要参照的是&lt;a href=&quot;https://tobiasahlin.com/blog/move-from-jquery-to-vanilla-javascript/&quot;&gt;这篇文章&lt;/a&gt;, 有兴趣的朋友可以参考一下。&lt;/p&gt;
&lt;p&gt;在去除了Bootstrap, JQuery之外，我已经完全去除了对第三方Javascript库的依赖，所有Javascript只有一个文件，2KB大, 相当于之前1%大小．&lt;/p&gt;
&lt;p&gt;当然，只是做减法也没意思．我又在Javascript层加入了&lt;a href=&quot;https://github.com/turbolinks/turbolinks&quot;&gt;Turbolinks&lt;/a&gt;. 它的原理难以用几句话描述，但只需要加入这个库，再写几行代码，你所有的站内页面跳转都变得&lt;em&gt;很快&lt;/em&gt;，简直就是瞬间变脸，不信你&lt;a href=&quot;https://blog.3qin.us/welcome.html&quot;&gt;试试&lt;/a&gt;. 当然，这也不是没有任何限制．你写的Javascript需要遵循一定的规范．具体内容请阅读文档．&lt;/p&gt;
&lt;p&gt;加入turbolinks之后我的总体Javascript包大小涨回了40KB, 但与获得的跳转性能来相比，这是相当值得的．&lt;/p&gt;
&lt;h2&gt;总结&lt;/h2&gt;
&lt;p&gt;现在本博客主页加载在有cache情况下，应该不到500ms, 无cache情况下总加载大小一百多KB, 大多数网络情况不到一秒．页间跳转时间基本忽略不计．新版面相对之前个人觉得更自然清新，操作也直观．希望能听到你的&lt;a href=&quot;mailto:derek@3qin.us&quot;&gt;反馈&lt;/a&gt;．&lt;/p&gt;</content:encoded>
</item>
<item>
<title>通过吐槽俱乐部留下并找回你的话题</title>
<link>https://blog.3qin.us/keeping_and_finding_your_topic.html</link>
<enclosure type="image/jpeg" length="0" url="https://mail.3qin.us/~derek/blog_imgs/pics/derek.jpg"></enclosure>
<guid isPermaLink="false">i_a7u8fEe7DY3Hxs1edOVTjT0RnBZCoSrtZZVg==</guid>
<pubDate>Sat, 14 Mar 2026 02:11:57 +0000</pubDate>
<description>我认为, 比制造谎言更恶劣的行为是删文章 。可惜，今天不仅有平台以种种名义删除用户上传的文章，还有一些作者自甘堕落，自己删自己写的文章。在微信公众号上，这类现象比比皆是，一些链接等下再点，就再也点不通了。 我其实一点也不喜欢微信公众号这种传播方式 , 但我的朋友还有不少依赖于类似平台来获取信息，所以，今天我介绍一下 吐槽俱乐部 的一些用法，...</description>
<content:encoded>&lt;p&gt;我认为, &lt;a href=&quot;https://blog.3qin.us/how_to_tell_hearsay.html&quot;&gt;比制造谎言更恶劣的行为是删文章&lt;/a&gt; 。可惜，今天不仅有平台以种种名义删除用户上传的文章，还有一些作者自甘堕落，自己删自己写的文章。在微信公众号上，这类现象比比皆是，一些链接等下再点，就再也点不通了。&lt;a href=&quot;https://blog.3qin.us/weixin_7_sins.html&quot;&gt;我其实一点也不喜欢微信公众号这种传播方式&lt;/a&gt;, 但我的朋友还有不少依赖于类似平台来获取信息，所以，今天我介绍一下&lt;a href=&quot;https://blog.3qin.us/anti_social_media.html&quot;&gt;吐槽俱乐部&lt;/a&gt;的一些用法，可以帮你找回消失的文章，甚至可以作一番整理归纳。你挖坟也可，打脸也可，也可以用来治疗社交网络上常见的失忆症。&lt;/p&gt;
&lt;h2&gt;文章记录&lt;/h2&gt;
&lt;p&gt;你所有发到&lt;a href=&quot;https://roastidio.us&quot;&gt;吐槽俱乐部&lt;/a&gt;的任何链接，吐槽俱乐部都会在数据库里记录原文文字。你无需发表吐槽，甚至无需无言以对，提交链接就有。提交链接有多种方法，详见&lt;a href=&quot;https://roastidio.us/rules#quick_start&quot;&gt;吐槽俱乐部文档&lt;/a&gt;. 你发的任何话题都会生成一个唯一的站内链接，在站内话题链接内点击标题可以展示或隐藏当时抓取的原文。展示原文的直接链接形如：&lt;a href=&quot;https://roastidio.us/topic/518108?fulltext=t&quot;&gt;https://roastidio.us/topic/518108?fulltext=t&lt;/a&gt;, 在浏览器内点击可直接阅读数据库内的原文。原始链接附后，你也可以点进去看看文章是否还在，或跟当初有什么不同了。&lt;/p&gt;
&lt;p&gt;使用上需要注意以下几点：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;站内链接只对登陆用户开放。这是为了保护本站不被恶意攻击，或被长城屏蔽。&lt;/li&gt;
&lt;li&gt;数据库空间有限，只保留文字，不保留图片。公众号等平台对图片外链有相当限制，所以即使原始文章还健在，抓取的原文里图片可能无法展示。&lt;/li&gt;
&lt;li&gt;只有用户主动提交的文章才会被保留。这是因为微信公众号不提供开放接口遍历文章。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;文章找回&lt;/h2&gt;
&lt;p&gt;吐槽俱乐部目前收录了数十万篇文章，全部来自用户的直接和间接行为。你如何找回几天前，甚至上个月看过的文章呢？或者你如何在吐槽俱乐部的数据库内，自主浏览，找到你想看的文章呢？吐槽俱乐部提供若干种方法，在几个维度下提取数据库内已经存在的文章。&lt;/p&gt;
&lt;h3&gt;你的吐槽记录&lt;/h3&gt;
&lt;p&gt;过去一个月你的吐槽记录会直接显示在你登录吐槽俱乐部的入口里，并作时间和参与度排序。这个列表也可以匿名分享给别人，分享的方法是点击你的头像，选择&lt;code&gt;打开公众空间&lt;/code&gt;, 然后就会有一个公众空间的链接显示，例如我的是 &lt;a href=&quot;https://roastidio.us/user/KjQKkQVg&quot;&gt;https://roastidio.us/user/KjQKkQVg&lt;/a&gt;。 点进去和你的主页类似，只是没有你的任何个人信息。本页也可以作为一个RSS推送被订阅，订阅者可以收到动态更新。通过RSS订阅无需登录，但推送里只有摘要没有全文。如果你对RSS订阅工具还没有太强的偏好的话，我这里强烈推荐使用吐槽俱乐部的姊妹应用 &lt;a href=&quot;https://airss.roastidio.us&quot;&gt;Airss&lt;/a&gt; 来订阅，这样可以更方便和吐槽俱乐部交互。&lt;/p&gt;
&lt;h3&gt;全文搜索&lt;/h3&gt;
&lt;p&gt;吐槽俱乐部对数据库内所有文章提供&lt;a href=&quot;https://blog.3qin.us/find_topic_to_roast.html&quot;&gt;全文搜索功能&lt;/a&gt;。你可以到&lt;a href=&quot;https://roastidio.us/search&quot;&gt;这里&lt;/a&gt; 通过关键字找到对应的文章。使用中文搜索目前还存在一点技术难题：断词困难。目前断词靠的仅仅是空格和标点符号。所以除非你查找的短语在文中彻底被空格或标点完全隔开，否则是找不到的。例如：光靠&lt;code&gt;三国&lt;/code&gt; 是无法找到包含 &lt;code&gt;三国演义&lt;/code&gt; 的话题的，你需要输入完整的 &lt;code&gt;三国演义&lt;/code&gt;, 而且文章也必须存在单独的 &lt;code&gt;三国演义&lt;/code&gt; 字符串，前后没有其他未隔开的文字。&lt;/p&gt;
&lt;h3&gt;单一网络空间文章列表&lt;/h3&gt;
&lt;p&gt;每一篇文章都对应一个网络空间，在话题主页内有对应的网络空间文章列表链接。以微信公众号为例，对应的文章列表在&lt;a href=&quot;https://roastidio.us/webspace/4787&quot;&gt;这里&lt;/a&gt;. 微信公众号的链接无法细分，所以所有文章都混在一起。文章数量也不是很多。这是因为目前只有我自己可能会向吐槽俱乐部提交微信文章，而我又不常阅读微信公众号。同样，本页也可以作为一个RSS推送被订阅，订阅者可以收到动态更新。&lt;/p&gt;
&lt;h3&gt;短文字标记&lt;/h3&gt;
&lt;p&gt;对于中文读者，尤其是微信公众号平台读者来说，使用全文搜索功能受上述断词困难制约，公众号等网络空间又无法通过链接格式细分，所以这个短文字标记功能可能更有用。每次你吐槽的时候，都可以给话题添加短文字标记（hashtag), 形如&lt;code&gt;#新闻&lt;/code&gt;, 用过推特或微博的朋友应该不会陌生。短文字标记从&lt;code&gt;#&lt;/code&gt; 号开始，到空格或换行结束。有了短文字标记之后，你可以根据标记做相关查询，例如：&lt;a href=&quot;https://roastidio.us/tag/铁链女&quot;&gt;铁链女&lt;/a&gt;. 同样，本页也可以作为一个RSS推送被订阅，订阅者可以收到动态更新。&lt;/p&gt;
&lt;p&gt;短文字标记依赖于用户自行提交。所以我恳请用户们在提交文章的时候，尽可能加上有效的标记。&lt;/p&gt;
&lt;h2&gt;微信里的链接&lt;/h2&gt;
&lt;p&gt;微信说到底也是一个浏览器。但是，它完全隐藏URL，网站安全证书，也没有任何调试手段。虽然我们不是100%知道它在背地里干嘛，但我们明确知道，它至少在做很详细的用户行为记录，和针对内部公众号和外部网页很复杂的&lt;a href=&quot;https://blog.3qin.us/weixin_external_link.html&quot;&gt;选择性屏蔽&lt;/a&gt;. 由于微信的垄断和网络效应，我们离不开微信，但我恳请大家：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;不要用微信打开网页！！！&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;不要用微信打开网页！！！&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;不要用微信打开网页！！！&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;不管你用不用吐槽俱乐部，从你和他人的权益着想，在微信里看到任何链接，请第一时间用浏览器打开。分享链接的时候，不要用微信直接分享，请用浏览器，而且最好把链接的URL用文字方式粘贴到微信里。这样，你的下游可以剪贴URL直接回到浏览器里，而不再受微信的监控，数据分析，以及由此可能带来的屏蔽。诚然，如果是微信自己控制的公众号文章，微信可以把它认为不和谐的内容从源头删除，但至少吐槽俱乐部的存在，给用户们提供了一个保留文章的可能。这点微小的功能，或能给想挣脱&lt;a href=&quot;https://blog.3qin.us/apps_or_prisons.html&quot;&gt;互不联网&lt;/a&gt;束缚的朋友一点帮助。&lt;/p&gt;
&lt;p&gt;你愿不愿意牺牲一点点方便来获得一点点自由呢？&lt;/p&gt;</content:encoded>
</item>
<item>
<title>通过网络来剪贴</title>
<link>https://blog.3qin.us/copy_paste_through_web.html</link>
<enclosure type="image/jpeg" length="0" url="https://mail.3qin.us/~derek/blog_imgs/pics/derek.jpg"></enclosure>
<guid isPermaLink="false">b305UvAiUkyk9PN8UtSiYtK17_kFKznr114BrQ==</guid>
<pubDate>Sun, 01 Mar 2026 20:08:20 +0000</pubDate>
<description>我 前文 提到，我基本只用两个应用，一个是ssh到远程主机上的emacs, 另一个是本地的浏览器。另外，我目前常常用的一个数字设备是平板电脑。这种工作环境就带来一个问题，就是如何在这两个平台下剪贴文字，主要是从emacs向本地浏览器剪贴。你当然可以用android系统剪贴板，但有两个问题：</description>
<content:encoded>&lt;p&gt;我&lt;a href=&quot;https://blog.3qin.us/tablet_text_mode.html&quot;&gt;前文&lt;/a&gt;提到，我基本只用两个应用，一个是ssh到远程主机上的emacs, 另一个是本地的浏览器。另外，我目前常常用的一个数字设备是平板电脑。这种工作环境就带来一个问题，就是如何在这两个平台下剪贴文字，主要是从emacs向本地浏览器剪贴。你当然可以用android系统剪贴板，但有两个问题：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;在终端窗口选择大量文字，尤其是超过一屏幕的文字相当困难，而且常常换行，空白等无法精确传递。而换行和空白对于我常常需要剪贴的源代码片段来说相当重要。&lt;/li&gt;
&lt;li&gt;在一个平板电脑上，你没有精确的鼠标，只有手指。终端里文字通常还会相当小，我的笨手指无法有效地选择文字区间。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;当你足够痛苦的时候，就是需要创造力的时候了。&lt;/p&gt;
&lt;h2&gt;现有方案&lt;/h2&gt;
&lt;p&gt;当然，有这个痛苦的不止我一个。苹果刚刚推出的iPad pro主要推的创新点就是自带track pad，能解决精确选中文字的问题。iPad pro确实诱惑很大，可惜799美元的价格让我望而却步，这个价格可以买不错的笔记本电脑了。相比之下，我日常用的平板售价仅79美元，花十倍的价钱解决技术问题并不是我的风格。&lt;/p&gt;
&lt;p&gt;emacs平台下现有附加组件webpaste，可以让你用键盘选择要选择的文字区间，然后发到网上，以便于别人或你自己再用浏览器下载。但这个组件的目的是在聊天室快速传递大片文字同时不过分刷屏的，并不很适合我个人使用。第一它依赖第三方网上服务，第二到了网页上还要选中剪贴一次，虽然比终端窗口方便一点，但还是麻烦。&lt;/p&gt;
&lt;h2&gt;我的方案&lt;/h2&gt;
&lt;p&gt;我的灵感来自webpaste。我其实需要一个个性化的网上服务，能够暂时存储文字信息，而且能够快速选中剪贴。公网服务器我有，我日常使用emacs的主机就是。但我不想在上面安装任何服务端软件，毕竟日常维护和安全隐患都是需要考虑的。通盘考虑后我把问题分解成三个部分：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;一个命令行工具读入要剪贴的文字，归档存入特定目录，并生成html索引以便查询。&lt;/li&gt;
&lt;li&gt;一个网页脚本通过前述索引方便选中剪贴归档的文字片段。&lt;/li&gt;
&lt;li&gt;一个emacs脚本来把选中的文字传给命令行脚本，并绑定快捷键。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;命令行工具&lt;/h2&gt;
&lt;p&gt;对于处理文件并生成网页的命令行小工具来说，最适合的就是perl了。整个工具一共只需50行，包括注释。这里全文抄录如下。&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#! /usr/bin/perl -w
#
# organize text from stdin to files so they can be pasted in browser

use strict;
use warnings;
use v5.14;

use File::Slurp;
use Template;

# configs
# max items to keep. oldest is removed
our $MAX_ITEMS = 5;
our $SCRATCH_DIR = $ENV{&amp;#39;HOME&amp;#39;} . &amp;#39;/public_html/scratch&amp;#39;;

my $text = read_file(\*STDIN);
# let&amp;#39;s assume we do not call this script every second
my $name = time();
my $text_size = length($text);
write_file(&amp;quot;$SCRATCH_DIR/$name&amp;quot; . &amp;quot;.txt&amp;quot;, $text);

my %scratches;
opendir(my $dh, $SCRATCH_DIR) || die &amp;quot;cannnot open folder&amp;quot;;
while(my $file = readdir $dh) {
    next unless (-f &amp;quot;$SCRATCH_DIR/$file&amp;quot;);
    next unless ($file =~ /\.txt$/);
    my ($dev,$ino,$mode,$nlink,$uid,$gid, $rdev, $size, $atime, $mtime) = 
	stat(&amp;quot;$SCRATCH_DIR/$file&amp;quot;);
    $scratches{$file} = {
	mtime =&amp;gt; $mtime,
	size =&amp;gt; $size,
    };
}
closedir $dh;
my @sorted = sort {$scratches{$b}-&amp;gt;{&amp;#39;mtime&amp;#39;} &amp;lt;=&amp;gt; $scratches{$a}-&amp;gt;{&amp;#39;mtime&amp;#39;}} keys(%scratches);

for(my $i = $MAX_ITEMS; $i &amp;lt; scalar(@sorted); $i++) {
    my $file = $sorted[$i];
    unlink(&amp;quot;$SCRATCH_DIR/$file&amp;quot;);
    delete($scratches{$file});
}
@sorted = @sorted[0..$MAX_ITEMS - 1] if (scalar(@sorted) &amp;gt; $MAX_ITEMS);

my $tt = Template-&amp;gt;new({
    ABSOLUTE =&amp;gt; 1,
    });
$tt-&amp;gt;process(&amp;quot;$SCRATCH_DIR/index.tt2&amp;quot;,
	     { list =&amp;gt; \@sorted,
	       data =&amp;gt; \%scratches },
	     &amp;quot;$SCRATCH_DIR/index.html&amp;quot;) || die $tt-&amp;gt;error(), &amp;quot;\n&amp;quot;;

say &amp;quot;Copied $text_size byte to easypaste&amp;quot;&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;网页脚本&lt;/h2&gt;
&lt;p&gt;从网页上可以运行脚本，根据索引自动下载选中文字片段，并粘贴到系统剪贴板上。网页加载的时候自动下载选中最新的一份，用户可以多按两下按钮来选中之前的几份。这份javascript也不长，全文抄录如下：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;var last = null;

function fixAllItem() {
    document.querySelectorAll(&amp;quot;li.scratch-item&amp;quot;).forEach(item =&amp;gt; {
	var mtime = new Date(parseInt(item.getAttribute(&amp;quot;data-mtime&amp;quot;))*1000);
	item.querySelector(&amp;quot;span.scratch-mtime&amp;quot;).textContent = mtime.toLocaleString();
	item.querySelector(&amp;quot;button.scratch-button&amp;quot;).addEventListener(&amp;quot;click&amp;quot;, (e) =&amp;gt; {
	    loadContent(e.target.parentElement);
	});
    });
}

function loadContent(item) {
    var file = item.getAttribute(&amp;quot;data-name&amp;quot;);
    if (last == item) {
	// loaded
	document.querySelector(&amp;quot;#target-text&amp;quot;).select();
	document.execCommand(&amp;quot;copy&amp;quot;);
	item.querySelector(&amp;quot;button.scratch-button&amp;quot;).textContent = &amp;quot;Load&amp;quot;;
	last = null;
	return;
    }
    if (last != null) {
	last.querySelector(&amp;quot;button.scratch-button&amp;quot;).textContent = &amp;quot;Load&amp;quot;;
    }
    fetch(file)
	.then((res) =&amp;gt; {
	    return res.text();
	})
	.then((text) =&amp;gt; {
	    document.querySelector(&amp;quot;#target-text&amp;quot;).textContent = text;
	    last = item;
	    last.querySelector(&amp;quot;button.scratch-button&amp;quot;).textContent = &amp;quot;Copy&amp;quot;;
	});
}

document.addEventListener(&amp;quot;DOMContentLoaded&amp;quot;, function() {
    fixAllItem();
    loadContent(document.querySelector(&amp;quot;li.scratch-item&amp;quot;));
})&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;emacs脚本&lt;/h2&gt;
&lt;p&gt;最后，我需要从emacs内调用命令行工具，把文字传递进去，并绑定热键。我一共做了两个热键绑定，一个传送当前高亮区间，一个传送已经剪贴到emacs内部剪贴板内的文字。利用emacs现成函数，一小段lisp代码即可：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;;;; send current region to easypaste
(defun my-easypaste-region (&amp;amp;optional b e)
  (interactive &amp;quot;r&amp;quot;)
  (shell-command-on-region b e &amp;quot;easypaste&amp;quot;))
;;; send top of kill ring to easypaste
(defun my-easypaste-kill ()
  (interactive)
  (shell-command-on-region (current-kill 0) nil &amp;quot;easypaste&amp;quot;))
(global-set-key &amp;quot;\C-cpr&amp;quot; &amp;#39;my-easypaste-region)
(global-set-key &amp;quot;\C-cpk&amp;quot; &amp;#39;my-easypaste-kill)&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;总结&lt;/h2&gt;
&lt;p&gt;三个小功能模块，我一共用了三种不同的编程语言，如果加上html是四种。每段程序都很短。最终我用最经济的方法实现了我需要的功能。&lt;/p&gt;
&lt;p&gt;这个工具目前只负责从emacs向浏览器之间粘贴，但我只使用网络主机上的emacs，而浏览器在所有平台都可运行，我实际上可以方便从我的网络主机向所有平台搬运文本数据。反过来，即从本地平台向网络主机emacs剪贴现在我还只能依赖系统粘贴板，目前我还还并不觉得特别麻烦，留待以后再改善吧。&lt;/p&gt;</content:encoded>
</item>
<item>
<title>自由软件，开源软件还是免费软件</title>
<link>https://blog.3qin.us/free_software.html</link>
<enclosure type="image/jpeg" length="0" url="https://mail.3qin.us/~derek/blog_imgs/pics/derek.jpg"></enclosure>
<guid isPermaLink="false">3Wgb9jWIjN88I0_CB3Lu2kDyNw_P-PgQdH0hIg==</guid>
<pubDate>Sat, 21 Feb 2026 07:57:52 +0000</pubDate>
<description>我生活中用的绝大多数软件都是无需付费，源代码开放，采用保护用户和作者双方权益的版权许可的。最近在软件圈子里出了两件事情：一件是 Log4J重大安全漏洞 , 还有一件事情是 colors/faker作者自己注入Bug ，不少人对自由软件生态的健康产生了深深的疑虑。未来软件生态向何处去话题太大，今天我先要澄清一下名字，名不正则言不顺嘛。</description>
<content:encoded>&lt;p&gt;我生活中用的绝大多数软件都是无需付费，源代码开放，采用保护用户和作者双方权益的版权许可的。最近在软件圈子里出了两件事情：一件是&lt;a href=&quot;https://www.theregister.com/2021/12/13/log4j_rce_latest/&quot;&gt;Log4J重大安全漏洞&lt;/a&gt;, 还有一件事情是&lt;a href=&quot;https://www.bleepingcomputer.com/news/security/dev-corrupts-npm-libs-colors-and-faker-breaking-thousands-of-apps/&quot;&gt;colors/faker作者自己注入Bug&lt;/a&gt;，不少人对自由软件生态的健康产生了深深的疑虑。未来软件生态向何处去话题太大，今天我先要澄清一下名字，名不正则言不顺嘛。&lt;/p&gt;
&lt;p&gt;有人管这些软件叫免费软件，有人叫开源软件，还有人称它们为自由软件。那么那种称呼对呢？不讲究的话三者都对。但如果要细究，三者是不同的。它们其实是三种不同的发布和使用模式，之间的区别不在于授权许可文件规定了什么，而在于作者是谁，和使用者什么关系。&lt;/p&gt;
&lt;h2&gt;自由软件&lt;/h2&gt;
&lt;p&gt;我在这里把自由软件专指主要作者和控制者都是志愿者的软件。这也是三种软件的开端和根本。许多知名的自由软件诸如Linux，OpenSSL等都是自由软件。所谓自由软件，就是有人在不求任何回报的情况下，把自己写的软件开放给世界上所有人使用和修改。他们为什么没事自己写软件呢？一开始肯定是给自己用的，后来觉得别人可能也可以用，就开放给大家了。这种行为的本质是慈善，或者说是给全人类的礼物。既然是礼物，则以下成立：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;作者不对这软件负任何责任。他们自己觉得好用，别人是否这么认为对他们没有任何影响。&lt;/li&gt;
&lt;li&gt;假如使用者觉得有可改进的地方，可以自立山头去改，或者试图劝说作者去改。&lt;/li&gt;
&lt;li&gt;劝的方法必须是能落实到作者身上才有用。&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;最后一点我详细说一下。假如这个使用者对作者说：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;改成这样吧，对我会有用。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;这毫无意义，因为作者对使用者不负任何责任。所以只能这么劝：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;改成这样吧，不仅对我会有用，对其他人，包括你自己也会有用。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;这才可能给作者作改进的动力。&lt;/p&gt;
&lt;p&gt;所以说，在自由软件范畴里，作者对使用者的关系是施主对乞丐的关系，使用者可能可以通过一些方法策略来对作者的发展路线有所影响，但没有任何保证。&lt;/p&gt;
&lt;h2&gt;开源软件&lt;/h2&gt;
&lt;p&gt;所谓开源软件是九十年代末产生的新事物，其作者主要是一个大公司的雇员，软件受这个公司控制。这其实也是一种产品，这软件通常也不是公司针对自己的需求开发的，但它或者不容易商业化，例如Firefox，或者可以商业化，但不商业化对公司利益更大，例如Java，所以最终公司选择开放给大家使用。开放对公司有间接的利益，例如名声，推动生态圈向这个公司希望的方向发展等等。&lt;/p&gt;
&lt;p&gt;使用者呢，也不是通常意义上的客户，最多叫用户。假如使用者觉得需要在某方面改进，出来向这公司进言，绝大多数情况下也是没用的。仅在以下情形有用：很大一部分用户有一致的需求，一起发出同样的呼声。公司权衡利弊，觉得为名声，或从生态圈建设起见，改比不改更有利益，这才会去改。用户的这种行为从另一个角度看是一种起哄行为，反正要闹出动静出来才会有用。&lt;/p&gt;
&lt;p&gt;所以说，在开源软件的范畴里，作者和使用者的关系是明星和粉丝的关系。明星能对粉丝造成大的影响，反之，粉丝对明星影响从个体来说微乎其微，但拧成一股绳的粉丝还是颇有影响力的。&lt;/p&gt;
&lt;h2&gt;免费软件&lt;/h2&gt;
&lt;p&gt;免费软件早就有，但开源的免费软件是二十一世纪开始后才有的。其作者通常是一个起步公司，产品线比较单一。其产品的最低阶彻底开放给大家使用。公司虽然也求名，或也想建设生态圈，但更直接的目的是给用户一点甜头，争取使一部分用户被捆绑，最终成为付费客户。付费未必是升级为高阶版软件，收费客户支持也是一个常见的产生效益的方法。免费软件著名的例子包括MongoDB，ElasticSearch 等等。&lt;/p&gt;
&lt;p&gt;免费软件的用户群通常不会太大。公司通常也能积极听取用户的反馈，毕竟改进产品对公司发展至关重要，还可能转化免费用户为付费客户，直接提升效益。由于公司的低姿态，很多免费用户也常常以客户自居，对公司指手画脚。毕竟客户是上帝嘛。只要不是太过分，公司也就忍了，就算不挣钱，也至少有点公关的作用。&lt;/p&gt;
&lt;p&gt;所以说，在免费软件的范畴里，作者和使用者的关系是乙方和甲方的关系，甲方更强势，乙方忍气吞声，只为求财。&lt;/p&gt;
&lt;h2&gt;总结&lt;/h2&gt;
&lt;p&gt;虽说三种事物产生有先后，但到现在，三者之间已经有紧密连接：不仅相辅相成，甚至相互转化。自由软件的作者如果创业，自由软件就成了免费软件。创业公司如果被并购，免费软件可能就转化为开源软件。到后来公司觉得无利可图，放弃产品，虽然这款开源软件大概率是黄了，但也可能被社区里的志愿者捡起来，就又变成了自由软件。&lt;/p&gt;
&lt;p&gt;从自由软件到开源软件到免费软件，作者的地位越来越低，但使用者的地位越来越高。从另一个角度，作者的收获越来越大，使用者的使用代价也就越来越高。所以说吃亏就是占便宜，世上没有免费的午餐。&lt;/p&gt;
&lt;p&gt;软件业界的种种纷争其实都是双方认知不对等造成的。比如，假如作者觉得我做的是自由软件，是慈善，但使用者自居甲方，提出没完没了的需求，或者使用者觉得我用的是自由软件，用得心安理得，但作者总想从使用者身上捞好处，求捐赠。认知不对等就会产生矛盾，是矛盾总有爆发的一天，到矛盾爆发的时候，谁还记得当年美好的相遇呢？&lt;/p&gt;
&lt;p&gt;人世间的种种不平莫不来源于此。&lt;/p&gt;</content:encoded>
</item>
<item>
<title>Perl中的缺省变量$_</title>
<link>https://blog.3qin.us/default_variable.html</link>
<enclosure type="image/jpeg" length="0" url="https://mail.3qin.us/~derek/blog_imgs/pics/derek.jpg"></enclosure>
<guid isPermaLink="false">6UYNjVjTecWNXjjq6rUUCHlYjF08vbREv_q0GQ==</guid>
<pubDate>Wed, 18 Feb 2026 07:14:27 +0000</pubDate>
<description>用过perl的人对缺省变量 $_ 都一定相当熟悉．由于有了缺省变量，许多写法可以相当简化．例如：</description>
<content:encoded>&lt;p&gt;用过perl的人对缺省变量 $_ 都一定相当熟悉．由于有了缺省变量，许多写法可以相当简化．例如：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;while (&amp;lt;&amp;gt;) {　print; }
tr/a-z/A-Z/
chomp&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;但使用不当，你可能也会碰到相当费解的 bug. 下面我们仔细探究一下使用 $_ 的内在细节，希望能避免 bug, 更高效地写出正确的程序．&lt;/p&gt;
&lt;h2&gt;案例&lt;/h2&gt;
&lt;p&gt;我前一段写了个小程序，大致如下：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;foreach (@filenames) {
	my $fh = open($_);
	while (&amp;lt;$fh&amp;gt;) {
	    s/good/bad/g;
	}
	close($h);
	say &amp;quot;$_ fixed!&amp;quot;;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;有人看出问题了吗？我估计 perl 要六级以上才能看出问题．提示：打印出来的东西完全不是你一开始想的，更严重的是 &lt;span&gt;@filenames&lt;/span&gt; 内的数据被破坏．究竟是怎么回事？&lt;/p&gt;
&lt;h2&gt;variable scopes&lt;/h2&gt;
&lt;p&gt;Perl 提供丰富的 variable scope 规则：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;global variable&lt;/li&gt;
&lt;li&gt;dynamically-scoped variable&lt;/li&gt;
&lt;li&gt;lexically-scoped variable&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;搞懂这些scoping rule, 不仅对 perl 程序员有用，对所有程序员都有用．&lt;/p&gt;
&lt;h3&gt;global scoped&lt;/h3&gt;
&lt;p&gt;其实就是没有scope, 即全局变量．这最简单，可以理解成有一个全局的字典，通过名字指向静态分配的内存地址．在程序中的任意地方你都可以通过同一个名字读写同一块内存．perl 中的 our 变量就是全局变量.&lt;/p&gt;
&lt;h3&gt;dynamically-scoped&lt;/h3&gt;
&lt;p&gt;global scoped 简单，但导致程序各部分相互干扰很大．于是发明了局部变量，和 scope 关联．dynamically-scoped 的方法是维持全局字典，但在进入一个 scope 的时候，把全局字典中一部分另行保存，改成这个 scope 自定义的新值．离开这个 scope 的时候再恢复回去，保证对外界没有干扰．在 perl 里, local 变量就是 dynamically-scoped 局部变量．&lt;/p&gt;
&lt;h3&gt;lexically-scoped&lt;/h3&gt;
&lt;p&gt;还有另外一种方法．就是每个 scope 自己定义自己的一个小字典．先查自己小字典，查不到了，再查全局大字典．这也实现了局部重定义变量．在 perl 里, my 变量就是 lexically-scoped 局部变量．&lt;/p&gt;
&lt;h3&gt;dynamical vs lexical&lt;/h3&gt;
&lt;p&gt;假如你只有一个全局 scope 加一个局部 scope, 那这两者没本质区别．但如果再多，就有区别了．lexically-scoped 永远只作用在本 scope 内，和你程序如何执行没有关系．但 dynamically-scoped 和程序运行路径相关，会影响之后你程序运行遇见的所有新的 scope. 例如:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;our $a = 1;
our $b = 2;
sub inner_print {
    say &amp;quot;a=$a, b=$b&amp;quot;;
}

say &amp;quot;a=$a, b=$b&amp;quot;;   # a=1, b=2
OUTER: {
    my $a = 3;
	local $b = 4;
	say &amp;quot;a=$a, b=$b&amp;quot;;   # a=3, b=4
	inner_print();      # a=1, b=4
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;在之上的例子里，由于 $b 在 OUTER scope 是 dynamically-scoped, 而 $a 是 lexically-scoped, 导致在 inner_print 里一个用全局值，一个用 OUTER 里的值．&lt;/p&gt;
&lt;p&gt;通常而言，静态编译的程序更适合使用 lexically-scoped, 而动态解释的程序更适合使用 dynamically-scoped. 例如，在 C 语言里并无 dynamically-scoped 的方法．但 perl 及其他高级语言给了你更多的能力，相应的，也就有更多的可能性．某些功能用 dynamically-scoped 变量更方便，但对于大多数情况, lexically-scoped 更不容易出错，也更容易被编译器优化．所以在你不清楚该用什么的时候，请先考虑 lexically-scoped.&lt;/p&gt;
&lt;h2&gt;$_ 是什么&lt;/h2&gt;
&lt;p&gt;我们再回到一开始，理解一下 $_ 究竟是什么．它的使用分为大致两个方面：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;提供者．包括 iterator (例如 foreach) 和 stream 输入 (例如 while(&amp;lt;&amp;gt;) )．perl 的术语叫：topicalizer&lt;/li&gt;
&lt;li&gt;缺省使用者．包括 regular expression matching, 一些系统自带函数等．&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;由于以上因素，可以推理出：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;$_ 是全局变量&lt;/li&gt;
&lt;li&gt;$_ 无法做 lexically-scoped 局部变量&lt;/li&gt;
&lt;li&gt;$_ 可以做 dynamically-scoped 局部变量&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;很简单，假如 $_ 做了 lexically-scoped 局部变量, 它就无法自然传递到下层函数，那它的方便性就没了一大半，也就没意义了．让我们再考虑一下在 while(&amp;lt;&amp;gt;) 和 foreach() 两种用法下，究竟发生了什么．&lt;/p&gt;
&lt;h3&gt;while (&amp;lt;&amp;gt;) 里的 $_&lt;/h3&gt;
&lt;p&gt;当我们写：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;while(&amp;lt;$fh&amp;gt;) {
	}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;实际上 perl 会给我们自动扩写成：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;while(defined($_ = &amp;lt;$fh&amp;gt;) {
	}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这里，全局变量 $_ 会被赋值，会影响到外面．在我们最初的例子里，内循环的 while 改写了它. 同时由于下面 foreach 的性质，改写了外循环遍历的数组 &lt;span&gt;@filenames&lt;/span&gt;．由于 while 循环的结束条件，最终它和 &lt;span&gt;@filenames&lt;/span&gt; 全都变成了 undefined.&lt;/p&gt;
&lt;h3&gt;foreach 里的 $_&lt;/h3&gt;
&lt;p&gt;当我们写：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;foreach (@filenames) {
	}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;实际上 perl 会给我们自动扩写成：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
	    local $_;
		my $i;
		for($i=0; $i&amp;lt;scalar(@filenames); \$_=\$filenames[$i], $i++) {
		}
	}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这里和上面 while 有两个显著区别：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;$_ 并非拷贝了数组里的数据，而是一个 alias, 指向数组里的真实数据&lt;/li&gt;
&lt;li&gt;perl 自动生成一个外层，并将 $_ 做成一个 dynamically-scoped 的局部变量&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;为什么 $_ 必须是一个 alias呢？第一避免了内存拷贝，第二保证把它当作 l-value 可以直接修改原数组里的值．下面代码才成为可能.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;foreach (@filenames) {
		s/good/bad/g;
	}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;上面这段代码会修改 &lt;span&gt;@filenames&lt;/span&gt; 里的内容，这是预期的结果．这和 while (&amp;lt;&amp;gt;) 不一样，在 while (&amp;lt;&amp;gt;) 里数据拷贝是天然且合理的，输入流并无修改的需要．&lt;/p&gt;
&lt;p&gt;由于 $_ 必须是一个 alias, 所以 perl 必须再做一个外部 scope 把它做成局部变量．假如不这样做的话，foreach 循环结束之后，它将是一个无效的 alias，对它的任何操作都会导致内存越界．这和 while (&amp;lt;&amp;gt;) 结束之后残留一个无效数据不一样：无效的指针比无效的数据危险性大的多．&lt;/p&gt;
&lt;h2&gt;怎么避免&lt;/h2&gt;
&lt;p&gt;从上面的分析来说，foreach 不污染环境，但可能受污染，while (&amp;lt;&amp;gt;) 污染环境但不容易受污染．问题出在 while (&amp;lt;&amp;gt;) 上．那为什么 while (&amp;lt;&amp;gt;) 不也使用自动外层和 dynamically-scoped 呢？我想这主要是历史原因，而且从上面的分析来说, while (&amp;lt;&amp;gt;) 的污染是可预测的．对于我们程序员来说，为避免这个坑，你要记住以下两条就够了．&lt;/p&gt;
&lt;h3&gt;不做内循环&lt;/h3&gt;
&lt;p&gt;while (&amp;lt;&amp;gt;) 只能做最外侧循环．如果要做内循环，可以改成 lexically-scoped, 不用 $_:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;while (defined(my $line=&amp;lt;$h&amp;gt;)) {
	}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这样做的缺点是没有缺省变量了，不够方便．或者也可以用内部 dynamically-scoped $_:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;while (1) {
	    local $_ = &amp;lt;$fh&amp;gt;;
		last unless (defined($_));
	}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这样做的缺点是感觉罗嗦一点．&lt;/p&gt;
&lt;h3&gt;保护外层&lt;/h3&gt;
&lt;p&gt;除非你的 while (&amp;lt;&amp;gt;) 已经在程序顶层，即不在任何函数内部，尽量在 while (&amp;lt;&amp;gt;) 之外把 $_ 定义成 dynamically-scoped 局部变量来保护你函数的上层调用：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sub my_func {
	    local $_;
		while(&amp;lt;$fh&amp;gt;) {
		}
	}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;如果你的程序的 while (&amp;lt;&amp;gt;) 在最顶层最外侧循环，则无需做任何改变．这其实也就是 perl 原来简化写法的初衷．&lt;/p&gt;
&lt;h2&gt;总结&lt;/h2&gt;
&lt;p&gt;perl 让你写出精简方便的代码，但这后面的原理并不简单．理解 dynamically-scoped 和 lexically-scoped 的区别不仅让你能更深的掌握perl, 对其他高级语言的学习也很有帮助．&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;There is more than one way to do it. — Larry Wall&lt;/p&gt;
&lt;/blockquote&gt;</content:encoded>
</item>
<item>
<title>创作者经济里的经济学</title>
<link>https://blog.3qin.us/ugc_economics.html</link>
<enclosure type="image/jpeg" length="0" url="https://mail.3qin.us/~derek/blog_imgs/pics/total-surplus.png"></enclosure>
<guid isPermaLink="false">nLCfouBCPD8bsJ3YfXA31P9TJIzfw9nxRBm59Q==</guid>
<pubDate>Thu, 12 Feb 2026 23:23:00 +0000</pubDate>
<description>近两年有个词挺火：创作者经济 (creator economy) 。它指的是独立的内容创作者，在各大社交媒体平台上有偿传播自己创作的内容，从而获得经济收入。社交网络上绝大多数的内容都是用户辛苦创作而来，其中不少都颇有价值。创作者创作需要花时间和精力，所以他们理应得到一定的经济补偿，不是吗？今天，我们就从经济学角度来分析这个现象，看我们能找到什么本质。</description>
<content:encoded>&lt;p&gt;近两年有个词挺火：创作者经济 (creator economy) 。它指的是独立的内容创作者，在各大社交媒体平台上有偿传播自己创作的内容，从而获得经济收入。社交网络上绝大多数的内容都是用户辛苦创作而来，其中不少都颇有价值。创作者创作需要花时间和精力，所以他们理应得到一定的经济补偿，不是吗？今天，我们就从经济学角度来分析这个现象，看我们能找到什么本质。&lt;/p&gt;
&lt;h2&gt;经济学原理回顾&lt;/h2&gt;
&lt;p&gt;有些朋友没有学过微观经济学，有些朋友虽然学过，但可能也忘的差不多了。我先回顾一下几个基本概念，自由市场，供求关系，和市场价格。在一个自由市场中，有很多个供应商，有更多个消费者。一个商品的价格由供求关系决定。供应曲线和需求曲线如下图。一般作图X轴是数量，Y轴是价格。所以，需求曲线是一个单调下降曲线，因为每个消费者自己对这件商品的心理价值定位不同，价格越低则愿意购买的消费者越多，所以商品的需求量也越多。同理，供给曲线是一个单调上升曲线，愿意供货的供货商随价格上升而增加，所以，供应量也就越多。两条曲线的交点就是市场价格。&lt;/p&gt;
&lt;figure&gt;
&lt;img src=&quot;https://mail.3qin.us/~derek/blog_imgs/pics/total-surplus.png&quot; alt=&quot;Total Surplus&quot; title=&quot;&quot;/&gt;
&lt;figcaption&gt;Total Surplus&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;以市场价格作一条和X轴平行的直线，这条线和供给曲线之间的面积就是供货商们总体获得的收益 (Producer Surplus). 反过来，这条线和需求曲线之间的面积就是消费者总体获得的收益 (Consumer Surplus) . PS和CS的总和就是这个市场活动的总体价值，我们常常听说某某厂商“创造价值”，其实就是开创了市场，带给供求双方以收益。&lt;/p&gt;
&lt;p&gt;独立的内容创作者们当然创造了价值。但传统上，社交媒体上内容不收费，所以他们获得不了他们应得的生产者收益 (PS) 。在创造者经济的概念里，就是要改变这个现状，给创作者以合理的回报。这件事有道理吧？&lt;/p&gt;
&lt;p&gt;错，创作者经济是一个骗局，&lt;strong&gt;独立的内容创作者不应，也无法获得经济回报。&lt;/strong&gt; 这不是什么道德或法律的约束，而是经济学决定的。&lt;/p&gt;
&lt;h2&gt;价值 =/= 价格&lt;/h2&gt;
&lt;p&gt;看到这里的朋友可能不理解了：是的，价值不等于价格，但创作者并没有要求拿到他们创造的价值的全部啊，拿一半，留给消费者一半，不是很合理吗？比如说这篇文章吧，假如对于你带来的知识性娱乐性价值为一块钱，那么你给我五毛不是很合理吗？&lt;/p&gt;
&lt;p&gt;回到上面的供求曲线。可能大家有个误解，就是供给曲线的Y值是什么含义。是的，它是成本，但不是总体成本，而是 &lt;strong&gt;边际成本&lt;/strong&gt; 。举个例子就好理解了。假如你是一个汽车厂，造一辆车的成本是十万。今天市场价格是十万零一块，你卖还是不卖呢？你当然卖。供货商有很多，你的行为对市场价格影响很小。挣一块钱总比一块钱不挣强吧。就算你已经花了一千万研发这个型号的车，这个研发成本花都已经花了 (Sunk cost)，和你现在的市场行为已经无关了。所以说：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;自由市场上价格等于活的最惨的供应商的边际成本。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;好，回到我们的话题上。数字媒体上内容创作者里活的最惨的人，他的边际成本是多少呢？&lt;/p&gt;
&lt;p&gt;零。&lt;/p&gt;
&lt;p&gt;事实上所有数字媒体内容创作者的边际成本都是零。就算我花了两个小时写这篇文章，时间成本五百块，也不能摊入边际成本。既然我愿意写，就不应，也不能收费。上图里的供给曲线在数字媒体范畴里，其实紧贴X轴。所有数字媒体上内容消费者都应该心安理得地享受100%的消费者收益 (CS), 千万不要心有愧疚。这不是你想占便宜，而是经济学决定了的。&lt;/p&gt;
&lt;h2&gt;谁把钱挣了？&lt;/h2&gt;
&lt;p&gt;看到这里，你可能不理解了。不对呀，谁谁谁不是搞直播，vlog什么的挣了不少钱吗？&lt;/p&gt;
&lt;p&gt;没错。这里的区别在于，他们所在的不是自由市场，而是垄断市场。他们面对的消费者，就只想消费他们的内容，对别的内容完全不感冒。换言之，王思聪搞直播有粉丝团，你有吗？&lt;/p&gt;
&lt;p&gt;不管什么时代，内容创作者里的绝大多数 (99%+) 都注定没有粉丝团的。这不是因为他们的内容不够好，而是粉丝这个事物的供给就是这么多，远远不够分的，何况粉丝团有很强的&lt;a href=&quot;https://blog.3qin.us/middle_ground.html&quot;&gt;正反馈倾向&lt;/a&gt;, 所以创作者经济里最后一定是有的人挣大把钱，绝大多数人挣不到钱。从风险分析和潜在收益来说，想靠这个挣钱，还不如去赌，毕竟赌场的抽头比社交媒体平台的抽头小多了。&lt;/p&gt;
&lt;p&gt;那谁低风险地挣到钱了呢？只有平台。收费内容它们抽 15% (Google Play), 20% (Twitter Super Follow), 30% (Apple Store), 免费内容它们还能靠流量剥削用户的隐私，不管怎么样都能占到便宜。所以说，它们才会想尽办法宣扬挣到钱的极少数创作者的成功，蛊惑其他的内容创作者去它们的平台发布内容。天真的朋友，你看清楚了吗？&lt;/p&gt;
&lt;h2&gt;还要不要创作&lt;/h2&gt;
&lt;p&gt;看到这里的朋友可能会想，都是骗子，得了，我还是啥都不创作了，静静地享受我的消费者收益 (CS) 吧。有大局观的朋友可能会更悲观地想，既然经济规律不能给创作者以合理的回报，长此以往，就没有创作者了，开放数字媒体完了。&lt;/p&gt;
&lt;p&gt;要知道这世界上除了钱，还有别的东西。我今天先不多讲太高级的 &lt;a href=&quot;https://en.wikipedia.org/wiki/Maslow%27s_hierarchy_of_needs&quot;&gt;Maslow 金字塔&lt;/a&gt; 什么的，就讲点民间哲理：&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;嘛钱不钱的，乐呵乐呵不完了。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;你创作的目的是什么？每个人的目的不同，但钱只能是手段之一，它不会是你的目的。在开放数字媒体上创作虽然无法给创作者以经济利益，但给了创作者更大的自由和更广阔的空间。我们确确实实创造了价值，虽然这价值不是那么好量化，也捕捉不到。而且，数字媒体是史上第一个，也是目前唯一一个完全避免了 &lt;a href=&quot;https://www.sustainable-environment.org.uk/Earth/Commons.php&quot;&gt;公共草原的悲剧&lt;/a&gt; 的社会经济领域，即使有再多的人来索取，池子也不会变小，但你放进去任何一点点内容，就永远在池子里了。&lt;/p&gt;
&lt;p&gt;物质生活里我们做不到的事情，精神生活里我们做的到。这就是：&lt;/p&gt;
&lt;h2&gt;共产主义&lt;/h2&gt;</content:encoded>
</item>
<item>
<title>三个命令行工具</title>
<link>https://blog.3qin.us/command_line_tools.html</link>
<enclosure type="image/jpeg" length="0" url="https://mail.3qin.us/~derek/blog_imgs/pics/derek.jpg"></enclosure>
<guid isPermaLink="false">j49Xn_59KdSJomS0bNIr83jIEOiwd1KHC9F76Q==</guid>
<pubDate>Thu, 08 Jan 2026 02:18:29 +0000</pubDate>
<description>UNIX命令行的美丽之处是虽然每个工具只做一件事，但把它们组合起来，你可以完成所有复杂的工作。下面介绍的三个工具可能不太出名，做的事情其实也有点复杂，无法用简单几句话说清，而且感觉和UNIX的哲学也有点背离，但对于程序员和系统管理员的日常工作确实非常有用。我这里一并介绍，希望能给大家以启发。</description>
<content:encoded>&lt;p&gt;UNIX命令行的美丽之处是虽然每个工具只做一件事，但把它们组合起来，你可以完成所有复杂的工作。下面介绍的三个工具可能不太出名，做的事情其实也有点复杂，无法用简单几句话说清，而且感觉和UNIX的哲学也有点背离，但对于程序员和系统管理员的日常工作确实非常有用。我这里一并介绍，希望能给大家以启发。&lt;/p&gt;&lt;h2&gt;stow&lt;/h2&gt;&lt;p&gt;如果你像我一样，手动编译安装不少软件，肯定会和我有一样的烦恼。这就是安装容易，卸载难。在一个UNIX环境中，所有执行文件，所有库，等等都是混在一起放的，你很难分清楚什么文件是什么源包安装的，所以并没有统一的，干净的卸载流程。有时候你甚至觉得可能像 OS X 一样，所有安装文件完全分开才简单．但一起放有一起放的好处：路径设置简单．如果路径过于复杂，那先后顺序也很有影响，你也很难发现各个软件包之间的有没有冲突．stow 这个工具解决的就是多软件包安装卸载的问题，你为什么不可以同时得到分开放和一起放的好处呢？通过管理 symlink, stow 把多个目录下的文件形式上合并在一起，并可以随时拆除更换．下面举例：&lt;/p&gt;&lt;pre&gt;&lt;code&gt;packageA
   |-&amp;gt; bin		
      |-&amp;gt; commandA
   |-&amp;gt; lib
      |-&amp;gt; libA

packageB
   |-&amp;gt; bin		
      |-&amp;gt; commandB
   |-&amp;gt; lib
      |-&amp;gt; libB&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;合并之后成为：&lt;/p&gt;&lt;pre&gt;&lt;code&gt;local
   |-&amp;gt; bin
      |-&amp;gt; commandA -&amp;gt; ../stow/packageA/bin/commandA
	  |-&amp;gt; commandB -&amp;gt; ../stow/packageB/bin/commandB
   |-&amp;gt; lib
      |-&amp;gt; libA -&amp;gt; ../stow/packageA/lib/libA
	  |-&amp;gt; libB -&amp;gt; ../stow/packageB/lib/libB&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;正如传统 UNIX 的扁平目录组织形式一样．而且还有其他：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;扁平目录里只有 symlink, 并不占什么磁盘空间&lt;/li&gt;
&lt;li&gt;提供工具分 package 拆除/更换/检验 symlink&lt;/li&gt;
&lt;li&gt;自动检查冲突&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;事实上，这个工具不仅可以用于管理软件安装，任何你又想分目录管理又想扁平管理的地方都可以应用它．我已经开始用它管理文档，图片，音乐等等．现代的文件系统在一个目录里放几万个文件毫无问题，所以尽情把它们 stow 到一起吧，你会获得短路径，易搜索，好遍历的好处，同时不放弃分项目管理的干净整洁．&lt;/p&gt;&lt;h2&gt;ack&lt;/h2&gt;&lt;p&gt;我想人人都用过 grep. grep 来自 UNIX 的哲学，只做一件事情，就是字符串匹配．但任何尝试过在一个不是很简单的目录结构下 grep 过的人都和我一样受过伤害．你先来：&lt;/p&gt;&lt;pre&gt;&lt;code&gt;find . | xargs grep derek&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;发现没有跳过目录．然后你再来：&lt;/p&gt;&lt;pre&gt;&lt;code&gt;find . -type f | xargs grep derek&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;然后你意识到有些路径名包含空格，所以你再来：&lt;/p&gt;&lt;pre&gt;&lt;code&gt;find . -print0 -type f | xargs -0 grep derek&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;然后你找到一大堆二进制文件，只好重来：&lt;/p&gt;&lt;pre&gt;&lt;code&gt;find . -print0 -type f -name &amp;quot;*.c&amp;quot; | xargs -0 grep derek&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;然后你意识到还有 .h 文件，.cpp 文件，… 还有假如某些脚本并无固定后缀呢？快崩溃了吧？&lt;/p&gt;&lt;p&gt;当然一些老手会说，你可以 git grep. 但如果你 grep 的目录没有用 git 管理呢？但如果你想一起 grep 多个 git repo 呢？&lt;/p&gt;&lt;p&gt;ack 是 grep 在 DWIM (Do What I Mean) 哲学下的重新实现. 你只需要：&lt;/p&gt;&lt;pre&gt;&lt;code&gt;ack derek
ack --perl derek
ack --noperl derek&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;你猜猜看上述命令都干了啥？简单总结一下 ack 的好处：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;自动跳过你其实不想 grep 的文件和目录&lt;/li&gt;
&lt;li&gt;普通人可以记住理解的命令行&lt;/li&gt;
&lt;li&gt;高亮显示匹配结果&lt;/li&gt;
&lt;li&gt;集成到 emacs 和其他编辑器之内&lt;/li&gt;
&lt;/ul&gt;&lt;h2&gt;parallel&lt;/h2&gt;&lt;p&gt;这个年代每个人的电脑都是多核的．但可惜的是很多任务其实只能利用一个CPU. 如果你一个一个地去做，即使写成脚本，也是大大浪费时间．例如你有一堆图片，需要转换成另一个分辨率，有或者你有一堆 regression test 等着去做，你当然想并行地去做不是？parallel 是一个并行多任务 scheduler, 它有以下好处：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;自动识别你有多少CPU, 来达到最好的效率&lt;/li&gt;
&lt;li&gt;自动缓存打印信息，这样在并行运行的时候屏幕打印仍貌似串行运行的一样可读&lt;/li&gt;
&lt;li&gt;当某个任务异常退出的时候，不再提交新的任务但让已提交的任务正常运行到结束&lt;/li&gt;
&lt;li&gt;清晰合理的命令行语法&lt;/li&gt;
&lt;li&gt;还有很多很多高级功能&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;下面我给一个简单范例是我常常使用的：&lt;/p&gt;&lt;pre&gt;&lt;code&gt;ls -d * | parallel -j+0 make -C {}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;它的含义是：对于当前目录下所有子目录，每一个都进入运行 make, 并发数受限于 CPU 的个数．怎么样？让电脑满负荷运行吧，我自己要回家睡觉了．&lt;/p&gt;&lt;h2&gt;总结&lt;/h2&gt;&lt;p&gt;以上三个命令行工具其实都有十年以上的历史了，算的上久经考验．它们的目的并非直截了当，但都是程序员为了解决自己的痛点，为自己和同行自发设计的工具，从一个非常简单的开端逐渐演变到一个相对复杂和完备的现状，没有任何商业背景．&lt;/p&gt;&lt;p&gt;最后，它们都是用 perl 写的哦．&lt;/p&gt;&lt;blockquote&gt;
&lt;p&gt;Make the easy things easy and the hard things possible.
– Larry Wall&lt;/p&gt;
&lt;/blockquote&gt;</content:encoded>
</item>
<item>
<title>文本通讯录</title>
<link>https://blog.3qin.us/contacts_in_org.html</link>
<enclosure type="image/jpeg" length="0" url="https://mail.3qin.us/~derek/blog_imgs/pics/derek.jpg"></enclosure>
<guid isPermaLink="false">vSy9DGcdac6vOTSEyFlqXMOtQJ21iP7aLOZ2og==</guid>
<pubDate>Mon, 05 Jan 2026 07:48:07 +0000</pubDate>
<description>手机上最重要的数据就是通讯录了．当然，现在人们手中不止一个数字设备，在我 前文 中说到，我日常使用四个数字设备，台式电脑，笔记本电脑，手机，平板．当然，很多人还不止一部手机．所以，通讯录的维护，备份，同步就成了一个问题。你可能会问，难道不是有云端备份同步吗？我今天就要讲一下云端通讯录同步的使用问题，以及我为什么抛弃了云端方案，回归简...</description>
<content:encoded>&lt;p&gt;手机上最重要的数据就是通讯录了．当然，现在人们手中不止一个数字设备，在我&lt;a href=&quot;https://blog.3qin.us/tablet_text_mode.html&quot;&gt;前文&lt;/a&gt;中说到，我日常使用四个数字设备，台式电脑，笔记本电脑，手机，平板．当然，很多人还不止一部手机．所以，通讯录的维护，备份，同步就成了一个问题。你可能会问，难道不是有云端备份同步吗？我今天就要讲一下云端通讯录同步的使用问题，以及我为什么抛弃了云端方案，回归简单文本。&lt;/p&gt;&lt;h2&gt;现有方案&lt;/h2&gt;&lt;p&gt;其实，我早在没有使用智能手机的年代就开始使用云端服务来管理通讯录了，到今天已经超过15年。但是这个过程中我碰到了许多问题。下面我一一介绍一下现在存在的解决方案。&lt;/p&gt;&lt;h3&gt;LDAP&lt;/h3&gt;&lt;p&gt;LDAP是上世纪90年代的最新科技，其实并不是一个同步手段。你的通讯录只存在于云端，不存在于本地，由系统管理员统一维护。当然，Exchange也类似。这个方法其实仅适用于组织机构而不适合个人使用。一旦断网，就什么都没有了。&lt;/p&gt;&lt;h3&gt;CardDAV&lt;/h3&gt;&lt;p&gt;CardDAV是一个开放标准，有很多自由软件的服务端及客户端。利用这些，你可以在任意客户端保持通讯录同步。但这也有问题。第一你需要一个服务。当然可以使用一些开放的服务，但他们总有一些可靠性问题，还有隐私问题。当然，你也可以自己架设服务，毕竟现在VPS这么便宜。但这有一个技术门槛，而且感觉为了这么点事不值当。第二，你需要在各种平台，各种软件里安装插件，记得更改密码等等，这些都是维护成本。&lt;/p&gt;&lt;h3&gt;手机自带服务&lt;/h3&gt;&lt;p&gt;OPPO手机有OPPO云，华为手机有华为云，都可以轻松一点在多机同步通讯录。但这些都是私有服务，使用非开放标准。OPPO云华为手机用不了，华为云OPPO手机用不了，而且PC端都用不了，更不用提自由软件平台了。&lt;/p&gt;&lt;h3&gt;Apple&lt;/h3&gt;&lt;p&gt;如果你生活在Apple世界里，当然可以用Apple服务。可惜我不是，而且我不能想像被一个厂商永远束缚是什么样的生活。&lt;/p&gt;&lt;h3&gt;Google&lt;/h3&gt;&lt;p&gt;当然，也可以使用第三方服务例如Google，协议开放，支持所有客户端。但可惜的是，中国国内用不了。而且，你真的那么愿意信任Google吗？&lt;/p&gt;&lt;h3&gt;小众服务&lt;/h3&gt;&lt;p&gt;也有第三方小众服务，而且在雷达屏幕之下，尚未被中国长城屏蔽。国内原生的，使用开放标准协议的小众服务我至今没有找到过。另外，可靠性和隐私都是问题。&lt;/p&gt;&lt;h2&gt;我的处境&lt;/h2&gt;&lt;p&gt;之前，由于历史原因，我同时使用三到四种服务。可惜的是，这多种服务之间是互相隔离的，我在手机上看到的是所有服务的并集。如果一不小心几个服务之间的通讯录条目有重叠，结果就很有意思了。我在手机上输入新的通讯录条目也要谨慎小心，要输到我真的想输的子集里。否则同步之后，在不同服务中迁移条目相当困难。还有一次我在异国他乡，一段时间没有数据连接，突然间一部分通讯录条目蒸发不见，好几天都没有发现。&lt;/p&gt;&lt;p&gt;我终于意识到唯一可靠的就是本地存的通讯录。我需要的不是同步，而是能够简单把整个通讯录拿出来，整理，再放回去。毕竟，通讯录数据量很小。我经过一番整理后的通讯录不到一千个条目，其中大多数人我都不知道是谁了。总体通讯录vCard文件输出只有100KB，在这个年代这个数据量可以忽略不计了，我就是每天拷贝一次，消耗的时间和数据流量仍在噪声里。增量同步完全没有经济意义。&lt;/p&gt;&lt;p&gt;最后，目前我使用的所有平台所有软件都支持vCard文件导入导出，这已经是业界通用的标准了。数据格式已经不存在兼容性问题。&lt;/p&gt;&lt;h2&gt;新的方法&lt;/h2&gt;&lt;p&gt;现在，我的通讯录的标准版本保留在我的云主机上，以org-mode文本格式存放。我之前介绍过&lt;a href=&quot;https://blog.3qin.us/emacs_applications.html&quot;&gt;Org-mode&lt;/a&gt;，它的一个功能是在文本文件中维护一个小型半结构数据库，并提供结构化编辑和快速查询的方法，这正是我对通讯录的要求。我用git对这个文件做版本控制，并把它和我云主机的所有文件一同备份。我另外写了一个简单perl脚本，把org文件转换为通用的vCard文件，拷贝到我所有终端。在终端上我不定期的把本地的通讯录清空，然后一股脑把整个通讯录导入。&lt;/p&gt;&lt;p&gt;目前，这个方法运行良好，我已经停用了所有通讯录同步服务。还有几个小问题：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;要尽量避免在手机终端上编辑通讯录，所有数据录入在云主机emacs上完成。当然我所有平台，包括&lt;a href=&quot;https://blog.3qin.us/Emacs_on_android.html&quot;&gt;手机&lt;/a&gt;都可以ssh我的云主机。&lt;/li&gt;
&lt;li&gt;手机导入过程不是完全自动化，还需要手动选中所有条目，删除，再从文件中导入。要是能脚本控制的话就好了。&lt;/li&gt;
&lt;li&gt;手机导入速度有点慢。我导入前通讯录全空，但手机导入速度仍只有每秒几条，速度不够理想。好在一旦开始就不需要管了。&lt;/li&gt;
&lt;/ul&gt;&lt;h2&gt;行事历呢？&lt;/h2&gt;&lt;p&gt;通讯录和行事历是个人信息系统里的哼哈二将。理论上，行事历也可以做与通讯录同样的处理。行事历的iCalendar文件的格式和vCard文件类似，各平台兼容性也很好，而且数据量还更小。但是，行事历的变化比通讯录快的多，稍稍过时的通讯录问题不大，但稍稍过时的行事历问题就大了。但行事历有一大好处，就是它其实不需要多平台同步，一直留在我手机里就好了，反正我也离不开手机不是？所以不需要同步，只需要备份。能常常把iCalendar文件导出再备份就好，这实现很简单，也不需要云服务。&lt;/p&gt;&lt;h2&gt;结束语&lt;/h2&gt;&lt;p&gt;我的方法不一定适合别人，看起来也像回到了80年代。但是技术上不一定越新潮越好用，鞋子合不合脚只有自己知道。&lt;/p&gt;</content:encoded>
</item>
<item>
<title>中文网页资料的分享</title>
<link>https://blog.3qin.us/chinese_web_content.html</link>
<enclosure type="image/jpeg" length="0" url="https://mail.3qin.us/~derek/blog_imgs/pics/huangye88.png"></enclosure>
<guid isPermaLink="false">15gyCsqnSVujR0e_sVSarjrKGb8gK_VU9Vznuw==</guid>
<pubDate>Fri, 19 Dec 2025 22:04:05 +0000</pubDate>
<description>互联网的一个重要作用是信息发布和分享。你只要有一个链接，任何人点这个链接都会分享到同样的信息。当然，有些信息受到保护，需要登录才能看到，这也可以理解。本文谈的只包括对公众开放的信息，即可以链接分享的公开信息。今天我调查了四个常见中文信息来源：</description>
<content:encoded>&lt;p&gt;互联网的一个重要作用是信息发布和分享。你只要有一个链接，任何人点这个链接都会分享到同样的信息。当然，有些信息受到保护，需要登录才能看到，这也可以理解。本文谈的只包括对公众开放的信息，即可以链接分享的公开信息。今天我调查了四个常见中文信息来源：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.toutiao.com&quot;&gt;今日头条&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://mp.qq.com&quot;&gt;微信/QQ公众号&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://zhidao.baidu.com&quot;&gt;百度知道&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.huangye88.com&quot;&gt;黄页88&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;h2&gt;今日头条&lt;/h2&gt;&lt;p&gt;今日头条到今天已经是巨无霸级别，上面有海量的信息，某些颇有价值，相当一部分在别的地方找不到。这些海量信息你无需使用APP，也无需登录，只用浏览器就可以看到，链接简洁明了，例如：&lt;a href=&quot;https://www.toutiao.com/i6853032117417443840/&quot;&gt;https://www.toutiao.com/i6853032117417443840/&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;下面说缺点。&lt;/p&gt;&lt;h3&gt;用户跟踪&lt;/h3&gt;&lt;p&gt;这是我见过所有网站中，cookie用量最大的之一。一次访问，你的浏览器就被植入11个cookie，还不包括少量第三方cookie。你就是匿名访问，头条也很努力地想弄清楚你是谁。&lt;/p&gt;&lt;h3&gt;无标准meta&lt;/h3&gt;&lt;p&gt;在社交媒体分享的时候，假如网页有若干标准化meta标签的话，渠道和对方可以先期了解链接的一些信息，例如缩略图，标题，摘要，媒体格式等等。业界两个标准一个是来自facebook的&lt;a href=&quot;https://ogp.me/&quot;&gt;Open Graph&lt;/a&gt;, 另一个是来自Twitter的&lt;a href=&quot;https://developer.twitter.com/en/docs/tweets/optimize-with-cards/overview/abouts-cards&quot;&gt;Twitter card&lt;/a&gt;. 头条都没有。就算你放弃标准，试图解析头条HTML内容，也找不到任何有用的元数据。所以，在非头条支持的社交媒体上，例如whatsapp，telegram等，头条链接都是干巴巴的链接。在微信上当然不是，这是由于微信和头条的协作关系，用api生成的。&lt;/p&gt;&lt;h3&gt;javascript超强依赖&lt;/h3&gt;&lt;p&gt;我自己写了个爬虫，试图分析一下头条链接内容。但是，我很快放弃了。因为&lt;strong&gt;什么都没有&lt;/strong&gt; . 头条链接内容虽然在浏览器里打得开，但在程序自动抓取情况下，什么都没有，一片空白。我一开始还以为是某种网络限制，或user agent检查，但后来我意识到，这全是javascript的魔法。你点的任何头条链接，&lt;a href=&quot;https://www.toutiao.com&quot;&gt;&lt;strong&gt;包括头条主页&lt;/strong&gt;&lt;/a&gt; ，其实给你传的都是一样的一个javascript程序，所有内容，包括标题，都由javascript二次下载。你如果不信，可以在浏览器里禁用javascript试试。当然，在今天javascript是网上浏览不可或缺的东西，但一般网站，尤其是信息发布性网站，至少会有一点文字信息不依赖javascript，只有头条做的够绝。&lt;/p&gt;&lt;p&gt;这个后果之一就是所有搜索引擎，除了头条自己的之外，都无法索引头条上的信息。我知道头条在推自己的搜索引擎，但是作为用户来说，在头条发布信息，就是断绝了其他一切流量可能，你所有的流量都来自头条自己。头条网站根目录的&lt;code&gt;robots.txt&lt;/code&gt;说的够直白：&lt;/p&gt;&lt;pre&gt;&lt;code&gt;User-agent: *
Disallow: /&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;爬虫请靠边站。&lt;/p&gt;&lt;h2&gt;微信公众号&lt;/h2&gt;&lt;p&gt;微信公众号也是规模庞大的信息发布平台。在一些领域，其实已经是垄断级别，而且和国内唯一最大的社交网络深度绑定，你不可能忽略它。公众号的文章内容除了在微信内部可以阅读，其链接也可以分享，通过普通浏览器匿名访问。当然，和微信的互动，如订阅，微信内分享，运行小程序是不行的，这也是可以预计到的。&lt;/p&gt;&lt;p&gt;下面说缺点。&lt;/p&gt;&lt;h3&gt;超长链接&lt;/h3&gt;&lt;p&gt;微信链接通常长这样：&lt;a href=&quot;https://mp.weixin.qq.com/s?__biz=MzA4NjMzNTEwMw==&amp;amp;mid=2653630285&amp;amp;idx=1&amp;amp;sn=fc50fe1d1fbf56a1bc1a0784cfe980a1&amp;amp;chksm=8415c45db3624d4ba56273c3d2af0d1e70b5f405d51d6f2bd3768bbe6be114efd2de140c53f7&quot;&gt;https://mp.weixin.qq.com/s?__biz=MzA4NjMzNTEwMw==&amp;amp;mid=2653630285&amp;amp;idx=1&amp;amp;sn=fc50fe1d1fbf56a1bc1a0784cfe980a1&amp;amp;chksm=8415c45db3624d4ba56273c3d2af0d1e70b5f405d51d6f2bd3768bbe6be114efd2de140c53f7&lt;/a&gt;. 带劲吧？实际上，如果你看的懂query string，这里最后的参数chksm其实是不必要的。但你分享出来就是这个鬼样子。当然，微信后台也会在浏览器里植入cookie来试图跟踪你，但貌似跟踪的力度不如头条。&lt;/p&gt;&lt;h3&gt;meta不标准&lt;/h3&gt;&lt;p&gt;微信公众号文章其实包含 OpenGraph 和 Twitter card, 但是是有问题的。例如：&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&amp;lt;meta property=&amp;quot;og:url&amp;quot; content=&amp;quot;http://mp.weixin.qq.com/s?__biz=MzA4NjMzNTEwMw==&amp;amp;amp;mid=2653630285&amp;amp;amp;idx=1&amp;amp;amp;sn=fc50fe1d1fbf56a1bc1a0784cfe980a1&amp;amp;amp;chksm=8415c45db3624d4ba56273c3d2af0d1e70b5f405d51d6f2bd3768bbe6be114efd2de140c53f7#rd&amp;quot; /&amp;gt;
  &amp;lt;meta property=&amp;quot;og:image&amp;quot; content=&amp;quot;http://mmbiz.qpic.cn/mmbiz_jpg/ibvjqYe1KOjBwFAj7MXVhGat6icJuyNefugzAtDw88tiaRCc2DqkEbLet3PU2sewCRfJmKvexVJYsWTvm8yicMSx0A/0?wx_fmt=jpeg&amp;quot; /&amp;gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;这个问题就在于链接是&lt;code&gt;http&lt;/code&gt;而不是&lt;code&gt;https&lt;/code&gt;，虽然我用浏览器访问的方式是&lt;code&gt;https&lt;/code&gt;. 根据互联网规范，&lt;code&gt;https&lt;/code&gt;网页不能内嵌非加密信息。搞笑的是假如你通过&lt;code&gt;http&lt;/code&gt;去加载这个图片的话，微信服务器会返回HTTP301，把你再重定向到同一个服务器，同一个路径下的&lt;code&gt;https&lt;/code&gt;链接上。所以说，微信的这些meta是写错了。&lt;/p&gt;&lt;h3&gt;Javascript 强依赖&lt;/h3&gt;&lt;p&gt;和头条一样，微信公众号文章不开Javascript也读不了。但稍微好一点的是，虽然内容没有，但是标题，和 opengraph meta 还是有的，所以你至少不是在看一个白板。对于爬虫分析来说，也有点信息，不至于什么都看不到。我估计各种搜索引擎还是有所覆盖的。&lt;/p&gt;&lt;h2&gt;百度知道&lt;/h2&gt;&lt;p&gt;百度知道是百度自己的公众问题解答网站，有些解答还是不错的。何况是百度自己人，所以在百度搜索排名都很高，不管你搜个什么，前几名必然有百度知道链接。当然，你分享链接后别人匿名访问，其实也不是那么匿名。除了百度cookie之外，百度知道自己还有自己的cookie。&lt;/p&gt;&lt;p&gt;先说优点：&lt;/p&gt;&lt;h3&gt;不依赖 Javascript&lt;/h3&gt;&lt;p&gt;你就算关掉Javascript，百度知道还是一个样子，所有内容都呈现。这里必须给个大大的好评。关掉javascript，百度就完全不能跟踪你是谁了，最多知道你的IP什么的。另外，这对搜索引擎也是大利好。毕竟百度是开这个的。&lt;/p&gt;&lt;p&gt;再说缺点：&lt;/p&gt;&lt;h3&gt;无任何标准meta&lt;/h3&gt;&lt;p&gt;和头条一样，百度知道完全没有Open Graph, Twitter Card之类的一切都没有，连&lt;code&gt;link rel=canonical&lt;/code&gt;都没有。假如社交分享这种链接就肯定什么都没有了。分析meta的时候我还发现了一个重大信息：&lt;/p&gt;&lt;h3&gt;GBK charset&lt;/h3&gt;&lt;p&gt;光用浏览器一般看不出来，但百度知道所有网页都还是GBK编码，而不是国际通用的UTF-8编码。有点不可思议，毕竟百度旗下其他几个网站，包括搜索都早就是UTF-8的了。这里简单介绍一下，GBK是GB2312的扩展，包含中英文还有日文假名之类字符。UTF-8是现在的国际标准，包含一切。这意味着百度知道不能使用例如：&lt;code&gt;😓&lt;/code&gt;, &lt;code&gt;💔&lt;/code&gt; 之类的字符，也不能用一些小众一点的语言。&lt;/p&gt;&lt;p&gt;这还不是最关键的。GBK支持在各种新型编程环境中基本不存在，当然，在古典语言例如C里也不存在，但那里毕竟可以用古代的第三方库，而二十一世纪的快捷编程环境通常已经假定字符串是UTF-8了，也没有什么库可以用。我写的爬虫程序自然也无法支持。&lt;/p&gt;&lt;h2&gt;黄页88&lt;/h2&gt;&lt;p&gt;黄页88是国内流行的B2B信息发布平台。样子虽然有点九十年代，但信息量还是不小，主要是各种中小企业广告，无需登录就可以浏览。所有链接都可以自由分享。&lt;/p&gt;&lt;p&gt;先说优点：&lt;/p&gt;&lt;h3&gt;相当完备的 Opengraph meta&lt;/h3&gt;&lt;p&gt;这是我见过除了facebook自己之外，对Opengraph支持最全的信息网站了。你分享的链接一定很漂亮。例如这个：&lt;/p&gt;&lt;figure&gt;
&lt;img src=&quot;https://mail.3qin.us/~derek/blog_imgs/pics/huangye88.png&quot; alt=&quot;huangye88&quot; title=&quot;&quot;/&gt;
&lt;figcaption&gt;huangye88&lt;/figcaption&gt;
&lt;/figure&gt;&lt;p&gt;上图来自&lt;a href=&quot;https://iframely.com/embed/https%3A%2F%2Fshenyang.huangye88.com%2Fxinxi%2F3671_152811788.html&quot;&gt;iframely.com&lt;/a&gt;的demo. 我没有付费，不好意思直接链接。&lt;/p&gt;&lt;h3&gt;不依赖 Javascript&lt;/h3&gt;&lt;p&gt;关掉Javascript，你唯一失去的就是第三方广告，整个网页甚至更漂亮了。各种搜索引擎想必都能轻松接入。&lt;/p&gt;&lt;p&gt;再说缺点：&lt;/p&gt;&lt;h3&gt;Opengraph 有瑕疵&lt;/h3&gt;&lt;p&gt;这似乎也不仅仅是opengraph的问题，黄页88有大量的图，大多数的图来自&lt;code&gt;https&lt;/code&gt;, 仍有少量来自&lt;code&gt;http&lt;/code&gt;, 没有端到端保护。opengraph meta里的链接也都是&lt;code&gt;http&lt;/code&gt; 的。我试了几个图和链接，把链接替换成&lt;code&gt;https&lt;/code&gt; 其实是照样工作的。和微信类似，但不同的是没有自动&lt;code&gt;http -&amp;gt; https&lt;/code&gt; 跳转。在这个年代，加密已经是主流，既然已经做到九成了，何必不做到十成，图个干净？&lt;/p&gt;&lt;h2&gt;总结&lt;/h2&gt;&lt;p&gt;一句话总结以上网站：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;黄页88：我很土，但我很努力&lt;/li&gt;
&lt;li&gt;百度知道：还活在2000年&lt;/li&gt;
&lt;li&gt;微信公众号：制霸中国，节操尚存&lt;/li&gt;
&lt;li&gt;今日头条：不是我的人，就是我的敌人&lt;/li&gt;
&lt;/ul&gt;</content:encoded>
</item>
<item>
<title>WEB1, WEB2 和 WEB3</title>
<link>https://blog.3qin.us/web1_web2_web3.html</link>
<enclosure type="image/jpeg" length="0" url="https://mail.3qin.us/~derek/blog_imgs/pics/yahoo_1997.jpg"></enclosure>
<guid isPermaLink="false">XIFOET1U-8H3WTGl2vzK_nwFSXPnijVqa7rQiw==</guid>
<pubDate>Fri, 19 Dec 2025 21:19:24 +0000</pubDate>
<description>WEB3 最近是一个热点词汇。什么是 WEB3 呢？要回答这个问题，我们要先了解什么是 WEB1 和 WEB2。 解释了什么是WEB1，2，3之后呢，我还想尝试一下预测未来，虽然我的预测通常很不准。</description>
<content:encoded>&lt;p&gt;WEB3 最近是一个热点词汇。什么是 WEB3 呢？要回答这个问题，我们要先了解什么是 WEB1 和 WEB2。 解释了什么是WEB1，2，3之后呢，我还想尝试一下预测未来，虽然我的预测通常很不准。&lt;/p&gt;&lt;h2&gt;WEB1&lt;/h2&gt;&lt;p&gt;WEB1 就是最原来的，上世纪九十年代的互联网。在WWW的发明人 Tim Berners-Lee 的最初构想里，互联网是一个全球化，分布式的一个信息发布和相互引用的平台，每一个有能力的人或机构都可以自己运行一个网站，自由地发布信息，而访问者也可以自主选择信息来源。用户和网站之间，网站和网站之间互不统属，采用业界的开放标准互相沟通。除了WWW之外，以下的一些应用也是同时期，并基于同样的开放，标准化，分布式的精神，所以我们也把它们归结到WEB1:&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.3qin.us/the_real_email.html&quot;&gt;电子邮件&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;BBS, IRC, XMPP 等即时通讯工具&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.3qin.us/blog_and_feed.html&quot;&gt;个人博客和 RSS 汇集&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;figure&gt;
&lt;img src=&quot;https://mail.3qin.us/~derek/blog_imgs/pics/yahoo_1997.jpg&quot; alt=&quot;Yahoo at 1997&quot; title=&quot;&quot;/&gt;
&lt;figcaption&gt;Yahoo at 1997&lt;/figcaption&gt;
&lt;/figure&gt;&lt;p&gt;为了方便广大用户在性质各异，种类繁多的网站中挑选自己需要的内容，先是出现了不少门户网站，然后出现了搜索引擎。但它们还是主要做流量分发，算是从属于WEB1 的应用模式。&lt;/p&gt;&lt;p&gt;如果要总结一下，WEB1 是以内容为主的WEB，内容的提供者自己建网站，直接和内容的消费者接触。除了要遵守法律之外，没有中间人的规则需要遵守。&lt;/p&gt;&lt;h2&gt;WEB2&lt;/h2&gt;&lt;figure&gt;
&lt;img src=&quot;https://mail.3qin.us/~derek/blog_imgs/pics/twitter_2007.jpg&quot; alt=&quot;Twitter at 2007&quot; title=&quot;&quot;/&gt;
&lt;figcaption&gt;Twitter at 2007&lt;/figcaption&gt;
&lt;/figure&gt;&lt;p&gt;WEB2 大致发端于2004年，来自于三个技术革新：智能手机，社交网络，和云服务。这时候出现了平台，平台上运行应用，应用再吸纳原来用户自主发布的内容。它解决了WEB1 的一大痛点， 就是自己建网站不仅有经济代价，还有不低的技术门槛和长期维护所需要的人力成本。内容的发布者大大降低了内容发布的成本，并可以借助平台和应用的网络效应快速吸引用户流量。平台之间一开始有激烈的竞争，不惜代价让利给内容发布者和消费者，但不出几年，增长快的平台通过规模效应和网络效应迅速打垮或吃掉小一点的平台，几次兼并之后，只剩下为数不多的几个，个个都在自己的领域有很强的垄断性，如苹果，谷歌，和脸书。我上文提到的几个 WEB 延伸应用也有了本质变化：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;邮件被几个超大型邮件服务商事实垄断&lt;/li&gt;
&lt;li&gt;即时通讯工具更加如此，而且摒弃了开放标准，成为互不联通的几大孤岛&lt;/li&gt;
&lt;li&gt;个人博客渐趋式微，网民被社交媒体收编&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;如果要总结一下，WEB2 是以应用为主的WEB，掌控权和盈利被平台把持。内容的提供者和内容的消费者中间隔着平台，大家都被平台所绑架了。&lt;/p&gt;&lt;h2&gt;WEB3&lt;/h2&gt;&lt;p&gt;WEB2 演进到现在，从内容提供者搞消费者都越来越不满：费用越来越贵，广告越来越多，隐私越来越少，还无端删帖屏蔽。没办法，垄断嘛。&lt;/p&gt;&lt;blockquote&gt;
&lt;p&gt;天下苦秦久矣。 —- 司马迁 《陈涉世家》&lt;/p&gt;
&lt;/blockquote&gt;&lt;p&gt;于是现在有人提出了WEB3 的概念，就是利用区块链技术，让WEB 重新变成分布式的样子，打破平台的垄断。区块链技术最成熟的应用就是加密货币，其中最古老最有名也是市场总量最大的就是比特币。其实，明眼人都看的出来，加密货币就是一个&lt;a href=&quot;https://en.wikipedia.org/wiki/Ponzi_scheme&quot;&gt;庞氏骗局&lt;/a&gt;. 但很多人不知道的是，主权货币，例如美元，人民币之类，不也是庞氏骗局吗？现在主权货币的发行者，也就是各央行，手里根本没有真金白银，&lt;a href=&quot;https://www.lynalden.com/debt-jubilee/&quot;&gt;所有的资产95% 以上是国债，或者比国债更无聊的东西&lt;/a&gt;。国债本身又是以同一个主权货币来计算，这货币绕到最后还不是一张纸。都是骗子，就看谁能骗到底了。&lt;/p&gt;&lt;blockquote&gt;
&lt;p&gt;窃钩者诛，窃国者为诸侯。 —- 孟子&lt;/p&gt;
&lt;/blockquote&gt;&lt;figure&gt;
&lt;img src=&quot;https://mail.3qin.us/~derek/blog_imgs/pics/coinbase_2022.jpg&quot; alt=&quot;Coinbase&quot; title=&quot;&quot;/&gt;
&lt;figcaption&gt;Coinbase&lt;/figcaption&gt;
&lt;/figure&gt;&lt;p&gt;主权货币靠的是国家信用，加密货币靠的是加密算法和世界各地的参与者，谁说没有国家主权就不能发行货币了？&lt;/p&gt;&lt;p&gt;区块链说到底，是一个分布式的数据库。而数据库，就是所有林林总总的WEB 应用的核心：任何内容说到底不还是数据。所以，以区块链为基础做的互联网应用，就是WEB3。 理论上万物都可以做，实际上有一个重大的问题：作为一个数据库，区块链的效率非常低。所以直到现在，WEB3主流的应用还是一些附加值非常高的应用，如加密货币交易，NFT交易等。提高效率的方法不是没有：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;链外数据汇总。但这会大大降低安全性&lt;/li&gt;
&lt;li&gt;中心化管理。但这不是回到WEB2的老路上了吗？&lt;/li&gt;
&lt;/ul&gt;&lt;h2&gt;预测&lt;/h2&gt;&lt;p&gt;我的看法是WEB3并不是 WEB1 或 WEB2 的取代品。区块链解决了两个很重要的问题：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;在分布式数据管理情况下的各方互相信任问题&lt;/li&gt;
&lt;li&gt;在法律够不到的情况下权力和义务认定的问题&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;这扩展了WEB应用的领域，但不是所有的问题都适合用用区块链技术来解决的。WEB2 大规模取代 WEB1 是一个偶然，这个偶然不会再重复。&lt;/p&gt;&lt;p&gt;WEB2的问题是垄断，但这是一个经济学问题，或者说是一个社会学问题，不是一个技术问题，也不应该用技术来解决。我估计只会有少量WEB2应用会迁移到WEB3技术上，另会有少量WEB2应用会回归到WEB1，例如第一方内容发布。&lt;/p&gt;&lt;p&gt;WEB1 的技术也在发展。在今天，在自由软件和虚拟化的加持下，自己设立网站的技术门槛已经大大降低，我就有好几个，不算本博客，还有 &lt;a href=&quot;https://roastidio.us/&quot;&gt;吐槽俱乐部&lt;/a&gt;, &lt;a href=&quot;https://airss.roastidio.us/&quot;&gt;Airss 推送阅读&lt;/a&gt;, &lt;a href=&quot;https://gara.fly.dev/&quot;&gt;还不去开房&lt;/a&gt;，我还&lt;a href=&quot;https://blog.3qin.us/living_in_email.html&quot;&gt;自己运行自己的邮件服务&lt;/a&gt;&lt;/p&gt;&lt;p&gt;其实WEB1，WEB2，WEB3之争最终争的是用户。作为用户，你的回答是“别人用啥，我就用啥”，还是“我爱用啥，我就用啥”呢？我希望是后者，但不少人的实际选择是前者。&lt;/p&gt;</content:encoded>
</item>
<item>
<title>清空你的收件箱</title>
<link>https://blog.3qin.us/inbox_zero_on_webmail.html</link>
<enclosure type="image/jpeg" length="0" url="https://mail.3qin.us/~derek/blog_imgs/pics/empty_outlook.png"></enclosure>
<guid isPermaLink="false">JSLG3vZO-zuooGxalXlSMlJXDsKuFt4FYqh2Ww==</guid>
<pubDate>Wed, 17 Dec 2025 23:19:34 +0000</pubDate>
<description>看邮件在这个时代已经成为一个负担。一般认为，清空收件箱(Inbox Zero)是保证Email处理及时的最佳策略。它指的是保持你的收件箱接近于空，所有邮件都看过，该回复的回复，然后归档保存，以便于全文搜索。但是你会说：</description>
<content:encoded>&lt;p&gt;看邮件在这个时代已经成为一个负担。一般认为，清空收件箱(Inbox Zero)是保证Email处理及时的最佳策略。它指的是保持你的收件箱接近于空，所有邮件都看过，该回复的回复，然后归档保存，以便于全文搜索。但是你会说：&lt;/p&gt;&lt;blockquote&gt;
&lt;p&gt;臣妾做不到啊！&lt;/p&gt;
&lt;/blockquote&gt;&lt;p&gt;与之对应的是无限收件箱(Inbox Infinity), 就是完全放任自流，除非有人提醒你要看邮件了再看，而且也只看想看的那几封。我估计现在大多数人都是采取第二种策略，毕竟是懒人的方法。&lt;/p&gt;&lt;blockquote&gt;
&lt;p&gt;一屋不扫，何以扫天下。&lt;/p&gt;
&lt;/blockquote&gt;&lt;p&gt;我今天我就来清一下我三个web mail账户: &lt;a href=&quot;https://outlook.com&quot;&gt;https://outlook.com&lt;/a&gt;, &lt;a href=&quot;https://mail.yahoo.com&quot;&gt;https://mail.yahoo.com&lt;/a&gt;, &lt;a href=&quot;https://gmail.com&quot;&gt;https://gmail.com&lt;/a&gt;。已经放任自流很久了。还有救吗？&lt;/p&gt;&lt;h2&gt;我的账户&lt;/h2&gt;&lt;p&gt;先大致看一下我都有什么：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href=&quot;https://outlook.com&quot;&gt;https://outlook.com&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;hotmail是web mail的先驱。我1997年注册，当年还尚未被微软收购。这个邮箱多年废弃不用，信噪比极低，目前收件箱邮件一万左右。&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href=&quot;https://mail.yahoo.com&quot;&gt;https://mail.yahoo.com&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Yahoo是当年互联网老大，我自然也有账号。我在2001年左右注册，曾长期使用。现在也基本废弃。目前收件箱邮件五千以上，有一定的有效邮件。&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href=&quot;https://gmail.com&quot;&gt;https://gmail.com&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Gmail 2004年横空出世，让web mail发生了革命，如大空间，全文搜索，但也从此带来了无限收件箱的恶果。我注册于2006年，长期使用，一直没有废弃，但最近看的比较少。目前收件箱邮件不知道有多少（gmail提供的数字很不准，只能做参考），当在一万以上。&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;现在，yahoo，outlook也早已提供足够大的存储空间，让我也堕入无限收件箱的深渊。还记得很久之前，看邮件可积极了，但是如今呢？&lt;/p&gt;&lt;blockquote&gt;
&lt;p&gt;Now email feels like a chore, rather than a joy. Something you fall behind on. Something you clear out, not cherish. Rather than delight in it, you deal with it. Your relationship with email changed, and you didn’t have a say.&lt;/p&gt;
&lt;p&gt;– hey.com&lt;/p&gt;
&lt;/blockquote&gt;&lt;p&gt;我的目的是清空以上三个收件箱，垃圾扔掉，剩下全部归档保存在我自己的云主机上。做的到吗？&lt;/p&gt;&lt;h2&gt;工具&lt;/h2&gt;&lt;p&gt;工欲善其事，必先利其器。对于海量邮件的处理，我需要强悍的工具：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://pyropus.ca/software/getmail/&quot;&gt;getmail&lt;/a&gt;. 超多功能的命令行邮件迁移工具，但我只用POP3功能下载邮件。&lt;/li&gt;
&lt;li&gt;我自己写的perl脚本，利用了CPAN上三个主要邮件处理相关的包：
&lt;ul&gt;
&lt;li&gt;Mail::Internet, 负责提取，转移邮箱里的邮件&lt;/li&gt;
&lt;li&gt;Mail::Message，负责结构化处理邮件&lt;/li&gt;
&lt;li&gt;DateTime::Format::Mail，负责弄清楚邮件日期&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.mutt.org&quot;&gt;mutt&lt;/a&gt;. 我目前日常使用的邮件环境是&lt;a href=&quot;https://www.djcbsoftware.nl/code/mu/mu4e.html&quot;&gt;mu4e&lt;/a&gt;, 好处是和我工作环境emacs紧密集成，但特殊情况还是要祭出更快速更强悍的mutt&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;我的步骤是：&lt;/p&gt;&lt;ol&gt;
&lt;li&gt;用getmail一股脑把邮件通过POP3全部下载&lt;/li&gt;
&lt;li&gt;用脚本把有用的和没用的分开&lt;/li&gt;
&lt;li&gt;用肉眼把没用的再过一遍，以免有遗漏。&lt;/li&gt;
&lt;li&gt;有用的归档，没用的扔掉。&lt;/li&gt;
&lt;/ol&gt;&lt;p&gt;有用和没用的定义很简单：我回复过的都是有用的，我信任的人发来的都是有用的，其他都是没用的。这是我长期总结出来的经验，这些判断也都可以通过我的脚本做到。&lt;/p&gt;&lt;h2&gt;清空过程&lt;/h2&gt;&lt;p&gt;一个账户一个账户来吧。&lt;/p&gt;&lt;h3&gt;outlook.com&lt;/h3&gt;&lt;figure&gt;
&lt;img src=&quot;https://mail.3qin.us/~derek/blog_imgs/pics/empty_outlook.png&quot; alt=&quot;empty outlook&quot; title=&quot;&quot;/&gt;
&lt;figcaption&gt;empty outlook&lt;/figcaption&gt;
&lt;/figure&gt;&lt;p&gt;Outlook.com 几经沿革，现在已经和当年大不一样了。说实话并不难用。打开pop功能需要在网页设置里点一下，提示简单明确，但第一遍会失败，要再回网站里确认一下。之后就能一通到底，让getmail一口气把所有邮件下载，用时不到一小时，下载一个G左右。网页inbox清空如下：&lt;/p&gt;&lt;p&gt;由于这里基本都是垃圾，所以我的分类脚本相当成功，运行十分钟，找到不到200有用邮件。我又肉眼把垃圾箱里近万封邮件再扫一遍，没发现什么有用的。手工扫描不到半小时，再清空垃圾箱，收工！&lt;/p&gt;&lt;h3&gt;mail.yahoo.com&lt;/h3&gt;&lt;figure&gt;
&lt;img src=&quot;https://mail.3qin.us/~derek/blog_imgs/pics/empty_yahoo.png&quot; alt=&quot;empty yahoo&quot; title=&quot;&quot;/&gt;
&lt;figcaption&gt;empty yahoo&lt;/figcaption&gt;
&lt;/figure&gt;&lt;p&gt;Yahoo! 已是过眼云烟，现在已经属于Verizon。现在网页做的也还行，就是广告稍微多了点。和微软谷歌不同，Verizon无法集成什么应用，当然就算有别人也不会去用。在这里打开pop功能还费了一番手脚，不仅要打开一个开关，还要设定专有app password，网页文档也不甚明确。好歹是有惊无险，总算通了。最后一个问题是无法一口气下载，下载一次只搞到一两千封，还要手动再来几次，直到彻底清空。Yahoo下载速度明显比outlook.com慢不少，虽然总体量比outlook小不少，但下载了一个多小时，才总算清空了：&lt;/p&gt;&lt;p&gt;这里有我不少早期私人邮件。我的脚本还是几分钟搞定，找到两百多封有用邮件。但肉眼扫描之下，发现不少遗珠。我昨天晚上花了一个多小时，常常迷失在阅读老邮件上。最后又找到几百封有用邮件。总算搞定，再清空垃圾箱，收工！&lt;/p&gt;&lt;h3&gt;gmail.com&lt;/h3&gt;&lt;figure&gt;
&lt;img src=&quot;https://mail.3qin.us/~derek/blog_imgs/pics/ongoing_gmail.png&quot; alt=&quot;ongoing gmail&quot; title=&quot;&quot;/&gt;
&lt;figcaption&gt;ongoing gmail&lt;/figcaption&gt;
&lt;/figure&gt;&lt;p&gt;多少年了，Gmail仍然是web mail的老大。但是当年革命性的创举已经被outlook.com赶上，各种应用集成别人也有了。在这里打开pop功能也需要在网页设置点一下，还要打开所谓insecure legacy app访问。好在网页文档还是比较明确。Gmail下载速度比yahoo快，但比outlook要慢。但最大问题是每次仅能下载五六百封就没了，比Yahoo还要糟糕。我今天上午我写博客过程中，一直在手动继续下载，有几十次了，但现在邮箱里还有至少好几千：&lt;/p&gt;&lt;p&gt;Gmail里估计至少有几千我的私人邮件。今天晚上有的忙了。&lt;/p&gt;&lt;h2&gt;空箱以后呢&lt;/h2&gt;&lt;p&gt;空箱之后，还要继续保持空箱。其实，只要做到以下几点这并不难。我在非web mail账户中已经做到了，并维持了数年。现在要把这个习惯延伸到web mail上：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;只有一个收件箱，跨越所有账户，保存过去一个月所有往来邮件。目前我这里邮件数量不到一千，绝大多数都看过。&lt;/li&gt;
&lt;li&gt;只有一个归档箱，跨越所有账户，保存所有有用邮件直到永远。目前我这里邮件已经接近十万。只靠通过搜索来访问。&lt;/li&gt;
&lt;li&gt;关闭新邮件提醒。我每天在碎片时间主动浏览收件箱里的新邮件，能快速回复快速回复。需要后续操作的邮件先标记下来。&lt;/li&gt;
&lt;li&gt;每一到两天抽空把标记出需要耐心回复或额外操作的邮件耐心处理，防止越积越多，待处理邮件最多不能超过一周。&lt;/li&gt;
&lt;li&gt;对于次要邮箱，例如这三个，不再使用网页或app。每天午夜用脚本通过getmail自动下载新邮件到统一收件箱，第二天一起处理。&lt;/li&gt;
&lt;li&gt;最后，最关键的是：在99%的时间，&lt;strong&gt;只使用字符界面工具处理邮件&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;由于我绝大多数时间仅使用字符界面工具处理邮件，这完全避免了病毒，恶意网站，用户跟踪，图片，声音等负面影响，可以放心去看。而且处理速度大大加快。在合理防御下，我每天收到的垃圾，广告，无意义提醒加在一起不到一百。我相信，这已经比大多数人多。但我处理每封时间不到半秒，总耗时不到一分钟。相比如果漏看一封有意义的邮件对你带来的机会成本来说，这一分钟绝对值得。&lt;/p&gt;&lt;p&gt;邮件在诞生的时候就是一个字符界面工具，现在是时候让邮件彻底回归本源了：&lt;/p&gt;&lt;blockquote&gt;
&lt;p&gt;And yet, email remains a wonder. Thanks to email, people across cultures, continents, countries, cities, and communities communicate every day. It’s reliable. It’s simple. There are no service provider incompatibilities, technical hurdles, or gatekeepers. If you have an email address, and they have an email address, email just works, every time.&lt;/p&gt;
&lt;p&gt;– hey.com&lt;/p&gt;
&lt;/blockquote&gt;&lt;h2&gt;后记&lt;/h2&gt;&lt;figure&gt;
&lt;img src=&quot;https://mail.3qin.us/~derek/blog_imgs/pics/empty_gmail.png&quot; alt=&quot;empty gmail&quot; title=&quot;&quot;/&gt;
&lt;figcaption&gt;empty gmail&lt;/figcaption&gt;
&lt;/figure&gt;&lt;p&gt;最终，我从Gmail下载了两万封邮件，总体量超过两个G。用脚本自动检测出六千多有用邮件，再用肉眼找出不到一千。把Gmail也终于清空了。&lt;/p&gt;</content:encoded>
</item>
<item>
<title>你有电子邮件邮箱吗？</title>
<link>https://blog.3qin.us/the_real_email.html</link>
<enclosure type="image/jpeg" length="0" url="https://mail.3qin.us/~derek/blog_imgs/pics/derek.jpg"></enclosure>
<guid isPermaLink="false">xuYLtZN_P75FC6HfH3WrKjW5RIWCs77FscgevQ==</guid>
<pubDate>Wed, 17 Dec 2025 19:32:16 +0000</pubDate>
<description>这个问题好像是白给：Email是互联网最古老的通信方式了，是人都有啊。但是，我在这里大胆说一句：在读到我博客所有读者中，拥有自己的电子邮件邮箱的人不到1%。</description>
<content:encoded>&lt;p&gt;这个问题好像是白给：Email是互联网最古老的通信方式了，是人都有啊。但是，我在这里大胆说一句：在读到我博客所有读者中，拥有自己的电子邮件邮箱的人不到1%。&lt;/p&gt;&lt;h2&gt;邮件是做什么的？&lt;/h2&gt;&lt;p&gt;我们先探讨一下，邮件是干什么的。到二十一世纪今天，通信方式多种多样，通信的需求也非常细化了。用邮件沟通最适合做什么呢？&lt;/p&gt;&lt;h3&gt;实时通知？&lt;/h3&gt;&lt;p&gt;假如我想请你今天晚上出去小酌一番，提前一小时发你邮件了，然后你放了我鸽子。错在谁呢？显然，错在我这里。对于实时性比较强的通信，邮件是一个很不好的手段。我可以微信你，短信你，打电话Call你，就是不应该发邮件。同理，任何通知性的信息，例如开会提醒，上课提醒，交作业提醒等等，你都不应该发邮件了，发了也是白发，徒增烦恼而已。&lt;/p&gt;&lt;h3&gt;文件传递？&lt;/h3&gt;&lt;p&gt;常常有人给我发邮件，邮件里最多一句话，但有一个不小的附件，常常是文档，电子表格之类，意图通常是让我看看，改改，再发回去。老实说，这是一个非常糟糕的工作方式。除了上面说过的实时性不够的问题，还有：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;邮件有比较严格的大小限制&lt;/li&gt;
&lt;li&gt;邮件是Base64编码，你发4MB的附件，实际要存5MB&lt;/li&gt;
&lt;li&gt;你发来，我发去，同一个附件交流无数次，没版本控制不说，浪费的存储空间是惊人的。&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;少量文件应该用即时通信工具，最好有端到端加密的工具如Signal等传递。大量文件应该用项目管理工具来管理。&lt;/p&gt;&lt;h3&gt;讨论问题？&lt;/h3&gt;&lt;p&gt;很多人，尤其是在工作中，喜欢用邮件来回讨论问题。但是这也是很有问题的。问题之一是在outlook影响下，绝大多数人回邮件是&lt;a href=&quot;https://en.wikipedia.org/wiki/Posting_style#Top-posting&quot;&gt;top post&lt;/a&gt;, 导致上下文是逆序的，除了当事双方，别人相当难以理解。而且邮件越回越长，下面从来没有人修剪，最后无法阅读。问题之二是当气氛有点不友好之后，你抄送我老板反映，我抄送你老板反映，再有第三者出来搅浑水，最后通常变成骂战，没一点建设性了。&lt;/p&gt;&lt;p&gt;对于大多数人来说，讨论问题应该在恰当的论坛，BBS或讨论组里。这里有用户权限控制和归档功能，更容易达到文明理性讨论的目的。&lt;/p&gt;&lt;h2&gt;邮件还有用吗？&lt;/h2&gt;&lt;p&gt;既然以上都不适合用邮件，那我们干脆不要邮件了不是更简单？那我们现在来探讨一下邮件不可取代的地方：&lt;/p&gt;&lt;h3&gt;留作证据&lt;/h3&gt;&lt;p&gt;假如你老板跟你面谈的时候承诺这个项目完成之后给你加薪升职，我建议你立刻写个邮件给他，敲钉转角，而且一定要留个问题问他，让他不得不回复一下。同理，会议记录，备忘录等等也是这个目的。&lt;/p&gt;&lt;h3&gt;备份渠道&lt;/h3&gt;&lt;p&gt;邮件虽然在各个专项都不是最好的通信手段，但却是在各个专项中最好的通信手段不能用或不够可靠的时候，不可或缺的一个备份渠道。&lt;/p&gt;&lt;h3&gt;永久归档&lt;/h3&gt;&lt;p&gt;你收到的邮件其中99%最多过一个月就一点用都没有了。但剩下1%你却希望能永久保留下去，不仅十年，二十年之后可以再看，平时也可以搜索关键字什么的来回顾，找到对有用的信息。&lt;/p&gt;&lt;h2&gt;我们有什么？&lt;/h2&gt;&lt;p&gt;现在我们回到刚开始的问题：我们有没有自己的电子邮件邮箱？&lt;/p&gt;&lt;p&gt;绝大多数人有的是只不过是以下两者：&lt;/p&gt;&lt;h3&gt;工作邮箱&lt;/h3&gt;&lt;p&gt;工作邮箱其实不太好用作证据留存，尤其是可能和你的工作单位发生争执的时候。除了你入职签的保密协议会对你不利之外，公司的工作邮箱其实是有后台可以被管理员任意修改的。&lt;/p&gt;&lt;p&gt;工作邮箱其实也不是一个好的备份通信渠道。通常工作邮箱会有一些不近人情的过滤机制和纪律约束，也不建议你用作工作之外的私人联系。&lt;/p&gt;&lt;p&gt;最后工作邮箱不可能永久。或者你走，或者开你走，或者关门，有多少人能在一个地方干超过十年？枉提一辈子了。&lt;/p&gt;&lt;h3&gt;免费邮箱服务&lt;/h3&gt;&lt;p&gt;当然，你还有自己的个人邮箱，来自诸如Gmail，hotmail，或国内的QQ邮箱，网易邮箱什么的。可惜的是，这些也不是你的。坦率的说，这些服务是针对你个人的广告投放平台和隐私搜集工具，其邮件功能只不过是引你上钩的诱饵罢了。我们先不提广告啊，隐私啊什么的，就只考虑邮件功能，它们都很欠缺：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;数据下载相当困难。详见我之前&lt;a href=&quot;https://blog.3qin.us/inbox_zero_on_webmail.html&quot;&gt;博客&lt;/a&gt;。普通人根本做不到归档。&lt;/li&gt;
&lt;li&gt;借反垃圾邮件的名义，设置不近人情的门槛限制正当邮件进入，却对广告商大开方便之门。电子邮件成了最不可靠的通信手段，谈何做备份渠道。&lt;/li&gt;
&lt;li&gt;留作证据倒是不假，但恐怕是服务商留作针对你的证据吧。真正有信息量的邮件，你放心让QQ收吗？&lt;/li&gt;
&lt;/ul&gt;&lt;h2&gt;怎么办？&lt;/h2&gt;&lt;p&gt;我能想到的只有两个办法。&lt;/p&gt;&lt;h3&gt;有节操的付费服务&lt;/h3&gt;&lt;p&gt;任何服务都是有价值的，你不是花钱买，就是花了别的什么东西。当然，花钱未必能保证不被虐，但不花钱则一定被虐。可惜的是，这个市场被贪图蝇头小利的屌丝们裹挟，有节操，踏踏实实挣用户钱的服务商不容易生存。中国国内我暂时没有见到针对个人的靠谱服务。国外有一些，例如今年新出的比较火的&lt;a href=&quot;https://hey.com&quot;&gt;hey.com&lt;/a&gt;。年费99美元，我认为这个收费标准还是合理的。&lt;/p&gt;&lt;h3&gt;自己搭&lt;/h3&gt;&lt;p&gt;我就是这样，用自己的域名，自己（租）的服务器，自己做管理员。邮件服务都是非常成熟的自由软件，归根到底没多难搞，我的精力其实主要花在跟垄断型邮件服务商斗智斗勇上了，争取我发出的邮件别人能收到。对自己搭邮件服务有兴趣的朋友可以和我交流。&lt;/p&gt;&lt;p&gt;我不会再丢任何一封有意义的邮件了。你呢？&lt;/p&gt;</content:encoded>
</item>
<item>
<title>我的电子邮件处理流程</title>
<link>https://blog.3qin.us/email_flow.html</link>
<enclosure type="image/jpeg" length="0" url="https://mail.3qin.us/~derek/blog_imgs/pics/derek.jpg"></enclosure>
<guid isPermaLink="false">XNFvAW_KB8Q4Pm5FpObZGYLn67ThCtY711yfCQ==</guid>
<pubDate>Wed, 17 Dec 2025 19:32:15 +0000</pubDate>
<description>几个月前我写过一篇 你有电子邮件邮箱吗？ ，阐述了电子邮件在这个时代对于个人来说不可取代的地方。我自己对邮件的处理流程经过很多年，在很多个工具上的逐步提炼，形成了一个我自以为比较简练合理的流程，在这里总结一下，希望对读者有一定启发。我这里描述的流程主要适用于个人邮件。工作邮件出于你的公司基础架构的种种限制，可能不一定可以适用。</description>
<content:encoded>&lt;p&gt;几个月前我写过一篇&lt;a href=&quot;https://blog.3qin.us/the_real_email.html&quot;&gt;你有电子邮件邮箱吗？&lt;/a&gt;，阐述了电子邮件在这个时代对于个人来说不可取代的地方。我自己对邮件的处理流程经过很多年，在很多个工具上的逐步提炼，形成了一个我自以为比较简练合理的流程，在这里总结一下，希望对读者有一定启发。我这里描述的流程主要适用于个人邮件。工作邮件出于你的公司基础架构的种种限制，可能不一定可以适用。&lt;/p&gt;&lt;h2&gt;极简组织&lt;/h2&gt;&lt;p&gt;邮件归根结底，是很多很多个文件，它们的主要内涵是文字，相互之间也有一定的松散关系。为了方便处理，我认为邮件一定要完全保存在一个你可以快速访问的主机上，可以绕过所有工具，直接用脚本处理。否则，这些数据就不是在真正意义上属于你。&lt;/p&gt;&lt;p&gt;我的邮箱组织只有两个文件夹：Inbox (收件箱), Archive (归档箱). 此外没了。我所有的邮件，不管从什么地址收下来的，都在这里。收件箱保留最近一个月的往来邮件，通常数量在一千左右，归档箱保留所有有意义的长期保留的邮件，目前超过七万。其他所有的文件夹都没有：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;没有草稿箱。简单邮件不需要打草稿。复杂邮件我草稿不打在邮件界面里。何况我的云主机永不掉线，草稿在人机界面 (主要是Emacs) 上几天也不会丢。&lt;/li&gt;
&lt;li&gt;没有发件箱。我所有自己写就的邮件都Bcc自己，这样在收件箱里自然形成完整会话，不需要另行保存。&lt;/li&gt;
&lt;li&gt;没有垃圾箱。我从来不手动删除邮件。我会用脚本自行归档邮件，剩下的自然而然就最多保留一个月。&lt;/li&gt;
&lt;li&gt;没有自动检测的垃圾邮件箱。在我的邮件服务器上有相对宽松的&lt;a href=&quot;https://blog.3qin.us/block_spam_by_source.html&quot;&gt;垃圾检测机制&lt;/a&gt;, 这些彻底的垃圾会直接拒收。其他我全部收下来。&lt;/li&gt;
&lt;li&gt;没有任何分类箱。不少人，包括我自己以前，总想着分门别类地把邮件收集好。最后我发现我坚持不了几年。如果三天打鱼两天晒网地去归类，还不如不做。何况，一个长期有效，合理科学的分类方法也近乎不可能。&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;另外，我也不使用高级一点的标签，标记，优先级标注等功能。首先它们对我用处不大，再者我也无法坚持。有些事情要给自己留余地。题外话的一个例子：比如说跑步，我每天其实可以跑5公里。但跑了五公里之后我回家要瘫坐在沙发一段时间，也做不到持之以恒。后来我减半到2.5公里，过去一年的时间我天天都在跑，一年下来也有不少里程了。&lt;/p&gt;&lt;h2&gt;线索第一&lt;/h2&gt;&lt;p&gt;我重度依赖的邮件功能就是线索管理。我必须明确知道，哪封邮件是回复哪封的，这样邮件们形成一个树状组织结构，这样我才能追本溯源，上下贯通。我完全不可以接受Gmail或Outlook的线性会话结构。当然，目前在手机客户端也没有什么选择余地，所以我尽量不用任何手机上的邮件app。有必要的时候，我会手动修剪甚至嫁接邮件树，来应对一些乱回复，或者使用不当邮件客户端的人。当然，这些树操作功能有热键方便操作。&lt;/p&gt;&lt;p&gt;任何有意义的邮件线索，我都会回复。如果实在无话好说，一句谢谢也是可以的。如果一定不能回复给发件人，想保密的话，那我也会回复，但会把回复的对象删除，只保留自己。这其实是假回复，我有快捷键来保证秒级处理。当然，假回复也并不常见。我自己的回复自然而然就形成了标记，而这标记不依赖于任何特定邮件平台的特定功能。&lt;/p&gt;&lt;p&gt;有了线索之后，我可以利用线索来加强搜索能力，和简化自动化归档。&lt;/p&gt;&lt;h2&gt;搜索访问&lt;/h2&gt;&lt;p&gt;我的归档箱中邮件几万，唯一可行的访问方法是搜索。所以，一个针对自己邮件的定制搜索引擎是必不可少的。我用过两个：一个是&lt;a href=&quot;https://notmuchmail.org/&quot;&gt;notmuch&lt;/a&gt;, 一个是&lt;a href=&quot;https://www.djcbsoftware.nl/code/mu/&quot;&gt;mu&lt;/a&gt;. 目前我使用后者。它们都是本地安装的软件，而我直接把搜索安装在我的云主机上。查询语法很丰富，我不能完全记忆，还需要时常参考文档。我通常先根据一定关键字，发件人，时间段等信息先做搜索缩小范围以便快速人工浏览，然后再通过邮件线索信息做细化搜索找出依赖关系来弄清楚上下文。&lt;/p&gt;&lt;p&gt;有了一个强大的搜索引擎之后，这几万封邮件才成了真正有意义的个人数据；否则这些只是无用的堆砌而已。&lt;/p&gt;&lt;h2&gt;自动归档&lt;/h2&gt;&lt;p&gt;我的收件箱保留最近一个月所有往来邮件，也方便常规非搜索的邮件客户端软件使用。但我整个邮件处理流程的核心是归档。归档的意义有两个：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;去芜存菁&lt;/li&gt;
&lt;li&gt;节约空间&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;我收件箱中的邮件中完全垃圾大致10% ~ 20%左右。剩下的至少60% ~ 70%都是广告，群发邮件，各种通知，或者其他信息量很少的邮件。只有10% ~ 20%需要长期保留。那我是如何把这些需要保留的邮件找出来的呢？我多年以来总结出的算法如下：&lt;/p&gt;&lt;ol&gt;
&lt;li&gt;归档的单元是线索。&lt;/li&gt;
&lt;li&gt;所有仍有未读邮件，或者最新回复在一个月内的线索保留在收件箱内。&lt;/li&gt;
&lt;li&gt;所有有我回复参与的线索归档。&lt;/li&gt;
&lt;li&gt;所有我不参与的线索删除。&lt;/li&gt;
&lt;li&gt;归档线索中，所有附件删除。&lt;/li&gt;
&lt;/ol&gt;&lt;p&gt;这个算法简单明了，容易实现，没有任何模糊空间，而且也不依赖于任何邮件内容。我之前提到的主动回复，假回复，线索剪裁嫁接等操作都是为归档服务的：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;主动回复标记了有用线索，同时也是网上礼节。&lt;/li&gt;
&lt;li&gt;假回复在保密情况下也标记了有用线索，在热键定义下方便快捷。&lt;/li&gt;
&lt;li&gt;线索剪裁和嫁接保证了线索的合理性，剪掉了垃圾分支，对于归档之后的搜索访问也是大有帮助的。&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;另外，我在归档过程中自动删除了所有附件来节约空间。我归档箱中七万多邮件，总大小不压缩只有两三个G。附件不参与全文检索，所以对搜索没什么意义。这些附件可能也有部分有意义，但是，它们信噪比低，又很难用搜索找出来，全盘考虑下，我还是选择全部删除来简化算法。少量实在有用的附件我会另行保存。&lt;/p&gt;&lt;h2&gt;未来&lt;/h2&gt;&lt;p&gt;目前我的邮件流程已经比较固定了，但是定制化的部分比较多，不是很容易推广。今年我会争取把适用性强的部分抽取出来，发表成自由软件，方便其他用户使用。我也希望能多了解其他邮件用户的独到心得，进一步完善我的流程。&lt;/p&gt;</content:encoded>
</item>
<item>
<title>安卓手机上的Emacs</title>
<link>https://blog.3qin.us/Emacs_on_android.html</link>
<enclosure type="image/jpeg" length="0" url="https://mail.3qin.us/~derek/blog_imgs/pics/phone-emacs.png"></enclosure>
<guid isPermaLink="false">KKYGGmLbTordSzMiLTVdX73Dhm2QfdNxhq7HNQ==</guid>
<pubDate>Sun, 14 Dec 2025 20:40:47 +0000</pubDate>
<description>我上个月的博客有一篇关于 Emacs , 有一篇关于 Android手机 . 自然而然，会有人希望在手机上运行 Emacs, 是不是? 我当时以为不行，但其实我错了。Emacs 可以在 Android 手机上运行，而且不是 ssh 到远程主机上，不是什么简化版，不是什么仿真器，而是真的 Emacs 直接运行在 Android 系统上，包括一切你在电脑上的 Emacs 所拥有的高级功能，例如 org-mode, magit, eww 等。Emacs 在手机上不打折!</description>
<content:encoded>&lt;p&gt;我上个月的博客有一篇关于 &lt;a href=&quot;https://blog.3qin.us/emacs_applications.html&quot;&gt;Emacs&lt;/a&gt;, 有一篇关于 &lt;a href=&quot;https://blog.3qin.us/Android_as_computer.html&quot;&gt;Android手机&lt;/a&gt;. 自然而然，会有人希望在手机上运行 Emacs, 是不是? 我当时以为不行，但其实我错了。Emacs 可以在 Android 手机上运行，而且不是 ssh 到远程主机上，不是什么简化版，不是什么仿真器，而是真的 Emacs 直接运行在 Android 系统上，包括一切你在电脑上的 Emacs 所拥有的高级功能，例如 org-mode, magit, eww 等。Emacs 在手机上不打折!&lt;/p&gt;&lt;h2&gt;Termux 终端&lt;/h2&gt;&lt;figure&gt;
&lt;img src=&quot;https://mail.3qin.us/~derek/blog_imgs/pics/phone-emacs.png&quot; alt=&quot;Emacs on phone&quot; title=&quot;&quot;/&gt;
&lt;figcaption&gt;Emacs on phone&lt;/figcaption&gt;
&lt;/figure&gt;&lt;p&gt;我说过，有没有字符界面是真电脑和假电脑的根本区别．我之前介绍过 ConnectBot，是手机上的全功能 ssh/telnet/local 终端仿真器。但手机上本地应用时各种字符界面工具不够，所以通常我只用它 ssh 到远端。下面介绍的这个应用叫 Termux，是完全针对手机本地使用的终端仿真器。它的软键盘扩展类似 ConnectBot, 但真正把 Termux 和其他终端仿真器区别开的是相当丰富的网上应用库，直接用大家熟悉的Debian系的 apt 工具可以访问! 换句话说，这是安卓上的 cygwin, 而且比 windows下的 cygwin 更好用。刚安装上app的时候它仅是一个极简系统，但我们可以:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;$ apt install make git perl emacs&lt;/code&gt;&lt;/pre&gt;&lt;figure&gt;
&lt;img src=&quot;https://mail.3qin.us/~derek/blog_imgs/pics/termux.png&quot; alt=&quot;termux&quot; title=&quot;&quot;/&gt;
&lt;figcaption&gt;termux&lt;/figcaption&gt;
&lt;/figure&gt;&lt;p&gt;然后不到200MB流量之后，这些基础软件就安装到你的手机里了。Termux 本身可以从 google play 或 f-droid 安装，而且无需 root 你的手机。如果有一天你不想用它了，卸载 app 就会把 Termux 以及你通过 apt 安装的所有软件，以及你用这个环境产生的所有文件一起清除，不留痕迹，安全环保。&lt;/p&gt;&lt;h2&gt;CPAN 及其他&lt;/h2&gt;&lt;figure&gt;
&lt;img src=&quot;https://mail.3qin.us/~derek/blog_imgs/pics/phone-cpan.png&quot; alt=&quot;cpan on phone&quot; title=&quot;&quot;/&gt;
&lt;figcaption&gt;cpan on phone&lt;/figcaption&gt;
&lt;/figure&gt;&lt;p&gt;当然，Termux 毕竟不是一个完全的 Linux Distribution，各种软件总会有些缺失。但它有 gcc 和基础库，实在不行可以自己编译。但在此之前你还有相对简单的方法安装软件。假如你所需要的软件是 perl 写的，你可以用 CPAN 来下载安装。我用 cpan 安装了 template toolkit 和 ack, 都是比较复杂的 perl 软件包，都能顺利安装成功测试通过。当然，也不仅限于 perl 和 cpan, python 上也有类似的软件发布平台 pip, ruby 和 node.js 也有类似的基础设施，这些平台都能在 Termux 上找的到，有点遗憾的是 Haskell 平台暂时还没有。CPAN 证明了一点，有了 Termux, 安卓已经是一个真的通用操作系统了。&lt;/p&gt;&lt;h2&gt;Emacs&lt;/h2&gt;&lt;figure&gt;
&lt;img src=&quot;https://mail.3qin.us/~derek/blog_imgs/pics/phone-melpa.png&quot; alt=&quot;melpa on phone&quot; title=&quot;&quot;/&gt;
&lt;figcaption&gt;melpa on phone&lt;/figcaption&gt;
&lt;/figure&gt;&lt;p&gt;Termux 已经包含 emacs 26，相当新了。其中，org-mode 和大多数你用的到的 emacs 组件都已经自带，另外，和 perl, python, ruby 等一样，emacs其实也是个编程语言以及应用发布平台。通过 emacs 自带的 melpa 平台，我们可以很轻易安装其他附加软件包，例如常用的 markdown-mode 和我之前介绍过的magit (git 前端)。安装了几个包之后，这个手机上的 emacs 已经达到了和我工作电脑上完全一致的功能。你目前看到的这份博客其实是完全在手机版 emacs 上写作完成的。而且，当你有了真的 emacs 和 git 之后，其实我上个月介绍的几个安卓应用，例如 syncorg, mgit 等对我也基本失去了意义，何必不用全功能并且和电脑一致的软件呢？&lt;/p&gt;&lt;h2&gt;用途&lt;/h2&gt;&lt;figure&gt;
&lt;img src=&quot;https://mail.3qin.us/~derek/blog_imgs/pics/phone-magit.png&quot; alt=&quot;Magit&quot; title=&quot;&quot;/&gt;
&lt;figcaption&gt;Magit&lt;/figcaption&gt;
&lt;/figure&gt;&lt;p&gt;让我再分析一下在手机上安装命令行环境，emacs 及其附加软件的意义。它带给我们很多功能，但不是所有功能都很有意义。比如，如果我愿意的话，我其实可以在手机 emacs 上读写邮件，但这恐怕不能给我带来什么价值，毕竟手机环境下有更好用的邮件客户端。在手机上用 emacs 和 git 的真正价值在于它提供了一个分布式的写作平台，而且手机环境和电脑环境完全保持一致，让我能无缝地在电脑和手机之间切换，当没有电脑或使用电脑不方便的时候可以继续写下去，而不是仅仅刷屏微信什么的。相比之下，wiki 不好用，Google doc 不能离线，用邮件把 word 文档传来传去? 还不如把我杀了。&lt;/p&gt;&lt;h2&gt;总结&lt;/h2&gt;&lt;p&gt;文字界面的历史超过我的年纪。很多人认为，文字界面不方便，不人性化，在1984年第一代 Mac 诞生的时候，苹果为了标榜革命，甚至完全去除了它的文字界面。但十几年后，Mac OSX 又加上了标准的文字界面，承认了当年的错误。Emacs 在我心中是文字界面的终极大 BOSS, 通过对文字的极致处理，衍生出种种周边功能，从而俯瞰其他编辑器。在智能手机成为现代人身体的一部分的今天，在 Termux 的帮助下，手机终于打通了关，见到了 BOSS. BOSS 其实从来未变，他一直在这里等待。&lt;/p&gt;</content:encoded>
</item>
<item>
<title>VI 和 EMACS 之争</title>
<link>https://blog.3qin.us/vi_vs_emacs.html</link>
<enclosure type="image/jpeg" length="0" url="https://mail.3qin.us/~derek/blog_imgs/pics/emacs_vs_vi.jpg"></enclosure>
<guid isPermaLink="false">9GGY1omWCHB0WZKwD3LNj8aeIMKbjiD-2GvcHg==</guid>
<pubDate>Tue, 16 Sep 2025 02:02:41 +0000</pubDate>
<description>我自己是一个忠实的 emacs用户，但在 emacs 不存在的地方也常常需要使用 vi. vi 和 emacs 之争贯穿 UNIX 和 LINUX 的几乎全部历史，不知道引起过多少口水。在21世纪的今天，有人为它们都过时了，但我觉得未必。今天我试图用尽可能中立的态度回顾一下我所知道的全部历史，不仅有一定科普意义，对自由软件从何处来，到何处去这个问题也能提供一些思考的原材料。</description>
<content:encoded>&lt;p&gt;我自己是一个忠实的 emacs用户，但在 emacs 不存在的地方也常常需要使用 vi. vi 和 emacs 之争贯穿 UNIX 和 LINUX 的几乎全部历史，不知道引起过多少口水。在21世纪的今天，有人为它们都过时了，但我觉得未必。今天我试图用尽可能中立的态度回顾一下我所知道的全部历史，不仅有一定科普意义，对自由软件从何处来，到何处去这个问题也能提供一些思考的原材料。&lt;/p&gt;&lt;h2&gt;史前时代&lt;/h2&gt;&lt;figure&gt;
&lt;img src=&quot;https://mail.3qin.us/~derek/blog_imgs/pics/emacs_vs_vi.jpg&quot; alt=&quot;Emacs vs VI&quot; title=&quot;&quot;/&gt;
&lt;figcaption&gt;Emacs vs VI&lt;/figcaption&gt;
&lt;/figure&gt;&lt;p&gt;很久很久以前，这世界上即没有 vi 也没有 emacs. 1970年带给人类 UNIX 和阴极射线管 (CRT)终端，但人机交互仅限于严格意义上的命令行，即你敲一条命令，电脑回一些结果。那程序是怎么写的呢？也是一行一行敲进去，用其他命令一行一行改。你并不能在看到多行程序上下文的情况下，移动光标到位置，然后插入或修改文字。这个一行一行敲，一行一行改文件的工具在 Unix 下叫 ed , 当然也是 unix 之父 Ken Thomson 的杰作。Ken 是一个真正的大拿，他直到后来也不是很理解，你为啥要看到程序上下文才能写程序? 不都在你脑子里吗？&lt;/p&gt;&lt;h2&gt;1976: 原始 emacs&lt;/h2&gt;&lt;p&gt;在 MIT AI 实验室有另外一个操作系统 ITS, 上面的类似 ed 的程序叫 TECO. TECO 在技术上比 ed 高级一些，它已经是一屏一屏显示，然后有一个命令行界面可以再输入命令，比如在第三行第五个字符后面插入字符串 “hello” 什么的。当然这样也不方便，但它还有一个功能，可以定义宏 (macro)，把某个命令序列绑定到一个热键上。于是许多人就写了许多宏，让 TECO 变的好用很多。机房管理员叫 Richard Stallman, 就是后来大名鼎鼎的 RMS, 他搜集整理了大家的有用的宏放在一起并持续维护，最后大家都用他的了。RMS 把这些宏的总和起了个名字: Extended MACroS，简称: emacs&lt;/p&gt;&lt;h2&gt;1977: VI&lt;/h2&gt;&lt;p&gt;在大致同时期，美国西岸的加大伯克利分校有个研究生叫Bill Joy. 伯克利是最早的 unix 使用者，Bill 也买了二手 CRT 终端拨号连到学校上机写程序。他发现， ed 太他妈难用了，于是就找出源码一阵改，改的新版叫 em, Ed for Mortals. 后来越改越来劲，并利用到终端的新特性，添加了全屏模式，新程序叫 ex. 这个程序迅速得到了同学们的一致好评，Joy 发现人人都用全屏模式，没人用保留的兼容ed的行编辑模式了，于是他再改名，叫 VIsual, 命令仍只取两个字母: vi. 随着 BSD 攻占全美大学机房，这个程序也被 AT&amp;amp;T 采纳，进入 unix 主流。&lt;/p&gt;&lt;h2&gt;1981: Goosling emacs&lt;/h2&gt;&lt;p&gt;随着 unix 的流行，ITS 逐渐式微。大家都用 unix 系统和 c语言，但不是所有人都喜欢vi。很多人怀念 emacs 的强大功能和用户可扩展性，出现了几个 emacs 克隆版本, 其中最著名的是 James Gosling 的版本。Gosling 10年之后以 JAVA 之父闻名天下，但初露头角时靠的是重写 emacs. 他的版本在技术上有不少创新:&lt;/p&gt;&lt;ol&gt;
&lt;li&gt;核心用 C 语言写就，运行在 UNIX 上&lt;/li&gt;
&lt;li&gt;主要应用逻辑用一种自带的 lisp 实现&lt;/li&gt;
&lt;li&gt;麻雀虽小，但已经有原始的 VM 和 GC&lt;/li&gt;
&lt;/ol&gt;&lt;p&gt;很快，这个版本就在学术圈流行开来，成为高端编辑器的代名词。当然， vi 的地位也无可撼动，有人形象地说:&lt;/p&gt;&lt;blockquote&gt;
&lt;p&gt;Vi is like masturbation: it is not as good as the alternative, but it is always there.&lt;/p&gt;
&lt;/blockquote&gt;&lt;h2&gt;1985: GNU&lt;/h2&gt;&lt;p&gt;RMS 在这一年重操老本行，在 Gosling 的基础上，重写了一个更强大的 lisp 引擎，整理了所有代码，作为他实现一个完全自由的操作系统 GNU 的奠基石。第一个版本就叫 GNU EMACS 13. 从技术角度而言，这个 emacs 并无太大创新，但它的政治意义非常深远。我这里提过的所有软件，从 Ken 到 Joy 到 Gosling 写的，都是开源的，但并非自由的。原因有二: 一，虽然这些软件是自发写的，但他们都有雇主，软件著作权属于雇主；二，个人开发者源码互相借鉴抄来抄去，说不清根源了，所以， AT&amp;amp;T 和其他公司的著作权在法理上难以挑战，最后这些软件的新版本连开源都做不到了。RMS 对软件权益有切身之痛，一年前就辞了职，成为完全自由职业者，gnu emacs 虽一开始基于 Gosling 版本，但不到一年的时间，彻底重写了每一行代码，而且全部著作权交给刚成立的自由软件基金会。这样，gnu emacs 成为史上第一在法理上无可辩驳的自由软件。这个版本也迅速取代了 Gosling 版的江湖地位。&lt;/p&gt;&lt;p&gt;这里再着重提一下 RMS 这个人。RMS 以圣徒自诩，人们也通常以为他是唐吉柯德式的傻瓜。从技术水平和贡献上他比不了 Ken, Joy 或 Gosling, 但他创立了自由软件基金会和 GNU 项目，并身体力行，一直以身做则，为我们今天蓬勃发展的自由软件事业奠定了基石。从这个意义上说，他比这些大拿们更伟大。&lt;/p&gt;&lt;h2&gt;1991: vim&lt;/h2&gt;&lt;p&gt;事实上今天我们用的 vi 并非 Bill Joy 的 vi，如果想体验一下老 vi 朋友可以尝试在 debian 下安装 nvi (BSD vi), 当然这也不是老 vi, 但毕竟接近的多. 老 vi 正如 RMS 所预料的一样，从开源的共享软件变成了厂家的商业软件。当 FreeBSD 要发布的时候，必须把所有和 AT&amp;amp;T 有关的代码移除，所以只能重新写了 nvi. BSD 的朋友们比较保守，整出的 nvi 和老 vi 相当接近，但另一批人就没这么多历史包袱。&lt;/p&gt;&lt;p&gt;vim 起源于 Amiga 平台，但在新兴的 Linux 平台迅速找到了自己的家。自称 vi improved，它迅速成为 linux 上最主流的 vi ，并大胆添加了语法高亮，用户程序扩展等贴近程序员使用的功能。和之前的 vi 或 emacs 不同，vim 的开发团队并无够分量的大拿坐镇，但赶上了 linux 和互联网的爆发，兼收并蓄的吸纳社区里各种贡献，虽然从软件工程学上不一定严谨，也没有什么特别值得一提的技术独创，却走进了 Linux 社区的心里，和 linux 一起在90年代病毒式扩张。同期的另几个重要软件如 apache，mysql，php 莫不如是。&lt;/p&gt;&lt;h2&gt;1992: lucid Xemacs&lt;/h2&gt;&lt;p&gt;再说 emacs 这边。90年之后，RMS 的主要精力放在社会活动上，FSF 请了新人继续开发 emacs. 但 FSF 没什么钱，光靠情怀请不到什么牛人，何况上面还有一个要求甚高的原作者 RMS 指手画脚，所以 gnu emacs 开发陷于停滞。此时有个公司 lucid 要做基于 emacs 的IDE, 自己搞了一套 lucid emacs, 主要贡献者是 Jamie Zawinski(JWZ). 此人在 lucid 94年关门后又去了 Netscape，然后又在三藩市开了个夜店 DNA Lounge, 非常值得一去。JWZ和 RMS 在技术路线上有严重分歧，自由软件早期最著名的一次分裂和骂战上演了。回头看实际上双方都是好人，但矛盾不可调和。Lucid emacs 演变成了 XEmacs, 在 GNU 体系之外独立发展。90年代中后期实际上有三大编辑器，vim, emacs 和 Xemacs.&lt;/p&gt;&lt;p&gt;Vim 在编程功能上渐渐追上来了，到96年左右实际上在程序员需要的功能上超越了 emacs。emacs 一直以来都有个劣势，就是比较慢，占内存，毕竟是基于高级语言的。当时有个说法：&lt;/p&gt;&lt;blockquote&gt;
&lt;p&gt;EMACS: Eight Megabyte And Constantly Swapping.&lt;/p&gt;
&lt;/blockquote&gt;&lt;p&gt;早期 pc linux 用户都穷，没多少内存，结果你功能还不行，所以 gnu emacs 比起 vim 就不受欢迎了。 Xemacs 倒是功能更强，但更耗资源，还有个乱臣贼子的骂名，也没有大火。&lt;/p&gt;&lt;h2&gt;2001: 新世纪&lt;/h2&gt;&lt;p&gt;2001年，xemacs 和 emacs 相继推出了 v21, vim 也推出了 6.0。编辑器功能的进化放缓，emacs 在编程功能上终于基本追上了时代，21世纪的电脑也都够快有够多内存，emacs用起来也不觉得比vim慢多少了，我自己也是大致在这段时间成为 emacs 用户的。&lt;/p&gt;&lt;p&gt;那边厢 xemacs 问题逐渐暴露出来。它其实一直没有找准定位，一个更新更潮的 emacs? 问题是真正追求新潮的人也不会去用可以追溯到1976年的软件了不是? 用 emacs 或 vi的人要的是 get the job done. 所以 xemacs 一直没有足够大的社区来好好维护这么大这么复杂的程序。它还坚持了近十年，但最近一个正式版本发布已经是十年前了。&lt;/p&gt;&lt;p&gt;但不管怎么发展，vi 和 emacs 还都坚持着自己的原则． vi 的哲学就是 unix 的哲学：每个工具做好自己的事．emacs 的哲学则更古老一点：别让贫穷束缚了你的想像．这两个哲学对立而互补，驱动着自由软件不断进步．&lt;/p&gt;&lt;h2&gt;总结&lt;/h2&gt;&lt;p&gt;vi 的历史非常平稳，在两个关键的时间节点上搭上了历史的快车．而 emacs 的历史相对就跌宕起伏了：emacs 所瞄准的目标远比 vi 的高，摔的也比 vi 狠的多．其实，vi 和 emacs 并不是敌人，而是在不同层面上互补的伙伴．大家共同的阵营叫自由软件，而对于自由软件阵营里的程序员来说，什么又比我们手中用来写代码写文档的工具更重要呢？&lt;/p&gt;</content:encoded>
</item>
<item>
<title>用 Julia 做数据分析</title>
<link>https://blog.3qin.us/data_processing_with_julia.html</link>
<enclosure type="image/jpeg" length="0" url="https://mail.3qin.us/~derek/blog_imgs/plots/julia_plot.png"></enclosure>
<guid isPermaLink="false">Zlf1hcZotnRZTze133AvJFGaSPjBQ6prSWNPmA==</guid>
<pubDate>Mon, 08 Sep 2025 05:02:18 +0000</pubDate>
<description>据说，这是个大数据的时代。当然，我们普通人接触真正大数据的机会不多，但总要学一两招数据分析，否则也不好出来见人不是。假如你有一堆数据，通常在一个CSV文件里，你需要把数据处理一下，做一些图表，找一些规律，说明一些现象，你可能会用 excel 来做这件事，这没问题。</description>
<content:encoded>&lt;p&gt;据说，这是个大数据的时代。当然，我们普通人接触真正大数据的机会不多，但总要学一两招数据分析，否则也不好出来见人不是。假如你有一堆数据，通常在一个CSV文件里，你需要把数据处理一下，做一些图表，找一些规律，说明一些现象，你可能会用 excel 来做这件事，这没问题。&lt;/p&gt;&lt;p&gt;但假如这原始数据文件有几十上百个字段，几百万行呢？傻眼了吧。&lt;/p&gt;&lt;p&gt;这时候你需要真正强悍的家伙事儿。请看: &lt;a href=&quot;https://julialang.org/&quot;&gt;Julia&lt;/a&gt;&lt;/p&gt;&lt;h2&gt;什么是Julia&lt;/h2&gt;&lt;p&gt;&lt;a href=&quot;https://julialang.org/&quot;&gt;Julia&lt;/a&gt;是最近十年内出现的新型编程语言。通俗地说，它兼具 Matlab 的科学计算功能，和 R 的统计计算功能，语法更现代化，而且&lt;strong&gt;非常快&lt;/strong&gt;. 这主要是因为：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;它是基于LLVM的编译到底执行。&lt;/li&gt;
&lt;li&gt;它是真正通用的编程环境，并不局限于计算&lt;/li&gt;
&lt;li&gt;它有相当复杂的自动并行计算功能，充分利用你电脑的多个核心&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;假如你曾用过Matlab，Octave 或 R，但不是花过大量心血，还愿意尝试新鲜事物的话，不管你是专业从事数据分析处理，还是像我一样的业余爱好者，我建议你了解一下，跟我一起开始一段简短的旅程。&lt;/p&gt;&lt;h2&gt;安装&lt;/h2&gt;&lt;p&gt;当然，第一步是安装。请从&lt;a href=&quot;https://julialang.org/downloads/&quot;&gt;官网&lt;/a&gt;下载安装。过程相当标准化，没什么好说的。然后，你就得到了一个命令行界面：&lt;/p&gt;&lt;pre&gt;&lt;code&gt;Dereks-MacBook-Pro:~ derek$ julia
               _
   _       _ _(_)_     |  Documentation: https://docs.julialang.org
  (_)     | (_) (_)    |
   _ _   _| |_  __ _   |  Type &amp;quot;?&amp;quot; for help, &amp;quot;]?&amp;quot; for Pkg help.
  | | | | | | |/ _` |  |
  | | |_| | | | (_| |  |  Version 1.5.1 (2020-08-25)
 _/ |\__&amp;#39;_|_|_|\__&amp;#39;_|  |  Official https://julialang.org/ release
|__/                   |

julia&amp;gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;你还可以尝试集成IDE &lt;a href=&quot;https://junolab.org/&quot;&gt;Juno&lt;/a&gt;, 这是一个基于 Atom 的集成环境。我大致试用了一下，还不错，但对我个人意义不是特别大。当然我不是一个典型用户，大家不妨多尝试一下。&lt;/p&gt;&lt;h2&gt;大型数据文件处理&lt;/h2&gt;&lt;p&gt;现在回到我们开始的问题。我们有一个相当大的数据文件需要处理分析。Julia直接提供了相应的程序包，就是 &lt;a href=&quot;https://juliadata.github.io/DataFrames.jl/stable/&quot;&gt;DataFrames&lt;/a&gt;, 对应复杂类型的大型数据表格处理，和 &lt;a href=&quot;https://juliadata.github.io/CSV.jl/stable/&quot;&gt;CSV&lt;/a&gt;, 负责CSV文件的读取到 DataFrame 和从 DataFrame 输出到CSV文件。这些程序包都可以在julia命令行下安装：&lt;/p&gt;&lt;pre&gt;&lt;code&gt;julia&amp;gt; using Pkg
julia&amp;gt; Pkg.add(&amp;quot;DataFrames&amp;quot;)
julia&amp;gt; Pkg.add(&amp;quot;CSV&amp;quot;)
julia&amp;gt; using DataFrames, CSV&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;一大堆安装编译的输出之后，这两个包就安装好可以用了。&lt;/p&gt;&lt;p&gt;第一步是读入我们的数据文件：&lt;/p&gt;&lt;pre&gt;&lt;code&gt;df = CSV.read(&amp;quot;/Users/derek/Downloads/Ridershare_data_triplevel_Sep2019_week1_nofilter.csv&amp;quot;)&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;简单吧。这个文件有两百万行，但十秒钟之内就读入，生成成DataFrame了：&lt;/p&gt;&lt;pre&gt;&lt;code&gt;1978890×26 DataFrame. Omitted printing of 22 columns
│ Row     │ Column1 │ Trip_ID                                  │ Trip_Day │ Is_Weekend │
│         │ Int64   │ String                                   │ String   │ Bool       │
├─────────┼─────────┼──────────────────────────────────────────┼──────────┼────────────┤
│ 1       │ 0       │ 0003eb321a18a94794a1f7953738569808fa38e5 │ Sunday   │ 1          │
│ 2       │ 3874    │ ac3456ae1d86578e2ec442ff9d4f1d980af9b2cf │ Sunday   │ 1          │
│ 3       │ 3873    │ ac30915385127ec33af27d30a92a8462d6c2c671 │ Sunday   │ 1          │
│ 4       │ 3872    │ ac2ef27a1089d302638bbe39afb5c5462fea0235 │ Sunday   │ 1          │
│ 5       │ 3871    │ ac1d012abf015bcb969e76710b3d1a29089a3a12 │ Sunday   │ 1          │&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;第二步是删掉我们不用的列。同样很简单：&lt;/p&gt;&lt;pre&gt;&lt;code&gt;df = df[:, [:Trip_Start_Timestamp, :Trip_End_Timestamp, :Pickup_Census_Tract, :Dropoff_Census_Tract]]
1978890×4 DataFrame. Omitted printing of 1 columns
│ Row     │ Trip_Start_Timestamp │ Trip_End_Timestamp     │ Pickup_Census_Tract │
│         │ String               │ String                 │ Int64?              │
├─────────┼──────────────────────┼────────────────────────┼─────────────────────┤
│ 1       │ 2019-09-01           │ 09/01/2019 12:15:00 AM │ missing             │
│ 2       │ 2019-09-01           │ 09/01/2019 12:15:00 AM │ 17031081402         │
│ 3       │ 2019-09-01           │ 09/01/2019 12:15:00 AM │ 17031071300         │
│ 4       │ 2019-09-01           │ 09/01/2019 12:15:00 AM │ 17031330100         │
│ 5       │ 2019-09-01           │ 09/01/2019 12:15:00 AM │ 17031842000         │&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;第三步是删掉数据不完整的行。原始文件通常都是有瑕疵的，需要一定的数据清洁。这在julia里非常简单：&lt;/p&gt;&lt;pre&gt;&lt;code&gt;julia&amp;gt; df = DataFrames.dropmissing(df)
1307900×4 DataFrame. Omitted printing of 1 columns
│ Row     │ Trip_Start_Timestamp │ Trip_End_Timestamp     │ Pickup_Census_Tract │
│         │ String               │ String                 │ Int64               │
├─────────┼──────────────────────┼────────────────────────┼─────────────────────┤
│ 1       │ 2019-09-01           │ 09/01/2019 12:15:00 AM │ 17031081402         │
│ 2       │ 2019-09-01           │ 09/01/2019 12:15:00 AM │ 17031071300         │
│ 3       │ 2019-09-01           │ 09/01/2019 12:15:00 AM │ 17031330100         │
│ 4       │ 2019-09-01           │ 09/01/2019 12:15:00 AM │ 17031842000         │
│ 5       │ 2019-09-01           │ 09/01/2019 12:15:00 AM │ 17031839100         │&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;第四步是对列做一定数据处理。这其实需要写一点程序，但外围就是这样的：&lt;/p&gt;&lt;pre&gt;&lt;code&gt;julia&amp;gt; df = DataFrames.select(df,
           :Trip_Start_Timestamp =&amp;gt; ByRow(ts2integer) =&amp;gt; :start,
           :Trip_Start_Timestamp =&amp;gt; ByRow(ts2integer) =&amp;gt; :end,
           :Pickup_Census_Tract =&amp;gt; :pickup,
           :Dropoff_Census_Tract =&amp;gt; :dropoff)
1307900×4 DataFrame
│ Row     │ start │ end   │ pickup      │ dropoff     │
│         │ Int64 │ Int64 │ Int64       │ Int64       │
├─────────┼───────┼───────┼─────────────┼─────────────┤
│ 1       │ 0     │ 0     │ 17031081402 │ 17031320600 │
│ 2       │ 0     │ 0     │ 17031071300 │ 17031080300 │
│ 3       │ 0     │ 0     │ 17031330100 │ 17031841100 │
│ 4       │ 0     │ 0     │ 17031842000 │ 17031063200 │
│ 5       │ 0     │ 0     │ 17031839100 │ 17031833000 │&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;以上 &lt;code&gt;ts2integer&lt;/code&gt; 函数是我自己根据数据格式和我的需要写的，这里就不贴了。&lt;/p&gt;&lt;p&gt;再往后，就是你自己的数据处理和统计分析，取决于你个人的想法。你需要最基础的画图工具包：&lt;/p&gt;&lt;pre&gt;&lt;code&gt;julia&amp;gt; Pkg.add(&amp;quot;Plots&amp;quot;)
julia&amp;gt; using Plots&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;我画的一个简单曲线如下：&lt;/p&gt;&lt;figure&gt;
&lt;img src=&quot;https://mail.3qin.us/~derek/blog_imgs/plots/julia_plot.png&quot; alt=&quot;julia plot&quot; title=&quot;&quot;/&gt;
&lt;figcaption&gt;julia plot&lt;/figcaption&gt;
&lt;/figure&gt;&lt;h2&gt;批评&lt;/h2&gt;&lt;p&gt;说了一堆优点，现在说缺点。&lt;/p&gt;&lt;h3&gt;脉络不清晰&lt;/h3&gt;&lt;p&gt;实话说，我看了这两天，Julia 语法的脉络我还没摸出来。Julia 既可以当 OOP 语言用，也可以当 FP 语言用，但二者都只能做到八成。这也是可以理解的，毕竟 OOP 和 FP &lt;a href=&quot;https://blog.3qin.us/oop_and_fp.html&quot;&gt;不能共存&lt;/a&gt;. 我感觉它太过求全求大，所以难以找到脉络。我个人学东西总希望先找到核心思想，再用核心思想去套细节，但在这里可能还要依赖于盲人摸象式学习。&lt;/p&gt;&lt;h3&gt;文档无重点&lt;/h3&gt;&lt;p&gt;Julia 在线文档不少，但可惜的是缺乏主次之分。好的文档能让新手上来不用全部看过就先能用上，解决一些简单问题。细节可以过后细细研究。但 Julia 的核心库文档还是以堆砌事实为主。更由于上一条本来脉络就不是很清晰，一些很简单的事情我在偌大文档里也难以找到答案，不得已借助谷歌搜索或 Stack Overflow 来寻求答案。在这点上，我前一段主力学习的 &lt;a href=&quot;https://elixir-lang.org/&quot;&gt;elixir&lt;/a&gt; 文档就好的多。&lt;/p&gt;&lt;h2&gt;总结&lt;/h2&gt;&lt;p&gt;Julia 已经不是新生事物。它已经有八年的历史，成熟的社区，和一个相当擅长的领域。从高阶来看， Matlab和 R 的 99% 的使用场景都可以被取代；从低阶应用来说，使用 Python 等通用脚本语言来做数值计算和统计分析也变得没有实际意义了。&lt;/p&gt;&lt;p&gt;Julia 是 100% 的自由软件。普通人，用普通家用电脑，已经可以做 GB 级别相当复杂的数据分析，只要你愿意花功夫。&lt;/p&gt;&lt;p&gt;颤抖吧，凡人。专业和业余的鸿沟正在消失。&lt;/p&gt;</content:encoded>
</item>
<item>
<title>个人通信手段</title>
<link>https://blog.3qin.us/communication_choices.html</link>
<enclosure type="image/jpeg" length="0" url="https://mail.3qin.us/~derek/blog_imgs/pics/plankton.jpg"></enclosure>
<guid isPermaLink="false">nUR5ulELp5_3TYVAGarrWEKHmeCJQzxWgbSmJw==</guid>
<pubDate>Sun, 07 Sep 2025 22:23:02 +0000</pubDate>
<description>在我前一段时间的 文章 我批评了微信作为个人通信工具的种种缺点。那不用微信，还有什么好用的呢？本文调查了目前公开发行的各种实时通信工具，主要考量是对隐私的尊重。</description>
<content:encoded>&lt;p&gt;在我前一段时间的&lt;a href=&quot;https://blog.3qin.us/weixin_7_sins.html&quot;&gt;文章&lt;/a&gt;我批评了微信作为个人通信工具的种种缺点。那不用微信，还有什么好用的呢？本文调查了目前公开发行的各种实时通信工具，主要考量是对隐私的尊重。&lt;/p&gt;&lt;h2&gt;移动实时通信&lt;/h2&gt;&lt;p&gt;移动实时通信的定义是可以自行建立点到点的信道，在信道中发送消息不管到世界各地哪里的延时均小于一秒。这就排除了电子邮件，BBS留言版等应用。另外一个重要的要求是普世性，比方说我在我自己服务器上安装的应用，就算开放，实时，也不能算，因为用户覆盖面不够。同理，各种企业内部聊天工具如XMPP，钉钉，slack，MS Team也不能算。通信最基本的要求是文字短消息，然后再高级是语音留言，实时语音通信，实时视频通信等。信息可以群发，但这里我不要求聊天室似的的多人实时互动，群聊我以后再专门调查。&lt;/p&gt;&lt;p&gt;对于实时通信的隐私来说，很重要的一点就是端到端的加密。这个意思是信息从你手机出来就已经加密，然后无论中间种种转发，直到对方手机上都原样不变，然后在接收端手机本地解密。只有这样，你和通信的对方才能保证这个信息第一没有被偷窥，第二没有被篡改。假如没有端到端加密，仅有部分信道加密，那么你们之间的所有人都是潜在的偷窥者，截获者，记录者，篡改者。&lt;/p&gt;&lt;h2&gt;Facebook Messenger&lt;/h2&gt;&lt;p&gt;Facebook在全球的用户数量可能不比微信少，Facebook Messenger也是包罗万象的工具包含聊天功能。但是，Facebook的对用户隐私保护的历史记录也不怎么样。作为一种社交网络，Facebook最重要的资产就是掌握用户信息，包括社交图，地理位置，爱好取向等等，你在这里发的任何一条消息对facebook来说都是潜在的金矿。当然，facebook不提供端到端加密的功能，何必自缚手脚呢？&lt;/p&gt;&lt;h2&gt;Whatsapp&lt;/h2&gt;&lt;p&gt;Whatsapp现在也属于Facebook旗下一员。但是，在facebook收购之前，whatsapp已经有海量的忠实用户，收购后，whatsapp又加持了不少和fackbook互动的功能，但仍然保持一定的独立性，包括一直保持着的端到端加密的功能。whatsapp端到端加密算法在网上能找到的资料不多，应该没有经过安全工作者做缜密的代码审核。另外，如果在手机上同时安装whatsapp和facebook的话，两个客户端软件存在广泛的数据共享。从这点来看，这端到端加密也不是很保险，因为从手机这个端点就有漏洞。所以我的建议是：使用WhatsApp 的话，不要在同一台手机上安装任何facebook客户端软件。&lt;/p&gt;&lt;p&gt;还有一个问题，就是whatsapp在中国大陆受屏蔽。这不是whatsapp的责任，但毕竟影响其使用范围。&lt;/p&gt;&lt;h2&gt;Telegram&lt;/h2&gt;&lt;p&gt;Telegram是独立运营的通信工具。客户端软件经过第三方安全工作者独立审核。支持端到端加密，但缺省没有打开。在打开端到端加密的情况下无法群聊，只能群发。这也是合理的，群聊情况下，端到端加密存在技术难点，其有效性也值得疑问。&lt;/p&gt;&lt;p&gt;在不打开端到端加密的情况下，如果通过Telegram分享网页链接，Telegram的服务器会自动访问这个链接，它访问虽有其正当理由，如生成社交链接小图片，或者对对方做一些有害网站的及时提醒，但这仍然是侵犯了通信隐私。毕竟我发的链接只和通信双方有关，和Telegram没关系。和Whatsapp相比，Whasapp会在发送端本地访问链接，本地生成社交链接小图片然后发给对方。在这个角度下，Telegram做的不如Whatsapp好。&lt;/p&gt;&lt;p&gt;还有一个问题，就是Telegram的商业模式感觉无法持续。Telegram提供相当丰富的功能，包含视频一应俱全，消耗的资源不小。它一不收费，二不收集用户信息转卖，是如何持续商业运营的呢？情怀不能当饭吃啊。&lt;/p&gt;&lt;p&gt;当然，Telegram在中国大陆也受屏蔽。&lt;/p&gt;&lt;h2&gt;Signal&lt;/h2&gt;&lt;p&gt;Signal是当前最严格保护客户隐私的通信工具，所有源代码经过第三方专业审核。端到端加密想关都关不掉。为了保持加密的有效性，它甚至牺牲了不小的功能：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;没有社交链接缩略图功能。&lt;/li&gt;
&lt;li&gt;没有群聊。群聊难以做到端到端加密。&lt;/li&gt;
&lt;li&gt;没有网页版。必须使用客户端。这个原因是网页版软件无法在客户端做签名认证。&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;&lt;strong&gt;更新&lt;/strong&gt;：Signal支持群聊，而且群聊也是端到端加密的。但是群没有群主，成员只能自行退群。Signal也支持社交链接缩略图，但仅限几个网站如youtube等。&lt;/p&gt;&lt;p&gt;在端到端加密的基础上，Signal甚至可以提供匿名投递。这个意思是即使有端到端加密，平台运营商作为信息的传递者，至少知道了双方在这个时间点有信息交换这回事，这也是隐私信息的一部分。匿名投递的意思是发送方在不登录的情况下直接发信息，Signal完全不知信息从何而来，接收方收到信息本地解开才知道信息从谁处发来。这个功能目前只有Signal有。&lt;/p&gt;&lt;p&gt;Signal同样支持语音甚至视频通信。可以WebRTC直连，也可以经Signal服务器转发。WebRTC直连超出大多数用户技术能力，毕竟种种防火墙难以打通。转发的话目前效果还行，但是未来存疑。Signal是非盈利机构运营，资源毕竟有限。如果人人都开视频的话，我估计很快就垮了。&lt;/p&gt;&lt;p&gt;据说，目前在中国大陆注册Signal用户的过程需要翻墙，但使用无需翻墙。这点我没有验证，还请读者帮忙。&lt;/p&gt;&lt;h2&gt;短信／电话&lt;/h2&gt;&lt;p&gt;最后，我还要说最古老的移动通信手段，就是发短信，打电话。当然，这也没有端到端加密，所以也是不安全的。但是，和同样没有端到端加密的微信或Facebook相比，短信，电话，走运营商专用网络，你只需要担心运营商和政府。用微信／Facebook messager的情况下，你还要额外担心腾讯／Facebook。它们作为技术强大，商业能力强悍的大公司，和呆滞僵化的运营商比起来，其动手脚的能力强的不是一星半点。何况，微信等走公众IP网络，又没有强大的端到端加密保护，中间所有人都存在插一脚的可能。在这里我建议使用微信的时候不要用wifi，连你自己家的wifi都不要用。&lt;/p&gt;&lt;p&gt;还有一个费用问题。毕竟微信不要钱。但是请这么想：以中国大陆一条短信一毛钱人民币来举例，你一天发一百条，才十块钱人民币。如果你一天想发更多短信的话，我觉得钱还不是最重要的，你是不是要要再考虑一下你的人生规划了？&lt;/p&gt;&lt;p&gt;最后，短信／电话的最大好处我还没有提，就是人人都有，中国大陆也不屏蔽。&lt;/p&gt;&lt;h2&gt;总结&lt;/h2&gt;&lt;p&gt;我希望大家优先选择短信／电话作为最主要的移动通信手段。部分隐私敏感的消息，请使用有端到端加密的Signal，Telegram，Whatsapp（本机卸载Facebook情况下），三者排名分先后。一定要用微信或Facebook的话，请关wifi。&lt;/p&gt;&lt;figure&gt;
&lt;img src=&quot;https://mail.3qin.us/~derek/blog_imgs/pics/plankton.jpg&quot; alt=&quot;Who will join me?&quot; title=&quot;&quot;/&gt;
&lt;figcaption&gt;Who will join me?&lt;/figcaption&gt;
&lt;/figure&gt;&lt;blockquote&gt;
&lt;p&gt;FELICITATIONS, MALEFACTORS! I AM ENDEAVORING TO MISAPPROPPRIATE THE FORMULARY FOR THE PREPARATION OF AFFORDABLE COMESTIBLES! WHO WILL JOIN ME?!?! – Plankton&lt;/p&gt;
&lt;/blockquote&gt;</content:encoded>
</item>
<item>
<title>Emacs新应用</title>
<link>https://blog.3qin.us/emacs_applications.html</link>
<enclosure type="image/jpeg" length="0" url="https://mail.3qin.us/~derek/blog_imgs/pics/eww.png"></enclosure>
<guid isPermaLink="false">mlGYkBGVARSuUqCkacvTJWidj7pUGY_hshbbOA==</guid>
<pubDate>Sun, 07 Sep 2025 22:02:20 +0000</pubDate>
<description>Emacs作为一个面向程序员的编辑器，已是久负盛名。但正如巴塞罗那不仅是一家俱乐部，微信不仅是一个通信工具，Emacs也不仅是一个编辑器，而其实是一个应用平台，有着丰富的第三方应用。下面我介绍一下最近几年比较热门的一些应用。</description>
<content:encoded>&lt;p&gt;Emacs作为一个面向程序员的编辑器，已是久负盛名。但正如巴塞罗那不仅是一家俱乐部，微信不仅是一个通信工具，Emacs也不仅是一个编辑器，而其实是一个应用平台，有着丰富的第三方应用。下面我介绍一下最近几年比较热门的一些应用。&lt;/p&gt;&lt;h2&gt;浏览器EWW&lt;/h2&gt;&lt;figure&gt;
&lt;img src=&quot;https://mail.3qin.us/~derek/blog_imgs/pics/eww.png&quot; alt=&quot;EWW&quot; title=&quot;&quot;/&gt;
&lt;figcaption&gt;EWW&lt;/figcaption&gt;
&lt;/figure&gt;&lt;p&gt;用emacs浏览网页可能是疯了。要知道浏览器是目前最复杂的客户端应用，连微软都搞不定，emacs在一个文字界面上能搞出什么名堂? 说老实话，我个人经常在文字界面上使用浏览器，主要是阅读一些API文档，或者程序自动生成的html报告日志什么的。在这些情况下，可以在文字界面下快速浏览是一件很有意义的事情：这时候也不需要JavaScript或图片什么的，要的就是能快速打开，搜索和跳转。我曾经用过lynx和w3m, 在emacs内也曾用过其他方案，都比不上w3m好用．但是，emacs里最新的浏览器组件EWW在速度和兼容性上已经达到或超过了w3m的水平，而且在emacs内部可以借助其强大的文字表现和搜索功能，完美的实现了有限的文字html浏览。大家不妨一试。&lt;/p&gt;&lt;h2&gt;邮件客户端mu4e&lt;/h2&gt;&lt;figure&gt;
&lt;img src=&quot;https://mail.3qin.us/~derek/blog_imgs/pics/mu4e.png&quot; alt=&quot;mu4e&quot; title=&quot;&quot;/&gt;
&lt;figcaption&gt;mu4e&lt;/figcaption&gt;
&lt;/figure&gt;&lt;p&gt;Emacs可以读邮件至少有二十多年的历史了。mu4e已经是我自己用过的第四种emacs内置邮件客户端，但在前三次尝试中，我最后总是回到mutt。题外话夸一下mutt, 和它的前身pine一起，真的是历史上最杰出的文字界面邮件客户端，可以轻松应对每天几百封邮件狂轰滥炸．但我用过mu4e之后，已经渐渐不再使用mutt了．为什么？&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;mu4e 在基础邮件客户端功能上已经很逼近mutt了&lt;/li&gt;
&lt;li&gt;mu4e 使用了和 EWW 一样的 emacs 内建 shr 引擎来表现 html 邮件，渲染速度超越了 mutt + w3m&lt;/li&gt;
&lt;li&gt;mu4e 是完全基于搜索的，类似 gmail, 或命令行下的 notmuch. 比起常规邮件客户端它更适合当今海量邮件的现状．&lt;/li&gt;
&lt;li&gt;最后，mu4e 和其他邮件客户端做到了完美共生．不管文字界面多出色，你总会需要用到图形界面客户端，webmail和手机客户端的，对不对？&lt;/li&gt;
&lt;/ul&gt;&lt;h2&gt;git客户端magit&lt;/h2&gt;&lt;figure&gt;
&lt;img src=&quot;https://mail.3qin.us/~derek/blog_imgs/pics/magit.png&quot; alt=&quot;magit&quot; title=&quot;&quot;/&gt;
&lt;figcaption&gt;magit&lt;/figcaption&gt;
&lt;/figure&gt;&lt;p&gt;现在所有程序员都要用git. 但我之前有一点小小的偏见，认为各种封装后的 git 客户端都是给菜鸟用的，是阉割版，傻瓜版，用了跌份，直到 magit 扭转了我的偏见．其实 magit 也不是第一种 emacs 下的集成 git 客户端，但之前的种种源于更早的 RCS/CVS 系统界面的改造，用起来总是感觉怪怪的，而 magit 应该是第一种完完全全为 git 开发的 emacs 客户端，不仅适合菜鸟，也适合进阶用户：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;magit 和emacs内其他组件，例如ediff完美结合，提供更方便一致的用户界面&lt;/li&gt;
&lt;li&gt;magit 提供可探索的用户界面，老git用户例如我，甚至学到了以前不知道的窍门&lt;/li&gt;
&lt;li&gt;magit 并不屏蔽原生git命令界面，你能清楚知道它要做什么，做了什么，也不会久而久之不会用git命令行了&lt;/li&gt;
&lt;/ul&gt;&lt;h2&gt;org-mode&lt;/h2&gt;&lt;p&gt;把 org-mode 放在这里我其实有点犹豫．一是因为 org-mode 历史长的多，十几年了，另一个原因是很难定义 org-mode 究竟是什么．但如果不讲 org-mode 又感觉对不住大家，毕竟这是 emacs 近10年最牛的应用，没有之一．从某个角度来讲，org-mode是 emacs 里的 emacs, 它什么都能做，还可以进一步扩展．它可以用来写文档，写程序，做项目规划，做展示胶片，做电子表格，做网站，还有手机客户端．下面我从几个方面简述一下：&lt;/p&gt;&lt;h3&gt;个人项目管理&lt;/h3&gt;&lt;figure&gt;
&lt;img src=&quot;https://mail.3qin.us/~derek/blog_imgs/pics/org_mode.png&quot; alt=&quot;org-mode&quot; title=&quot;&quot;/&gt;
&lt;figcaption&gt;org-mode&lt;/figcaption&gt;
&lt;/figure&gt;&lt;p&gt;这是 org-mode 的初衷，stay organized. 用 org-mode 你可以记笔记，列待处理事项, 生成日程表，让你在千头万绪的日常工作生活中不会迷失线索，忘记事情．尤其是对于我这种已经整天对着 emacs 看的，又容易忘事情的人特别有用，相当于一个高效的数字助理在你的指尖．&lt;/p&gt;&lt;h3&gt;结构写作&lt;/h3&gt;&lt;p&gt;由于 org-mode 的强大功能和文字表现能力，很多人也把它当作通用写作平台．你可以把它理解成 word + excel + powerpoint: org-mode 能让你做结构性写作和表格演算，并通过 html 或 latex 后端生成专业级别输出．坦率地说我自己其实还没有习惯这么做，个人还是偏好于使用 markdown + pandoc 来做这类事情．&lt;/p&gt;&lt;h3&gt;文学编程&lt;/h3&gt;&lt;p&gt;英文原文是 Literate Programming, 我可能翻译的不好．这个概念是把注释嵌在代码里这种常见编程模式反过来，把代码片段嵌套在文档之中，运用 org-mode 强大的结构写作功能和可扩展的后处理能力，实现一套源文件，一边生成专业级文档，一边生成程序．目前看来在学术界或数据分析行业用的比较多，我暂时还没有这方面需求．&lt;/p&gt;&lt;h2&gt;总结&lt;/h2&gt;&lt;p&gt;我一开始说过，Emacs其实是一个应用平台．在 &lt;a href=&quot;http://www.melpa.org&quot;&gt;http://www.melpa.org&lt;/a&gt; 上目前列了4051个安装包, 全都可以在emacs内部一键式安装．当然，大多数应用不独特，也比不上其他平台上的类似应用．但是，这些应用中不乏亮点，除了我列出来的这几个之外，还有不少等待我去发掘．应该说，这是一个相当成熟健康的生态系统．Emacs在快40岁的年纪仍然生机勃勃，这是自由软件才能创造的奇迹．&lt;/p&gt;&lt;blockquote&gt;
&lt;p&gt;Vi is like masturbation: It is not as good as the alternative but is always there.
– Annonymous commentor&lt;/p&gt;
&lt;/blockquote&gt;</content:encoded>
</item>
<item>
<title>如何在吐槽俱乐部上发主贴</title>
<link>https://blog.3qin.us/primary_post_on_roastidious.html</link>
<enclosure type="image/jpeg" length="0" url="https://mail.3qin.us/~derek/blog_imgs/pics/derek.jpg"></enclosure>
<guid isPermaLink="false">_LDXJVXVvs3pie5ehFewj3KAe4Rcisr2Zu__rQ==</guid>
<pubDate>Sat, 06 Sep 2025 03:17:39 +0000</pubDate>
<description>吐槽俱乐部 可以让你对任意网页链接都可以发表评论。有一些朋友问可不可以在吐槽俱乐部里发主贴。就是说，没有原始链接，直接发贴可不可以呢？</description>
<content:encoded>&lt;p&gt;&lt;a href=&quot;https://roastidio.us/&quot;&gt;吐槽俱乐部&lt;/a&gt; 可以让你对任意网页链接都可以发表评论。有一些朋友问可不可以在吐槽俱乐部里发主贴。就是说，没有原始链接，直接发贴可不可以呢？&lt;/p&gt;&lt;h2&gt;吐槽俱乐部的限制&lt;/h2&gt;&lt;p&gt;吐槽俱乐部依赖一个外部链接来建立话题的上下文。所以说在这里凭空发贴，就是发主贴，是不可以的。其实，发主贴在技术上的难度并不大，但是，我故意搞这么一个限制是有其目的的。首先，在我的观念里，主贴总是需要文字多一点，否则不成了微博推特了吗？要码这么多字，一般人都会想在一个自主可控的地方写吧，所以我希望大家&lt;a href=&quot;https://blog.3qin.us/hosted_blogging_platforms.html&quot;&gt;自建的博客&lt;/a&gt; 。再者，吐槽俱乐部完全自由发言，假如又能发主贴的话，那么我作为网站的运行者，可能对用户发贴的内容还要负一定连带责任，怕麻烦的我当然能躲就躲。&lt;/p&gt;&lt;p&gt;但我也理解对于用户，不设立博客，直接发贴确实省却不少麻烦。理论上不可以的事情，其实也是可以做到的，但要利用到另一个我建立的可以随意发言的网站，这就是&lt;a href=&quot;https://gara.fly.dev/&quot;&gt;还不去开房GARA&lt;/a&gt;.&lt;/p&gt;&lt;h2&gt;还不去开房&lt;/h2&gt;&lt;p&gt;还不去开房GARA 我之前&lt;a href=&quot;https://blog.3qin.us/get_a_room_already.html&quot;&gt;介绍过&lt;/a&gt;，它提供一个完全匿名，不留痕迹的网上聊天室。聊天室有两种，一种是私有的，链接动态生成，必须别人把链接分享给你，链接例如：&lt;code&gt;https://gara.fly.dev/room/rg_cGyNH&lt;/code&gt;, 注意链接最后的八位密码。另一种聊天室是公开的，假如你的话题形如一个URL：&lt;code&gt;https://...&lt;/code&gt; 则所有输入同一个话题URL的用户都会被引导到同一个聊天室里。&lt;/p&gt;&lt;p&gt;聊天无需登录，聊完之后，等最后一个人退出的时候，所有记录删除，不留痕迹。所以说在这里也是无法长期留言，并公诸于众的。所以单靠这里也实现不了发贴的功能。但是，请注意两点：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;最后一个人离开聊天室的时候聊天室不是立刻关闭，而是有一分钟左右的延时保留。这是防止用户误操作，一不小心把房间关了，所有记录删除再也找不回来。&lt;/li&gt;
&lt;li&gt;聊天室本身也是一个网页，本网页当然也可以被吐槽。在吐槽的那一刹那，吐槽俱乐部会抓取网页内容保存，也就是保存了当前的聊天记录，&lt;strong&gt;这不就是相当于发贴了吗？&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;GARA 还有一个贴心功能：假如你在浏览器地址栏输入GARA网络主机内的任意地址，只要不是GARA网站自用的地址，GARA就自动生成关于这个话题URL的公开聊天室。例如：&lt;a href=&quot;https://gara.fly.dev/zz&quot;&gt;https://gara.fly.dev/zz&lt;/a&gt; 就是一个公开聊天室。和其他公开聊天室有一点区别，由于它的话题URL在本站内部，所以链接是被确认过的，吐槽这样的聊天室会把聊天室的动态链接例如：&lt;code&gt;https://gara.fly.dev/room/rg_cGyNH&lt;/code&gt; 再重定向回公开链接 &lt;code&gt;https://gara.fly.dev/zz&lt;/code&gt;, 这样链接更方便易记，省却剪贴一些乱码的麻烦。&lt;/p&gt;&lt;h2&gt;发贴攻略&lt;/h2&gt;&lt;p&gt;第一步，在浏览器地址栏里输入GARA内的任意地址，最好你能记住的。例如：&lt;code&gt;https://gara.fly.dev/zz&lt;/code&gt; 网页打开后你就在一个只有你一个人的聊天室里，面对一个文本框。在这里你可以写任何文字，并支持简略的markdown语法。你也可以发多段文字，这样的效果有点类似Twitter thread，完全随你。&lt;/p&gt;&lt;p&gt;第二步，到吐槽俱乐部吐槽本聊天室。假如你安装了吐槽俱乐部的&lt;a href=&quot;https://roastidio.us/rules#quick_start&quot;&gt;书签工具&lt;/a&gt; 的话，这只不过是点一个按钮的事。吐槽俱乐部会抓取网页文字，保留到吐槽俱乐部的数据库里。记住，在吐槽俱乐部点话题进来是不加载全文的，请点击标题加载全文。&lt;/p&gt;&lt;p&gt;然后就完了。原来的聊天室就算关闭了，你的聊天记录在GARA会被清除，但在吐槽俱乐部上的话题页会被保留。你可以再转发，请别人评论，或自己读自己的，谁也不打扰，一切随你。你也可以自己发评论评论自己，发评论的时候可以用hash tag做标记例如：“#有趣的事”，这样你或别人方便找回。&lt;/p&gt;&lt;h2&gt;方案弱点&lt;/h2&gt;&lt;p&gt;这种发贴方案也有自己的弱点。第一，吐槽俱乐部不永久保留的网页内容，你的发贴一般就存活一年左右。第二，吐槽俱乐部只抓文字，不抓图片，所以你上传的图片或文件附件在聊天室关闭之后就点不开了。最后一点也是最重要的一点，GARA没有用户这个概念，所有内部公开话题链接链接对所有人都是可以用的，一个人发贴之后，另一个人可以用同一个链接重新发贴，就把之前的内容冲掉了。你也可以用私有聊天室发贴，这样就不会有地址冲突了，你的内容不会被冲掉，包括自己也改不了了。&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://roastidio.us/&quot;&gt;吐槽俱乐部&lt;/a&gt; 和&lt;a href=&quot;https://gara.fly.dev/&quot;&gt;还不去开房GARA&lt;/a&gt; 这两个网站虽然都是我搞的，但是其实内部毫无关联，以上介绍的网站间互动其实都是web1.0时代就有的功能，不过是超文本链接而已。&lt;/p&gt;&lt;blockquote&gt;
&lt;p&gt;Do One Thing and Do It Well. —- The Unix philosophy&lt;/p&gt;
&lt;/blockquote&gt;&lt;p&gt;现在业界的趋势和这个正相反，争取把所有功能做在一个超级App里，但我一是做不到，二是不喜欢。你呢？&lt;/p&gt;</content:encoded>
</item>
<item>
<title>如何记笔记</title>
<link>https://blog.3qin.us/zettle_krasten.html</link>
<enclosure type="image/jpeg" length="0" url="https://mail.3qin.us/~derek/blog_imgs/pics/zettle.jpg"></enclosure>
<guid isPermaLink="false">EkFIAbWa9YXs_3-usfm3mk8z_HOqtdlAm6juEw==</guid>
<pubDate>Sat, 06 Sep 2025 02:54:02 +0000</pubDate>
<description>我年轻的时候从不记笔记。这不外乎两个原因：年轻记性好，而且没那么多东西要记。待到年纪渐长，终于意识到我迟早有一天会老年痴呆的。怎么办呢？哈利波特粉丝应该对第四集这个场景有印象：</description>
<content:encoded>&lt;p&gt;我年轻的时候从不记笔记。这不外乎两个原因：年轻记性好，而且没那么多东西要记。待到年纪渐长，终于意识到我迟早有一天会老年痴呆的。怎么办呢？哈利波特粉丝应该对第四集这个场景有印象：&lt;/p&gt;&lt;blockquote&gt;
&lt;p&gt;I sometimes find, and I am sure you know the feeling, that I simply have too many thoughts and memories crammed into my mind. —- Dumbledore to Harry&lt;/p&gt;
&lt;/blockquote&gt;&lt;p&gt;我们没有魔法盆，只好记笔记。但我之前记而不得其法，丢失的很多，未丢的也杂乱无法整理。直到前不久我了解到记笔记的不二法门，今天来跟大家分享。&lt;/p&gt;&lt;h2&gt;Zettelkästen&lt;/h2&gt;&lt;p&gt;Zettelkästen 是德语，意思是卡片盒。网上有很多资料，比如它的&lt;a href=&quot;https://zettelkasten.de/&quot;&gt;官网&lt;/a&gt;. 发明者叫 Niklas Luhmann, 是上世纪的一位相当学术高产的德国社会学家。他花了大半辈子，用卡片作笔记，最终留下近十万张卡片，装满了几个大箱子。这是其中的一张：&lt;/p&gt;&lt;figure&gt;
&lt;img src=&quot;https://mail.3qin.us/~derek/blog_imgs/pics/zettle.jpg&quot; alt=&quot;Luhmann’s zettel&quot; title=&quot;&quot;/&gt;
&lt;figcaption&gt;Luhmann’s zettel&lt;/figcaption&gt;
&lt;/figure&gt;&lt;p&gt;你或者说，用卡片记也是记，用笔记本记也是记，用电脑也是记，除了这家伙够有毅力之外，他的方法还能有什么特殊？有的。&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;能坚持几十年的方法，一定不是让人痛苦的。你的方法呢？&lt;/li&gt;
&lt;li&gt;记是一方面，想找的时候还要找的着。不用说几十年，你能快速找到去年你记的笔记某一页吗？&lt;/li&gt;
&lt;li&gt;你一个人无聊待着的时候，会主动翻阅自己过去的笔记，从而获得新的思路新的想法吗？&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;所以，请和我一起探索一下卡片盒方法的独到之处吧。&lt;/p&gt;&lt;h3&gt;篇幅&lt;/h3&gt;&lt;p&gt;用卡片记笔记能有效限制篇幅。笔记不是文章，是给自己看的，无需写的文采飞扬。一张卡片，就记一件事情，一个点子，一个发现。一句话不嫌短，但最长不要超过一百个单词，中文不超过两百字。另一件事情就另起一张卡片。把每件事情都试图写的独立一点，每张卡片独立都能让多年以后的自己重新理解。&lt;/p&gt;&lt;h3&gt;组织&lt;/h3&gt;&lt;figure&gt;
&lt;img src=&quot;https://mail.3qin.us/~derek/blog_imgs/plots/card_tree.svg&quot; alt=&quot;card tree&quot; title=&quot;&quot;/&gt;
&lt;figcaption&gt;card tree&lt;/figcaption&gt;
&lt;/figure&gt;&lt;p&gt;卡片放在盒子里，按序排放。但这个序既不是时间顺序，也不是分类顺序，而是你思路的顺序。人的思路肯定不是线性的，而是不停的在分支，更接近一颗树的样子。学软件的应该比较熟悉。今天思路断在这里，可能很长一段时间都不去管，但将来某年某月说不定又有想法，就把卡片再插在这里，重新开始。相比之下，笔记本就限制过多了。&lt;/p&gt;&lt;h3&gt;固化&lt;/h3&gt;&lt;p&gt;不要扔卡片，尽量不要修改卡片。假如你以前认为地球是平的，后来改变了看法，不要去试图修改历史，让自己显得伟大光荣正确，就原地接一张卡片，说自己想法变了就好。之前想法种种，不管多错误，毕竟是你自己思维的一部分，自己写自己看，何必不对自己忠实。历史不应修改，最多渐渐忘记。我们记笔记，不就是让忘记的速度再慢一点。&lt;/p&gt;&lt;h3&gt;单份&lt;/h3&gt;&lt;p&gt;一个人应该只有一个卡片盒。虽然，把工作，生活分开可能有一定道理，但说到底，你只有一个大脑，精神分裂者除外。你的卡片盒不过是你大脑的外挂，不应该再细分范畴。当然，你可以，也应该在卡片上作标签，类似推特的 #tag 一样，以便查询。但这个分类不是固化的，也不是互斥的。一张卡片可以有多个标签。&lt;/p&gt;&lt;h2&gt;我的方法&lt;/h2&gt;&lt;p&gt;最正宗的 Zettelkästen 用的是纸质卡片。但在这个数字信息化的时代，我作为软件工作者，必然使用数字化方法。数字化的好处这里不再详述，但也是有坏处的。最大的坏处是表达不够丰富，用笔可以画画，在电脑里我只会写文字。好在我浑身上下无半点艺术细胞，这点坏处对我来说问题不大。下面讲的是我自己的方法，与原方法略有区别，还请大家注意分辨。我想，每个人具体情况都有所不同，一定程度的订制是必要的。&lt;/p&gt;&lt;h3&gt;我的卡片&lt;/h3&gt;&lt;p&gt;我用 &lt;a href=&quot;https://en.wikipedia.org/wiki/Markdown&quot;&gt;markdown&lt;/a&gt; 格式记录笔记，一张卡片对应一个文件。文件可能分一个到几个小节，每节相当于幻灯胶片排版比较疏松的一页，篇幅类似于原版的 Zettelkästen. 纸质卡片有两面，我的数字卡片可能有更多“面”，即更多小节，但我目前还维持一节到两节。两节的好处是可以表达问题／回答，理论／例子这样的组织结构，对于某些笔记是很有用的。多面卡片我建议尽量不用，而最好分拆成多张卡片。&lt;/p&gt;&lt;h3&gt;卡片的组织&lt;/h3&gt;&lt;p&gt;我所有卡片文件放在一个目录里，不分子目录。我的文件名不包含内容信息，而只是时间戳。但是，我在卡片之外维护一个索引文件，在索引内实现两个功能：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;树的组织&lt;/li&gt;
&lt;li&gt;标签&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;懂点数据库知识的人应该可以理解我的做法的好处。但我用的不是数据库工具，而是 &lt;a href=&quot;https://orgmode.org/&quot;&gt;emacs org-mode&lt;/a&gt; 来组织我的索引文件。org-mode提供非常完备的结构化编辑一个树的方法，同时可以给树的每一个节点加标签，正好是我需要的，而且我本来就一天到晚在emacs里。你应该可以选择你最喜欢的工具，但做选择前，请考虑一下：记笔记是一辈子的事情，你选择的工具能存在多长时间呢？&lt;/p&gt;&lt;h3&gt;卡片的呈现&lt;/h3&gt;&lt;figure&gt;
&lt;img src=&quot;https://mail.3qin.us/~derek/blog_imgs/pics/card_pensieve.png&quot; alt=&quot;card: pensieve&quot; title=&quot;&quot;/&gt;
&lt;figcaption&gt;card: pensieve&lt;/figcaption&gt;
&lt;/figure&gt;&lt;p&gt;虽然我可以一直在emacs环境里写卡片，查卡片，对卡片树重新组织，给卡片打标签，到这个地步其实我还不需写一行代码。但是，一个更方便，更直观的方法来翻阅卡片是非常有必要的。现在人都有很多碎片时间，例如茶余饭后，等人等车的时候，与其掏出手机刷抖音，还不如掏出手机刷自己的卡片。到这个地步这就要写一点代码了。目前我已经实现了：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;把卡片转换成html文件，通过浏览器方便浏览&lt;/li&gt;
&lt;li&gt;一个全屏网页界面，在手机上可以通过手指上下左右滑动来遍历我的卡片树&lt;/li&gt;
&lt;li&gt;根据主题标签细分，来生成一个稀疏树，便于同主题浏览&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;刚好我的单张卡片篇幅不大，在手机全屏情况下阅读正合适。&lt;/p&gt;&lt;h2&gt;结束语&lt;/h2&gt;&lt;p&gt;Luhmann 教授一辈子写了十万张卡片，我才刚上路，还不到一百，且看我最终能写多少。&lt;/p&gt;&lt;blockquote&gt;
&lt;p&gt;Never send a human to do a machine’s job. – Agent Smith&lt;/p&gt;
&lt;/blockquote&gt;&lt;p&gt;尤其别委屈自己。&lt;/p&gt;</content:encoded>
</item>
<item>
<title>手机应用还是信息监狱？</title>
<link>https://blog.3qin.us/apps_or_prisons.html</link>
<enclosure type="image/jpeg" length="0" url="https://mail.3qin.us/~derek/blog_imgs/pics/baidu_mobile_web.jpeg"></enclosure>
<guid isPermaLink="false">TrEtBhWmE5ni30fnxE6YL89Vz6nDBpyrodyMlQ==</guid>
<pubDate>Fri, 05 Sep 2025 04:53:47 +0000</pubDate>
<description>读过我 向手机应用说不 一文的朋友们应该了解我对手机 app 的态度：99% 的手机应用都是无理取闹。但是，我对手机本身是没有什么负面态度的。智能手机和随处可见的数据网络大大加强了这个时代人类的连通性，确实为我们带来了很多的便利。如果不用 99% 的 app, 只用手机浏览器，我们是否还能享受智能手机的大多数便利呢？为缩小讨论范围，我这里把应用缩小到适用于 PC ...</description>
<content:encoded>&lt;p&gt;读过我&lt;a href=&quot;https://blog.3qin.us/say_no_to_app.html&quot;&gt;向手机应用说不&lt;/a&gt;一文的朋友们应该了解我对手机 app 的态度：99% 的手机应用都是无理取闹。但是，我对手机本身是没有什么负面态度的。智能手机和随处可见的数据网络大大加强了这个时代人类的连通性，确实为我们带来了很多的便利。如果不用 99% 的 app, 只用手机浏览器，我们是否还能享受智能手机的大多数便利呢？为缩小讨论范围，我这里把应用缩小到适用于 PC 端浏览器的网页应用范畴，主要是阅读和音视频类信息接收。这也是手机应用的一大领域。&lt;/p&gt;&lt;h2&gt;手机网络世界&lt;/h2&gt;&lt;p&gt;用手机浏览器，在中文网络世界基本寸步难行。&lt;/p&gt;&lt;h3&gt;百度&lt;/h3&gt;&lt;figure&gt;
&lt;img src=&quot;https://mail.3qin.us/~derek/blog_imgs/pics/baidu_mobile_web.jpeg&quot; alt=&quot;百度&quot; title=&quot;&quot;/&gt;
&lt;figcaption&gt;百度&lt;/figcaption&gt;
&lt;/figure&gt;&lt;h3&gt;知乎&lt;/h3&gt;&lt;figure&gt;
&lt;img src=&quot;https://mail.3qin.us/~derek/blog_imgs/pics/zhihu_mobile_web.jpeg&quot; alt=&quot;知乎&quot; title=&quot;&quot;/&gt;
&lt;figcaption&gt;知乎&lt;/figcaption&gt;
&lt;/figure&gt;&lt;h3&gt;虎扑论坛&lt;/h3&gt;&lt;figure&gt;
&lt;img src=&quot;https://mail.3qin.us/~derek/blog_imgs/pics/hupu_mobile_web.jpeg&quot; alt=&quot;hupu&quot; title=&quot;&quot;/&gt;
&lt;figcaption&gt;hupu&lt;/figcaption&gt;
&lt;/figure&gt;&lt;h3&gt;小结&lt;/h3&gt;&lt;p&gt;以上三个网站在 PC 端都是相当可用的，但到了移动端，它们都无时不刻试图诱使你下载移动 app, 甚至用户界面故意做成你会一不小心点错跳转到下载界面的样子。我浏览了一段时间之后只好放弃，再也不在手机上访问这些网站了。&lt;/p&gt;&lt;p&gt;英文网站这个情况也存在，但没有这么严重。&lt;/p&gt;&lt;h3&gt;Reddit&lt;/h3&gt;&lt;figure&gt;
&lt;img src=&quot;https://mail.3qin.us/~derek/blog_imgs/pics/reddit_mobile_web.jpeg&quot; alt=&quot;Reddit&quot; title=&quot;&quot;/&gt;
&lt;figcaption&gt;Reddit&lt;/figcaption&gt;
&lt;/figure&gt;&lt;h3&gt;Washington Post&lt;/h3&gt;&lt;figure&gt;
&lt;img src=&quot;https://mail.3qin.us/~derek/blog_imgs/pics/washington_post_mobile_web.jpeg&quot; alt=&quot;Washington Post&quot; title=&quot;&quot;/&gt;
&lt;figcaption&gt;Washington Post&lt;/figcaption&gt;
&lt;/figure&gt;&lt;h3&gt;小结&lt;/h3&gt;&lt;p&gt;这些英文网站在手机上基本可以正常使用，虽然也有提示下载 app 什么的，但容易拒绝，不给我带来过多烦恼。&lt;/p&gt;&lt;h2&gt;它们想干吗？&lt;/h2&gt;&lt;p&gt;在明面上，它们的理由是手机 app 能提供比网页更好的用户体验。这貌似正确，但值不得推敲：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;手机界面最大的问题是屏幕小。但手机 app 也无法克服这个问题呀。何况，我用10寸安卓平板访问各种网站，它们还是会各种提示下载 app&lt;/li&gt;
&lt;li&gt;以上我选的应用都是不需要过度用户交互的，常规 app 上能用的用户界面手段，网页照样做的到。其实这些网站也已经做到了。所以说，并不存在必须使用手机 app 不可的用户体验问题。&lt;/li&gt;
&lt;li&gt;手机网页界面上最严重的用户体验问题，恰恰是人为的，就是这些随处可见，试图诱导你下载 app 的提示本身！&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;所以说， “手机 app 能提供比网页更好的用户体验” 是一个循环论证。手机网页版其实可以做的够好，但是服务商们偏不，更有甚者，它们故意往不好的角度去做，其目的就是把用户往 app 上去带！这件事的核心理由并不是从用户角度出发的，而是从应用提供商角度出发的。联系到我之前&lt;a href=&quot;https://blog.3qin.us/say_no_to_app.html&quot;&gt;向手机应用说不&lt;/a&gt;一文，很简单，在手机 app 上有更大变现的可能。钱不是从天上掉下来的，所以，羊毛一定出在猪身上，这猪就是受蒙蔽，被洗脑的用户们。&lt;/p&gt;&lt;p&gt;当然，以上这些应用，至少在 pc 端还是可以通过浏览器使用的。现在还有不少应用压根就没有网页访问的可能，例如微信，今日头条等。它们彻底放弃了不那么挣钱的网页用户，一心一意地向手机 app 用户提供 “免费” 的服务，即使冒着被苹果，谷歌，和政府政策强制应用下架的风险也在所不辞。这里猪们如果没有足够的利润空间，这些厂商是不可能做活雷锋的。&lt;/p&gt;&lt;h2&gt;互不联网？&lt;/h2&gt;&lt;p&gt;在传统互联网的时代，每份信息的标示是链接，你只要有链接，就能顺藤摸瓜，跨越多个服务商来寻找根源。到了移动互联网时代，链接已经没有意义了，实际上已经成了互不联网。每个服务商都推自己的 app, 试图把用户抓在自己的手心里，不让自己的有价值信息，其中大多数还是用户创造出来的，让别人自由访问，就算想付费访问也不行。这篇文章&lt;a href=&quot;https://jhuo.ca/post/the_old_internet_is_end/&quot;&gt;互联网完蛋了，已经。&lt;/a&gt; 写自2017 年，讲的是同一件事，说的比我深，内容在今天仍然有效。&lt;/p&gt;&lt;p&gt;我个人仅在迫不得已的情况下使用手机 app. 在有可能的情况下，我会尽可能使用网页版应用。关于这篇文章，我自己其实有一个矛盾心理，这是因为估计各种服务商在我身上挣不到什么钱，但我确享受了互联网，和移动互联网的大部分红利。我这种人能逍遥在外，主要靠的是大多数天真用户，即所谓的猪们，为服务商提供利润。但是：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;如果大多数用户醒悟过来，像我这样谨慎使用各种应用的话，服务商挣不到钱，服务下线，所有人，包括我在内也就享受不了了&lt;/li&gt;
&lt;li&gt;如果用户都被服务商彻底洗脑，一心一意用 app 的话，服务商也就不需要再在乎我这类异端，而变成纯 app 访问模式，那我也逍遥不下去了&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;任何真相都值得了解。每个人都只能为自己打算，但最好是了解了真相之后。&lt;/p&gt;</content:encoded>
</item>
<item>
<title>吐槽俱乐部</title>
<link>https://blog.3qin.us/roastidious.html</link>
<enclosure type="image/jpeg" length="0" url="https://mail.3qin.us/~derek/blog_imgs/pics/roastidious_screen_shot.png"></enclosure>
<guid isPermaLink="false">uaoCsOeLtbzl9b3GxgoCJQCBv53AQM4Tr8RbvA==</guid>
<pubDate>Mon, 01 Sep 2025 06:10:19 +0000</pubDate>
<description>我的初衷是为我的博客做一个留言板。但是我又想，为什么不为所有人的博客做一个免费使用，尊重隐私和言论自由的留言板呢？然后我再想，为什么要局限于博客，而不是开放给所有人，能对所有对公众开放的网页留下你的评论，并且看到别人的评论，然后再进一步评论下去呢？</description>
<content:encoded>&lt;p&gt;我的初衷是为我的博客做一个留言板。但是我又想，为什么不为所有人的博客做一个免费使用，尊重隐私和言论自由的留言板呢？然后我再想，为什么要局限于博客，而不是开放给所有人，能对所有对公众开放的网页留下你的评论，并且看到别人的评论，然后再进一步评论下去呢？&lt;/p&gt;&lt;p&gt;于是，&lt;a href=&quot;https://roastidio.us&quot;&gt;吐槽俱乐部&lt;/a&gt;诞生了。&lt;/p&gt;&lt;h2&gt;留言板？&lt;/h2&gt;&lt;p&gt;留言板的作用主要是互动，让读者和作者互动，读者和读者之间互动。但是，拥有一个好的留言板并不容易。目前的解决方案主要是两种：&lt;/p&gt;&lt;ol&gt;
&lt;li&gt;使用博客平台自己的留言板&lt;/li&gt;
&lt;li&gt;使用第三方的留言板服务&lt;/li&gt;
&lt;/ol&gt;&lt;p&gt;方案一的问题是不够开放。你博客的读者未必是本平台的注册用户。而且平台为了防范恶意攻击，散发广告，灌水等行为必然采取一些限制措施，而这些限制措施常常使读者觉得过于繁琐，导致本来想留言的人最后很可能就不了了之。对于我的博客来说，由于我并没有使用任何公共博客平台，所以本来也就不可能。&lt;/p&gt;&lt;p&gt;方案二是指在你的博客内嵌入第三方提供的代码，从而集成留言服务。提供商包括&lt;a href=&quot;https://disqus.com/&quot;&gt;Discus&lt;/a&gt;等等。这些服务通常比常规博客平台的留言板功能做的强大，都会有一定的信用审查等功能，防止恶意灌水，同时又方便读者使用。但是问题也有：广告或付费，你只能二选一。在你博客网页上内嵌代码，有安全和隐私问题，最后，在中国大陆互联网生态下，它最终必然被屏蔽。Discus已经被屏蔽了。&lt;/p&gt;&lt;p&gt;如果不考虑钱的问题，现有留言板主要的困境是：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;尊重隐私和聚集人气的两难&lt;/li&gt;
&lt;li&gt;言论自由和维护气氛的两难&lt;/li&gt;
&lt;/ul&gt;&lt;figure&gt;
&lt;img src=&quot;https://mail.3qin.us/~derek/blog_imgs/pics/roastidious_screen_shot.png&quot; alt=&quot;roastidio.us&quot; title=&quot;&quot;/&gt;
&lt;figcaption&gt;roastidio.us&lt;/figcaption&gt;
&lt;/figure&gt;&lt;p&gt;读过我前文&lt;a href=&quot;https://blog.3qin.us/middle_ground.html&quot;&gt;温和派的困境&lt;/a&gt;的朋友应该了解，人间的最大问题是正反馈，富者愈富，穷者愈穷。在网上社区的反应就是网红的博客被恶意灌水，普通人的博客无人问津。假如有一个负反馈系统，这些问题就都不存在了。当然，没有正反馈，就不会聚集人气，也就不可能挣钱，但是我不在乎。且看在一个负反馈的游戏规则下，这个俱乐部能发展到什么地步。&lt;/p&gt;&lt;h2&gt;俱乐部的宗旨&lt;/h2&gt;&lt;h3&gt;信息安全&lt;/h3&gt;&lt;p&gt;吐槽俱乐部其实也是一个第三方网络服务。但和其他第三方留言板服务不同，它不需要做javascript 代码嵌入，而只能链接访问。留言并不能直接展示在博主的网页上。从缺点来说，博主无法向访客展示人气。但我也就不可能在博主网页上打广告，或者盗取流量信息等。&lt;/p&gt;&lt;p&gt;从评论者的角度来说，虽然你必须是俱乐部的注册用户才能发表评论，但本网站只需要用一个邮箱地址就可以注册，而且不向用户索取任何个人信息，包括用户名，密码等。你的邮箱地址也不会向任何人展示。在俱乐部里你甚至没有名字，只有一个由你控制的头像。大家不知道你是谁，也不在乎你是谁。你说的话不比任何人有份量，也不比任何人没份量。话的份量来自于你说的话有没有道理，而不是来自身份。&lt;/p&gt;&lt;h3&gt;言论自由&lt;/h3&gt;&lt;p&gt;作为用户，你可以任意发表评论。这里没有政治正确，也没有新闻审查，反正别人不知道你是谁，最多对你不理不睬，或者奋勇反击。但你既然敢说，就应该有被反击的心理准备不是？你可能会觉得这里会变成硝烟弥漫的战场，但其实不会。这里和社交媒体不同，最大的区别是没有旁观者，或者说不鼓励围观。网上吵架其实都是吵给别人看的，没有人围观，还吵的起来吗？&lt;/p&gt;&lt;p&gt;当然，你的言论自由不能侵犯别人的领域。你可以随便写，但别人没义务看，而且你也不能频繁骚扰别人。假如你对我吐槽，我不喜欢，我也不能删你的帖子。但是，被吐槽的人有权利对第三方屏蔽你的发言。这里的每个帖子都是独立控制的领域，谁的地盘谁做主。&lt;/p&gt;&lt;h3&gt;自力更生&lt;/h3&gt;&lt;p&gt;这里没有推荐排行，没有热搜，没有流量统计。热门与否，跟我无关。如果想看点人云亦云的东西，还是回到社交媒体吧。我刚才说过，这里没有正反馈。每个人都有自己的信息获取渠道，社交媒体也罢，草根论坛也好，吐槽俱乐部只接收吐槽，不提供槽点。&lt;/p&gt;&lt;p&gt;不推荐，不灌输的宗旨甚至包括你或别人发表在吐槽俱乐部的言论。这里不是发表平台，所有帖子都不会自动向任何访问者展示。想看帖，你必须自己发言，然后就能看到槽友的帖子了。先奉献，再索取，不是吗？何况大家一起吐槽过一个东西，才会有共同语言，要不然你怎么知道不是鸡同鸭讲？&lt;/p&gt;&lt;h2&gt;结束语&lt;/h2&gt;&lt;p&gt;这只是一个开始。吐槽俱乐部不适合所有人，但至少适合我。2021年，我希望自己能更主动搜集各种信息，而不是被动接收填鸭。我希望自己能更主动发表言论，其中系统一点，光明正大一点的写在博客里，而碎片一点，临时动念的写在吐槽里。而且我要做一些相关的软件工具和平台，分享给大家。在这年关将近的时候，也是给自己立一个旗子吧。&lt;/p&gt;&lt;p&gt;吐槽俱乐部的详细游戏规则在&lt;a href=&quot;https://roastidio.us/rules&quot;&gt;这里&lt;/a&gt;&lt;/p&gt;&lt;p&gt;吐槽俱乐部的专用博客在&lt;a href=&quot;https://blog.roastidio.us/&quot;&gt;这里&lt;/a&gt;&lt;/p&gt;</content:encoded>
</item>
<item>
<title>总统选举重新计票的探讨</title>
<link>https://blog.3qin.us/election_recount.html</link>
<enclosure type="image/jpeg" length="0" url="https://mail.3qin.us/~derek/blog_imgs/pics/derek.jpg"></enclosure>
<guid isPermaLink="false">r_a4modZLobnrL5YwnbE8kfGEYAH8Onl6RetVg==</guid>
<pubDate>Sat, 30 Aug 2025 21:03:16 +0000</pubDate>
<description>这两天美国总统选举扣人心弦，在多个州都出现了两个候选人票数相当接近的情况。根据选举法律，当双方票差小于1%的时候，一方可以要求重新计票。在2000年小布什对戈尔的时候，在佛罗里达州就出现了这种情况。今年很有可能多个州都会票差小于1%，我估计双方都会要求重新计票。有鉴于此，让我们先用数学探讨一下重新计票究竟有没有用，翻盘的概率能有多少。</description>
<content:encoded>&lt;p&gt;这两天美国总统选举扣人心弦，在多个州都出现了两个候选人票数相当接近的情况。根据选举法律，当双方票差小于1%的时候，一方可以要求重新计票。在2000年小布什对戈尔的时候，在佛罗里达州就出现了这种情况。今年很有可能多个州都会票差小于1%，我估计双方都会要求重新计票。有鉴于此，让我们先用数学探讨一下重新计票究竟有没有用，翻盘的概率能有多少。&lt;/p&gt;&lt;h2&gt;统计模型&lt;/h2&gt;&lt;p&gt;为简化起见，我先排除第三方候选人的所得票数，毕竟本来也不多，就1%～2%。假定如下：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;本州有N个选民，N/2选共和党候选人(R), N/2选民主党候选人(D)。&lt;/li&gt;
&lt;li&gt;由于工作人员失误，每张选票都有小概率计错，把R计成D，或者把D计成R。&lt;/li&gt;
&lt;li&gt;每张选票计错的概率分布为独立同分布，(IID)&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;假如我们把R选票当作0，D选票当作1，则那N/2个本来选R的选票将成二元随机分布，以1-p的概率为0，p的概率为1. 它们的和 (SumR) 也是一个随机分布. 由于样本足够多，根据 &lt;a href=&quot;https://en.wikipedia.org/wiki/Central_limit_theorem&quot;&gt;中心极限定理&lt;/a&gt;, 它将是一个正态分布，由两个统计特征决定：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;数学期望: &lt;code&gt;μ = N/2*((1-p)*0 + p * 1) = pN/2&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;方差：&lt;code&gt;σ2 = N/2*((1-p)*p*p + p*(1-p)*(1-p)) = p(1-p)N/2&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;同理，N/2个本来选D的选票也成二元随机分布，它们的和 (SumD) 也是一个正态随机分布，&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;数学期望: &lt;code&gt;μ = N/2*((1-p)*1 + p * 0) = (1-p)N/2&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;方差：&lt;code&gt;σ2 = N/2*((1-p)*p*p + p*(1-p)*(1-p)) = p(1-p)N/2&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;那两个和的和当然也是正态随机分布：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;数学期望: &lt;code&gt;μ = (1-p)N/2 + pN/2 = N/2&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;方差：&lt;code&gt;σ2 = p(1-p)N/2 + p(1-p)N/2 = p(1-p)N&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;所以说，虽然每张票有错误可能，但总和的数学期望仍然是N/2，和p无关。但是总和会有随机性，不一定是N/2了，上下会有所浮动，这个浮动和p紧密相关，p越大，浮动范围就越大。&lt;/p&gt;&lt;h2&gt;假说验证&lt;/h2&gt;&lt;p&gt;在数理统计中常用的分析方法是&lt;a href=&quot;https://en.wikipedia.org/wiki/Statistical_hypothesis_testing&quot;&gt;假说验证&lt;/a&gt;。你会有两种互补的假设：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;原始假设(Null hypothesis), 即原来的普遍认知&lt;/li&gt;
&lt;li&gt;新假设(Alternative hypothesis), 即你提出的新主张&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;这个分析方法是这样的：你先假定NH是对的，并用这为起点计算你的到的实验数据的概率。假如你得到的概率足够小，例如小于1%, 我们就可以推翻NH，从而证明AH。&lt;/p&gt;&lt;p&gt;我们以当前已经出的最接近的Wisconsin结果为例：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;Biden 得票1,630,541&lt;/li&gt;
&lt;li&gt;Trump 得票1,610,007&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;双方得票非常接近，只差20534票，占总票数(3,240,548)的千分之六，符合重新计票的前提。会不会由于工作人员失误，导致本来Trump赢得局面变成Biden赢的局面？好，让我们来验证一下。&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;NH：D &amp;lt;= N/2&lt;/li&gt;
&lt;li&gt;AH: D &amp;gt; N/2&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;这即所谓单边假说验证。在单边假说验证的时候，我们选取对AH最有利的NH情况，就是D = N/2。延续以上模型，把R选票当作0，D选票当作1，所以说，Sum的的数学期望是N/2，即1,620,274, 但统计结果是1,630,541, 偏了10,267票。我们根据这个偏差认为Biden赢了，会不会有问题？计票可能有错误的，不是吗？&lt;/p&gt;&lt;p&gt;我们先假定计票错误概率为 &lt;code&gt;p = 0.01&lt;/code&gt;, 即百分之一出错率。貌似有点合理。&lt;/p&gt;&lt;p&gt;现在我们计算方差。&lt;code&gt;σ2 = p(1-p)N = 32081.4252&lt;/code&gt;, 所以：&lt;code&gt;σ = sqrt(p(1-p)N) = 179&lt;/code&gt;&lt;/p&gt;&lt;p&gt;所以统计结果偏了 &lt;code&gt;10267/179 = 57&lt;/code&gt; 倍σ，这在统计上是天文数字。单边概率无限接近于零，所以NH一定错，AH一定对，Biden虽然只赢了千分之六，但这在统计上已经是铁证如山！&lt;/p&gt;&lt;p&gt;会不会我们高估了Wisconsin工作人员的能力，他们其实出错率比1%高的多呢？好，我们姑且假定出错概率不是1%, 而是10%。这已经是草菅人命型出错概率了，应该算够放得开吧。&lt;/p&gt;&lt;p&gt;&lt;code&gt;σ2 = p(1-p)N = 291649.32&lt;/code&gt;, 所以：&lt;code&gt;σ = sqrt(p(1-p)N) = 540&lt;/code&gt;&lt;/p&gt;&lt;p&gt;所以统计结果偏了 &lt;code&gt;10267/540 = 19&lt;/code&gt; 倍σ，这在统计上仍然是天文数字。单边概率无限接近于零，之前结论仍然成立。&lt;/p&gt;&lt;h2&gt;2000年的Florida&lt;/h2&gt;&lt;p&gt;我们翻出有史以来最接近的一次选举，就是2000年的Florida，Bush vs Gore。&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;Bush得票2,912,790&lt;/li&gt;
&lt;li&gt;Gore得票2,912,253&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;双方仅差537票！代入以上公式：&lt;/p&gt;&lt;p&gt;&lt;code&gt;N = 5825043, N/2 = 2912521.5&lt;/code&gt; 实际票数统计偏了 268.5&lt;/p&gt;&lt;p&gt;假定p = 0.1, 则：&lt;/p&gt;&lt;p&gt;&lt;code&gt;σ = sqrt(p(1-p)N) = 724&lt;/code&gt;&lt;/p&gt;&lt;p&gt;偏的只有 0.37倍σ, 单边概率35.6%，我们当然无法排除Gore获胜的可能性。即使我们假定 p = 0.01, σ 还是有240. 偏差还是只有一个多σ，单边概率13.2%，不能排除。所以，2000年的Florida，Gore 真的有可能赢了。&lt;/p&gt;&lt;p&gt;注意，以上两个概率并非Gore赢的概率，而是假定Gore打平，获得当前如此偏差数据的条件概率。我们只能说Gore赢面还是小于50%, 但不能忽略。&lt;/p&gt;&lt;h2&gt;回到当下&lt;/h2&gt;&lt;p&gt;目前看来，Wisconsin未必是最接近的一个州。且看能否破掉2000年Florida的历史记录吧。从我的数学模型来看，至少Wisconsin是铁案。用通俗的话说，在百万级别选票统计中，对单个选票统计正确性的要求其实相当低。当然，以上模型假定两边出错概率一致，这未必是对的。只要有任何系统性偏差，也就是有舞弊现象，则所有结论作废。&lt;/p&gt;&lt;p&gt;本文仅使用了基础数理统计，理工类或经济类大学课程想必都有包括。但多年不用，大家可能都生疏了。&lt;/p&gt;</content:encoded>
</item>
<item>
<title>LIV: 我自己的网页邮箱</title>
<link>https://blog.3qin.us/living_in_email.html</link>
<enclosure type="image/jpeg" length="0" url="https://mail.3qin.us/~derek/blog_imgs/pics/liv_mail_wide.png"></enclosure>
<guid isPermaLink="false">FKyCZ3QOvOTafAv7sMdvz-WeBf_tN_QN8N_sTA==</guid>
<pubDate>Fri, 29 Aug 2025 12:56:59 +0000</pubDate>
<description>年初的时候我写过一篇 我的电子邮件处理流程 ，详细描述了我是如何处理我自己的邮件的。简单的说，我主要是利用字符终端工具来浏览，回复邮件，从而达到高效，省时，安全的目的。但是，字符终端总有时候不尽如人意：很多邮件都是基于HTML的超文本邮件，在字符终端工具下展示总是欠缺。何况，有不少时候我还需要点击邮件中的链接，进入网页应用，在字符终端下...</description>
<content:encoded>&lt;p&gt;年初的时候我写过一篇&lt;a href=&quot;https://blog.3qin.us/email_flow.html&quot;&gt;我的电子邮件处理流程&lt;/a&gt;，详细描述了我是如何处理我自己的邮件的。简单的说，我主要是利用字符终端工具来浏览，回复邮件，从而达到高效，省时，安全的目的。但是，字符终端总有时候不尽如人意：很多邮件都是基于HTML的超文本邮件，在字符终端工具下展示总是欠缺。何况，有不少时候我还需要点击邮件中的链接，进入网页应用，在字符终端下基本上所有的网页应用都是打不开的。所以，我还是需要一个网页版邮箱。读过我&lt;a href=&quot;https://blog.3qin.us/the_real_email.html&quot;&gt;你有电子邮件邮箱吗？&lt;/a&gt;一文的朋友知道我为什么不愿意用Gmail之类的应用，而要自己搭建邮件服务器。那么，在自己的邮件服务器上，能不能实现类似Gmail的功能呢？&lt;/p&gt;&lt;h2&gt;现有的开源工具&lt;/h2&gt;&lt;p&gt;我曾经使用过两种开源网页邮箱工具，都是可以安装到自己的服务器上的。一个叫&lt;a href=&quot;https://www.sogo.nu/&quot;&gt;Sogo&lt;/a&gt;, 一个叫&lt;a href=&quot;https://roundcube.net/&quot;&gt;roundcube&lt;/a&gt;. 这两个软件包都可以在自建的邮件服务器上实现网页邮箱功能，其功能接近常见基于IMAP的邮件软件例如Thunderbird. 但是，我用了一段时间后都闲置不用，而重新回到字符终端工具了，即使字符工具有上述种种不便。这是因为这两个应用都是在IMAP上再包装的一层，所以：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;IMAP做不到的事情，它们也做不到。例如有索引的全文检索&lt;/li&gt;
&lt;li&gt;IMAP做的到的事情，它们才有可能做得到，但只可能更慢&lt;/li&gt;
&lt;li&gt;它们在设计上面向一个小型机构，服务于几十上百用户。而我只需要服务几个用户，主要是我自己，再加上我的家人，所以有不匹配的感觉&lt;/li&gt;
&lt;/ul&gt;&lt;figure&gt;
&lt;img src=&quot;https://mail.3qin.us/~derek/blog_imgs/pics/liv_mail_wide.png&quot; alt=&quot;web mail&quot; title=&quot;&quot;/&gt;
&lt;figcaption&gt;web mail&lt;/figcaption&gt;
&lt;/figure&gt;&lt;p&gt;我逐渐意识到，类似Gmail之类的云端邮件应用相当不简单。邮件这个应用虽然很古老，但是和其他网页版应用相比，要求其实很高：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;邮件是数据量相当大的应用。我邮箱里有7万封邮件，数据量超过几个G。这个应用必须和相当大的数据有紧密联系。&lt;/li&gt;
&lt;li&gt;邮件是和用户交互比较复杂的应用。假如点个什么按钮都要等个半秒一秒，你的耐心很快会被消耗殆尽的。&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;在一个网页应用的范畴下，数据在服务器端，交互在客户端，这就形成了一个两难：假如主要逻辑在服务器端，客户端通过HTTP请求与服务器端则会造成不可忽视的交互延迟，导致用户体验不好。假如使用类似React之类的前端框架，把逻辑功能尽量往前端迁移，则和后端的数据有带宽和距离上的割裂，这样就是一个相当复杂的分布式系统，一些重型数据应用，例如全文检索就不容易实现。&lt;/p&gt;&lt;p&gt;那么还有什么办法？&lt;/p&gt;&lt;h2&gt;Phoenix LiveView&lt;/h2&gt;&lt;p&gt;&lt;a href=&quot;https://www.phoenixframework.org/&quot;&gt;Phoenix LiveView&lt;/a&gt;是近几年涌现出来的新型网页应用框架。它是一个后端框架，但绕过了相对比较慢的无状态HTTP协议，而使用长时，有状态的WebSocket协议，使得客户端和服务器端的专有进程深度绑定，从而大大削减了交互延时。对于上述的邮件应用非常适合：所有应用逻辑运行在服务器端，和数据零距离，访问无阻碍。后端通过一个有状态的WebSocket连接和轻量的网页前端进行频繁交互，即时反馈加超文本邮件展示没问题！&lt;/p&gt;&lt;figure&gt;
&lt;img src=&quot;https://mail.3qin.us/~derek/blog_imgs/pics/liv_write_wide.png&quot; alt=&quot;compose&quot; title=&quot;&quot;/&gt;
&lt;figcaption&gt;compose&lt;/figcaption&gt;
&lt;/figure&gt;&lt;p&gt;问题只有一个，就是没有现成应用。自由软件的世界里，没有枪没有炮，我自己造！我的应用栈分三层：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;搜索引擎。这一层是现有的：&lt;a href=&quot;https://github.com/djcb/mu&quot;&gt;mu: Maildir Utility&lt;/a&gt;. 我常用的字符终端工具 &lt;code&gt;mu4e&lt;/code&gt; 即是基于此。&lt;/li&gt;
&lt;li&gt;我在&lt;code&gt;mu&lt;/code&gt; 的基础上封装一层，实现一个Erlang API，并补充一些mu没有的功能，把独享的&lt;code&gt;mu&lt;/code&gt;界面改造成可共享界面。这一层我管它叫&lt;a href=&quot;https://github.com/derek-zhou/maildir_commander&quot;&gt;mc: Maildir Commander&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;最上层的网页应用基于Phoenix LiveView + &lt;a href=&quot;https://surface-ui.org/&quot;&gt;Surface&lt;/a&gt;，用Elixir实现。这一层叫&lt;a href=&quot;https://github.com/derek-zhou/liv&quot;&gt;LIV: Live Inbox View&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;&lt;code&gt;mc&lt;/code&gt; 和&lt;code&gt;liv&lt;/code&gt; 是站在自由软件巨人们肩膀上开发的，它们自然也是自由软件。&lt;/p&gt;&lt;h2&gt;LIV&lt;/h2&gt;&lt;figure&gt;
&lt;img src=&quot;https://mail.3qin.us/~derek/blog_imgs/pics/liv_box_wide.png&quot; alt=&quot;threading&quot; title=&quot;&quot;/&gt;
&lt;figcaption&gt;threading&lt;/figcaption&gt;
&lt;/figure&gt;&lt;p&gt;LIV才刚刚发布，只实现了我最需要的基本功能，目前只能认为是一个MVP (Minimum Viable Product):&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;只有一种邮件列表方式，就是按线索，时间倒序排列&lt;/li&gt;
&lt;li&gt;不能删除邮件。这是因为我是用脚本&lt;a href=&quot;https://blog.3qin.us/email_flow.html&quot;&gt;自动删除无用邮件的&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;不能打开附件，写邮件也不能加附件。我对附件不太感冒&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;但是，LIV有其独特的功能，你在其他任何地方都找不到：&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;每封邮件，每个查询，都可以添加到浏览器标准书签&lt;/li&gt;
&lt;li&gt;用线索智能展示邮件，即使在一个很窄的手机屏幕都可以用&lt;/li&gt;
&lt;li&gt;使用Markdown格式来写邮件，并做即时HTML渲染&lt;/li&gt;
&lt;/ul&gt;&lt;figure&gt;
&lt;img src=&quot;https://mail.3qin.us/~derek/blog_imgs/pics/liv_box_narrow.png&quot; alt=&quot;phone view&quot; title=&quot;&quot;/&gt;
&lt;figcaption&gt;phone view&lt;/figcaption&gt;
&lt;/figure&gt;&lt;p&gt;在家庭宽带+WiFi环境下，LIV使用如丝般顺滑。如果使用LTE网络，则会略感延迟，但不会比Gmail差。我自己已经是95%以上的时间使用LIV阅读回复邮件了。当然，LIV的目的不是100%取代字符终端邮件工具，而是与之共存。毕竟在字符终端上，使用快捷键定制操作其效率是网页应用比不了的。&lt;/p&gt;&lt;p&gt;LIV现在没多少文档，也暂时不太适合终端用户使用。如果你像我一样，自己运行自己的邮件服务器，并且不怕自己编译安装软件的话，不妨一试。我期待收到你的反馈！&lt;/p&gt;</content:encoded>
</item>
</channel>
</rss>
