首页  >  All categories  >  Posts

体验新的RSS阅读器Follow

很早就关注到 diygod 在开发新的RSS阅读器,鉴于日常受益于 RSSHub,非常期待。今天凌晨两点运气不错蹲到了邀请码,先体验一下同时 claim 本博客。

This message is used to verify that this feed (feedId:48039983835900953) belongs to me (userId:43235607612881920). Join me in enjoying RSS on the next generation information browser https://follow.is.

浏览器自动补全 A to Z 看上网习惯

响应 椒盐豆豉 的问卷调查,从 A 到 Z,浏览器给的第一个推荐都是什么?以下是我的结果:

  • A - api.wogong.net/ LLM时代到来后,几乎所有境外的服务在中国大陆都不可达,因此利用 one-api 搭建了这个中转站,用来给身边朋友和自己的一些第三方APP使用。
  • B - bbs.hupu.com/lol 因为看 LOL 比赛,一直在这个分区看看帖子,早几年还有账户参与讨论,最近几年只读模式,毕竟这种论坛都是回合制,输出或者反击都是无意义的事,别带脑子来这里。
  • C - colab.research.google.com 很早很早就知道Google 的这个在线 notebook 服务,但是一直没怎么用,毕竟我有本地环境为什么要用这个呢?后来计算设备变得多起来,各处的 ipynb 文件也不好归档整理,散落在各个项目里。再说本地开一个不是还得找到对应的 python 环境,偶尔还受 poor network 拖累慢吞吞拖包,索性不需要显卡的都放到 colab 上了,主打一个打开浏览器就能使用。
  • D - douban.com 书影音标记,虽然数次叛逃,以及最近几年的数据也不全面了(本地 Obsidian 是最全的应该),但是查看书籍、电影介绍和评价还得是豆瓣。
  • E - easychair.org 最近一个会议的投稿网站,E开头的网站好像真不多?
  • F - freshrss.wogong.net 自己部署的RSS阅读器,之前用的miniflux,后来迁移到 freshrss,每日必开的网站了。
  • G - github.com 居然不是Google?应该是因为 Google 的搜索都直接在搜索栏解决了,GitHub 当之无愧。
  • H - hltv.org CS2 赛事数据网站,对的,我不仅看 LOL 比赛还看 CS2.
  • I - instapaper.com 老牌的 Read it later 网站,界面简洁,虽然曾经也想叛逃到 Pocket,但是实在接受不了图文混排的设计,还是简简单单的 Instapaper 就好,用了很多年了,几乎没有 Read it never,偶尔兴趣迁移了就 archive 就行,基本每周一清空。
  • J - jd.com 京东购物网站,Plus会员都续费到2027年了。
  • K - kagi.com 被 Hacker News 各种安利的付费搜索引擎,付费订阅了一年,目前没感觉到很大的优势,除了不给 google 隐私数据的快感?
  • L - localhost:5000 fava ,用来看看账本信息,即使没有这个估计也会是 localhost,毕竟经常尝试本地部署一些奇奇怪怪的东西。
  • M - mail.163.com 一个事情临时注册了163邮箱,不是 Gmail 是因为 pin 了。
  • N - news.ycombinator.com Hacker News 偶尔上去刷刷。
  • O - outlook.com 国内主力邮箱。
  • P - photos.google.com 应该是因为最近正在清空 Google Photos 的数据,全面迁移到 iCloud Photos,所以访问的有点多。
  • Q - qcloud.com 讲道理不应该经常访问的,肯定是之前 miniflux 导致机器卡死上去手动重启导致的。
  • R - rsshub.wogong.net 自己不熟的 RSSHub 服务。
  • S - smzdm.com 什么值得买,这几年广告水军是越来越多,官方也开始带货,但是没有其他替代网站了,而且关注的大V还是靠谱的。
  • T - twitter.com 推特,主要消息来源,唯一的设计媒体
  • U - 空缺,往下翻是utgd.net UNTAG 一个从少数派离职的人搞的另一个类似的媒体站,RSS订阅了,但是不输出全文,所以偶尔点进去看。
  • V - v2ex.com 签到了3000多天的网站,最近几年看的少了,但是还是偶尔刷刷。
  • W - wogong.net 就是这个网站啦。
  • X - xueqiu.com 我都很久没看了,一定是因为添加到书签了。
  • Y - youtube.com 油管。
  • Z - 空缺,往下翻就是 zhuanlan.zhihu.com 现在不登录不给看全文了,但是有时候没办法不看,看一半也行吧,知乎真的是越来越恶心了。

从miniflux到freshrss

我的miniflux 一直部署在香港的腾讯轻量云服务器上,因为原始版本的 psql 不支持中文搜索,2023底折腾了一下 zhparser,当时偷懒没有记录。最近一段时间服务器总是 IO 异常升高导致服务器卡死,无法SSH登录,只能重启解决。左思右想也就 miniflux 的 psql 有可能导致这个问题,遂猜测是否是添加了zhparser导致,尝试替换为原始版本的 psql,问题依旧(没有严格测试)。最终猜测可能是数据库文件太大了(1.5GB),服务器内存太小(2GB),和插件关系不大。

如何解决这个问题?其一是将miniflux 部署到本地的homelab服务器,但是网络联通性是个问题,本地的网络环境实在不稳定。其二是将psql托管到专业的地方,考虑到成本也放弃。其三就是放弃miniflux 的历史数据,重新设置,对于数据囤积爱好者也不能接受。最后就是放弃miniflux了。

其实miniflux的使用体验整体是不错的,界面简洁优美。奈何最近出现的以上痛点让我只能转而重新调研现有方案,此时 freshrss 出现在视野中,简单尝试了一下发现相对 miniflux 具有以下优点:

  1. 默认sqlite数据库,简单,miniflux 只支持 psql;
  2. 中文搜索开箱即用;
  3. 订阅管理功能更加全面。 缺点呢:
  4. 界面不如miniflux;
  5. 配置项过于复杂。

迁移的过程是简单的,直接导入 OPML 文件即可。先使用一段时间试试看。

NOW页面

2021年看到了关于 Now 页面的想法,最初是来自 [[Derek Sivers]] 在 2015 的一篇文章《The /now Page Movement》,“现在”页面用于填补相对固定的个人简介和频繁更新的社交网站之间的空白,以介绍作者近期状态或人生当前阶段关注的事情。

当时给博客建立了,但是一直没怎么使用,我不太会频繁更新自己的博客。

今年在使用看板的时候,意识到 now 和看板其实有点相似,遂在 Obsidian 中建立取代 kanban 的 now 页面。

其他 Now 页面🔗

  • 关于什么是now页面 https://nownownow.com/about
    • https://twitter.com/NowNowNow
  • https://blog.douchi.space/docs/now
  • https://rexarski.com/now/
  • https://blog.pursuitus.com/now
  • https://cbp.tldr.ink/#/notes/now.html
  • https://chuck.is/now/
  • https://yayu.net/now
  • https://harper.blog/now/

My App Defaults 2023

刷RSS看到了别人参加App Defaults活动的文章,和我每个季度整理的个人工具库非常接近,不过这个只包括软件,主要是博客作者们的主力软件清单。看别人的默认软件很有趣,也能得到一些启发,所以自己也参加一下,供他人参考。

📨 Mail Client: Gmail Web, Mail.app
📮 Mail Server: Gmail, iCloud
📝 Notes: Obsidian, Telegram Saved Messages
✅ To-Do: TickTick
📷 iPhone Photo Shooting: Apple Camera
🟦 Photo Management: Photos.app, Google Photos
📆 Calendar: Google Calendar
📁 Cloud File Storage: Dropbox, Google Drive, OneDrive
📖 RSS: Miniflux, Reeder
🙍🏻‍♂️ Contacts: Google Contacts
🌐 Browser: Google Chrome
💬 Chat: Telegram, Wechat
🔖 Bookmarks: Pinboard
📑 Read It Later: Instapaper
📜 Word Processing: Microsoft Word, Google Docs
📈 Spreadsheets: Microsoft Excel, Google Docs
📊 Presentations: Microsoft PowerPoint, Google Docs
🛒 Shopping Lists: Obsidian
🍴 Meal Planning: n/a
💰 Budgeting and Personal Finance: Beancount
📰 News: RSS
🎵 Music: Spotify
🎤 Podcasts: Overcast, Spotify
🔐 Password Management: BitWarden

你可能感兴趣的其他博主页面:

ChatGPT:一个心智模型

ChatGPT 发布接近一年了,今天刚好看到一篇很认同的文章,关于如何看待 chatGPT。 TLDR版本:它没有关于这个世界的基本模型,擅长的是给出听起来很像的答案,这与真正的答案是不同的。 当然这已经很有用了,但是距离 AGI 的目标还早得很。

以下是译文,采用 GPT 3.5 翻译,略作修改和注释,原文链接 https://xorvoid.com/chatgpt_a_mental_model.html .

自从ChatGPT在2022年底推出以来,我一直在努力寻找适当的技术框架。而且,全世界也一直在为此苦恼,无数关于末日和悲观的文章:对回形针最大化的恐惧(一个将整个宇宙变为制造回形针的邪恶AI故事),对失业的恐惧,对经济重塑的恐惧,对人工智能幻觉的恐惧,对进一步加速的错误信息的恐惧,对学生作弊的恐惧,等等等等。

这很累。

作为一名工程师,非工程师们常常问我对这个问题的看法。所以,这就是我的观点。

克制的理由🔗

我已经经历了许多技术炒作周期,我的工作方式一直是并且仍然是:“保持冷静,继续前行!”

为了唤起你的记忆,以前发生了这些事情:

  • 在1990年代,我们终于找到了“约柜”(装有十诫石板的柜子,宗教圣物),它被称为“Java面向对象编程”。我们打算重新编写一切,甚至包括操作系统。而今天的Linux是…哦等等…它仍然是C语言。
  • 在20世纪90年代末和21世纪初,我们都明白互联网是如此革命性,以至于公司做什么变得次要,重要的是他们是否在线上运营。纳斯达克指数完全没有崩盘,也没有花费15年才恢复到相同的价格水平。
  • 2008年大衰退之后,中本聪完全取代了建立在不可靠的人类互信基础上的世界金融系统。随着“信任”不再对任何事情有要求,比特币开启了一个新时代的计算机化货币、繁荣和自由。金融部门的不稳定不再存在。黑市在现在数字化的世界中完全无法运作。所有人都欢欣鼓舞。不幸的是,仍然存在许多毫无价值的过时法定货币纸张,因此,作为对世界的服务,本作者开始了一个慈善收集服务(给我发电子邮件)。
  • 2022年,准确无误的五年预测实现后,美国交通部禁止手动驾驶汽车,称“显然,5级自动驾驶远远优于人类驾驶员,今天是公共安全的里程碑。” Argo AI的股票在市场开盘时翻了三倍。但是,出于某种原因,我似乎无法访问argo.ai网站… 嗯嗯…
  • 2023年:ChatGPT将世界变成一个巨大的回形针工厂,在此过程中杀死了所有人类。人类安息。

下一个Buzzword Bingo游戏的荣誉提名:一切都是大数据,一切都是微服务,一切都是敏捷,一切都是面向服务的架构,一切都应该是JavaScript,一切都可以无代码完成,一切都应该在云端,一切都应该在本地,一切都可以用机器学习和数据科学建模,…

开玩笑的话不说,有一种感觉,ChatGPT有点不同,老实说我不反对(继续阅读)。但是,人类大脑有一种可怕的倾向,要么过度兴奋,要么过度恐惧地接受变化。真相在中间某个地方。

左侧进入舞台: 罗德尼·布鲁克斯🔗

最近,IEEE Spectrum刊登了一篇采访罗德尼·布鲁克斯(被认为是机器人学家)的文章,标题为《别再对GPT-4感到不安了》。在文章中,罗德尼·布鲁克斯提出了一个观点,我从一开始就有这种感觉,只是一直没有找到正确的词语来表达。

它没有任何关于世界的基本模型

在几乎是关于心灵理论的禅宗公案中,他说:

大型语言模型擅长的是表达答案应该听起来像什么,这与答案应该是什么不同

这完全捕捉到了我的感受。

让我解释一下。

采访ChatGPT🔗

当ChatGPT在2022年末推出时,朋友们立刻对我大加赞赏。他们说:“我想要它就在我旁边,就像一位合作的程序员”。所以,自然而然地,我想要评估这样一个大胆的说法。

我问了它与应聘者相同的面试问题。如果它要和我一起工作,它应该通过面试,对吧?但它没有。事实上,它惨败了。而且它以一个普通候选人失败的所有方式失败了(这在某种程度上是非常引人注目的)。

它为什么失败了?它只是没有一个基本的世界心智模型。回想起来,这就是我一直在面试中问的问题。我对琐碎的知识不感兴趣。我对使用的工具不感兴趣。我对几个恰当组合的流行词语也不感兴趣。

但是,我对看到有人根据某种潜在的现实模型来推理问题很感兴趣。我喜欢探索这个模型的边界情况。我喜欢抛出罕见的意外情况。我喜欢让人们思考他们以前从未考虑过的子问题。就好像我想说“让我们一起走到我们共同理解的边缘,然后试着继续前进”。然而,要达到这个目标,我们通常必须首先考虑并解决“标准”或“平均”的答案。相比之下,ChatGPT没有展示出这种能力。

专家考试技巧和世界模型构建🔗

在我上学的日子里,我偶尔会遇到一个超级擅长考试的人。我指的是那种不学习实际知识的人。相反,他们考虑的是考试制作者是如何构建考试的。比如,他们会考虑在多项选择题中有多少次答案是“(a)”。我曾经遇到过一些人,他们从未真正学过代数,因为他们只是“通过考试”。对于这样的技能,我有一部分是绝对敬畏的。这是我没有的技能。我记性不好。我是个糟糕的演员。我“读人”的能力几乎肯定低于平均水平。我一直依赖于建立和探索一个越来越复杂的世界模型,作为在这个复杂世界中导航的支撑。

我一直认为其他人也在做同样的事情:构建一个世界模型。这是真的吗?我不知道。那些特别擅长按需提供“事实”的求职者似乎在反驳这一观点。然而,对我来说,ChatGPT显然不是这样。

但这也有另一种方式。

了解一切事物的平均数量!🔗

ChatGPT是我目前对其的心理模型,类似于“对整个人类知识的最大似然估计器”。有两种非常不同的解释方式:(1)嗯,这只是一个愚蠢的统计技巧,和(2)天哪!!

你是否曾经遇到过一个似乎对一切都有一点了解的人?也许这个人还有一个庞大而多样化的社交圈子?也许当你有问题需要指引时,你会去找这个人?一个拥有极广泛知识面的人。

根据我的经验,那个人的知识深度不是最好的。或许他们甚至会给你一些错误的答案。也许那些错误的答案还被他们自信地给出。也许你会因为被他们误导而感到委屈…但是,也许你还是会继续待在他们身边,因为你欣赏他们的广度。毕竟,他们只是偶尔会犯严重错误而已(耸肩)。

现在这个人去参加了大约1000年的GPU训练营,回来后成为了ChatGPT

我们怎么能不感到印象深刻呢?了解并获得“标准”或“平均”的答案……嗯……对于一切。哇。

但在那个千年的训练中,核心结构没有改变。它是你一直拥有的那个老朋友,总是会以同样的方式出错,偶尔让你感到被冷落,有时让你对它的深度感到失望。

那么我们现在怎么办?

ChatGPT非常有用和有价值🔗

一位企业家朋友最近告诉我,他们每天都在不断使用它。这是有道理的,作为一名企业家意味着你需要不断地换“不同的角色”。成功青睐那些能够管理和利用广泛知识的人。而且要快速!

我自己在不了解的情况下,用ChatGPT在大约1小时内学会并实现了这个网站的RSS订阅。它犯了几个错误,但很容易纠正。我确信如果只用Google的话,会花费更长的时间。

目前,谷歌似乎被SEO操控得如此严重,以至于很难快速找到“最大似然”平均信息。你必须浏览大量的标题党、广告和无关紧要的内容,这些内容更多是关于“品牌建设”而不是“教育”,才能找到真正的宝藏。ChatGPT简直是节省时间的利器。谷歌感到害怕,而且他们应该感到害怕。

那么,未来会是什么样子?🔗

大型语言模型会改变全球经济吗?很可能。但这需要一些时间。互联网花了一些时间。移动电话也是如此。大多数新技术也是如此。

足够数量的人类工作将会消失吗?可能不会。

相反,你所拥有的是一个令人惊叹的工具,可以将创造力和独创性推向新的高度。我希望看到人们以新颖的方式将不同的知识领域结合起来。这对于多学科项目来说是一个巨大的福音。

如果你担心失业问题,考虑一下这个:我们曾经有真正的人被称为“计算机”(例如,看一下被低估的电影《隐藏的数字》),后来被机器取代了。这些工作消失了吗?没有,它们经历了重大重组,然后增长绝对爆炸!现在我们称他们为“计算机程序员”,截至2023年,他们的数量超过2500万(统计数据)。

很难相信这一次会有显著的不同。出于某种原因,每当人类发明一种新的创新工具时,我们似乎立即发现了100种以前从未实用过的新用途。这是人类历史的故事。当然,在其中肯定有一些关于人类思维的哲学,但我今天不打算尝试解开它。

改变会让人害怕吗?是的。绝对是。如果你不幸需要重新调整生活和职业,我为你感到遗憾。但这种改变是必要的。如今,即使是最富有的人,与几代人之前相比,普通人的生活条件也有了显著的改善。而这正是因为这种改变。

活在这个时代真是令人难以置信。

保持冷静并继续前进!

局域网控制小米智能插座

宿舍的上网环境是歌华有线,走的方式是很多年前在计算机知识科普书籍上看到的有线电视同轴电缆方式。 不知道是线路问题还是运营商赠送的 modem 问题,经常掉线,而且掉线后需要重启 modem 才能恢复。 这个过程需要手动操作,很麻烦。因为出问题的时候 modem 后台大部分时候也无法访问,所以通过 web 重启的选择也不可行。

所以我想到了用智能插座来控制 modem 的电源。这样就可以通过后台程序来自动重启 modem 了。但是 这里有个悖论问题是,modem 出问题的时候整个网络是不联通的,也就没办法通过互联网控制智能插座。 能不能通过局域网访问和控制智能插座呢?在网上一番搜寻找到了小米智能插座相关的一系列博客文章, 证明了这个方案的可行性。我主要参考了这篇小米智能插座监控设备耗电,并自动断电 感谢作者的分享,也简单记录一下我的实现过程。

我买的具体型号为小米智能插座3,没太研究明白到底有多少类似的款,应该大部分都是能满足要求的。 主要步骤如下:

1. 配置设备🔗

在配置好网络添加进入米家APP后,可以在米家APP或者路由器后台获得智能插座的 IP 地址。

2. 获取设备 Token🔗

采用 Xiaomi-cloud-tokens-extractor 提供的方法获取,运行后可以获取局域网所有设备的 token 和型号等信息。 示例输出:

NAME:     Mijia Smart Plug 3
ID:       <id>
MAC:      <mac>
IP:       192.168.1.1xx
TOKEN:    <token>
MODEL:    cuco.plug.v3
---------
NAME:     Mi Control Hub
ID:       <id>
MAC:      <mac>
IP:       192.168.1.1xx
TOKEN:    <token>
MODEL:    lumi.gateway.v3

3. 获取设备接口信息🔗

通过小米/米家产品库网站 https://home.miot-spec.com/ 获取设备的接口信息。 搜索 cuco.plug.v3 找到对应页面 https://home.miot-spec.com/spec/cuco.plug.v3 点击 查看属性和方法 可以看到接口信息,其中 Switch 是控制开关的接口,也是我们主要使用的。

# 获取当前状态
ret = s.raw_command('get_properties', [{'did':'Switch', 'siid':2, 'piid':1}])
print(ret)
# 设置状态:开机/关机
# value: True 关机,False 开机
ret = s.raw_command('set_properties', [{'did':'Switch', 'siid':2, 'piid':1,'value':False}])
print("set_switch_status: ",ret)

4. 系统监控脚本🔗

最终的监控脚本如下,可以配合 systemd 实现开机自启动。

注意:没有采用 ping 的方式监控 modem 的连通性,而是采用 requests 的方式监控 modem 的 web 服务是否正常。

import miio
import time
import requests
import logging

logging.basicConfig(level=logging.INFO, format='%(asctime)s %(levelname)s %(message)s')

ip = '192.168.1.1xx'
token = ''

def check_net():
    url = 'http://192.168.100.1'  # 替换为要检测的网站URL
    username = ''  # 替换为网站的用户名
    password = ''  # 替换为网站的密码
    session = requests.Session()
    try:
        response = session.get(url, auth=(username, password),timeout=1)
        return(True)
    except:
        return(False)

def set_switch_status(value):
    s = miio.device.Device(ip=ip, token=token)
    ret = s.raw_command('set_properties', [{'did':'Switch', 'siid':2, 'piid':1,'value':value}])
    logging.info("set_switch_status: " + str(ret))

logging.info('start monitoring network...')
err = 0
while True:
    if not check_net():
        err +=1
        logging.error('err: ' + str(err))
    else:
        logging.debug('it works!')
        err = 0
    if err > 3:
        logging.info('err: ' + str(err))
        logging.critical('switching off...')
        set_switch_status(False)
        time.sleep(5)
        logging.critical('switching on...')
        set_switch_status(True)
        time.sleep(120)
    time.sleep(15)

Search your code using Sourcegraph

Recently I have figured out how to handle link rot problem using Recoll. Of course you can use it for code searching, but we can do better.

Another method for searching code is using Github, if you don’t mind it’s online. Searching your own code is also easy with syntax user:<username>. However I want to be faster.

Years ago I tried Sourcegraph. I do not remember why I gave up. Maybe it’s because I was not familiar with Docker. Now I am using Docker everyday, actuaaly docker-compose, so I decided to give it another try. After finishing writing the previous sentence, I remembered that months ago sourcegraph cloud can host your own code, so I gave up self-hosting.

Now things is changing. Sourcegraph discontinued their cloud service. I have to host it myself, which is faster. Bad news is that you can only have 1 private repo now. https://news.ycombinator.com/item?id=34607118

We will be implementing changes to the Sourcegraph free tier on February 22, 2023 with the release of Sourcegraph 4.5. Details on the new free tier can be found here [1]. The changes are: The maximum number of private repositories that can be synced to each instance will be reduced from unlimited to 1. The free tier will no longer support SSO/SAML.

After more digging into hacker news, I found that you can still use sourcegraph to search your local code. https://news.ycombinator.com/item?id=36589033

In case someone is wondering how to search local repositories with sourcegraph, see https://docs.sourcegraph.com/admin/external_service/src_serv... and https://docs.sourcegraph.com/admin/deploy/docker-single-cont...
  docker run --add-host=host.docker.internal:host-gateway --publish 7080:7080 --publish 127.0.0.1:3370:3370 --rm --volume ~/.sourcegraph/config:/etc/sourcegraph --volume ~/.sourcegraph/data:/var/opt/sourcegraph sourcegraph/server:5.1.2


  docker run --rm=true --publish 3434:3434 --volume $PWD:/data/repos:ro sourcegraph/src-cli:latest serve-git /data/repos

So no more problems. Here is my docker-compose.yaml

version: "2.4"                                                                                                                                                                                                          [5/3244]

services:
  sourcegraph:
    image: sourcegraph/server:5.2.0
    restart: unless-stopped
    container_name: sourcegraph
    networks:
      - traefik
    ports:
      - "7080:7080/tcp"
      - "3370:3370/tcp"
    environment:
      - PUID=1000
      - PGID=1000
    volumes:
      - /data/docker/sourcegraph/config:/etc/sourcegraph
      - /data/docker/sourcegraph/data:/var/opt/sourcegraph
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.code.entrypoints=http"
      - "traefik.http.routers.code.rule=Host(`code.pm.lo`)"
      - "traefik.http.services.code.loadbalancer.server.port=7080"
  src-cli:
    image: sourcegraph/src-cli:latest
    restart: unless-stopped
    container_name: src-cli
    networks:
      - traefik
    ports:
      - "3434:3434/tcp"
    environment:
      - PUID=1000
      - PGID=1000
    volumes:
      - /data/Dropbox/Repos:/data/repos
    command: serve-git /data/repos
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.codesrc.entrypoints=http"
      - "traefik.http.routers.codesrc.rule=Host(`codesrc.pm.lo`)"
      - "traefik.http.services.codesrc.loadbalancer.server.port=3434"
networks:
  traefik:
    external: true

悲智双运

看完汉洋的伤痕椅子

很多年前就知道信息不对称,看完文章居然回忆了好一会才又想到这个词。技术很重要,技术的扩散也很重要。

所以是不是别太执着当下的选择?毕竟有限的见识怎么可能让我们做出最完美的选择呢。

学习到一个新的佛教用语,悲智双运。

向 ChatGPT 请教,告知这是佛教中的一个重要概念,它包含了两个方面的修行:悲和智。

悲,或称为悲心,是指对众生的苦难和痛苦产生深切的同情心和关怀。它是一种无私的、无条件的爱和慈悲,不仅仅局限于个人的幸福,而是关心所有众生的福祉。通过培养悲心,佛教徒努力解除众生的痛苦,并帮助他们摆脱轮回的苦难。

智,或称为智慧,是指超越表面现象,深入理解事物真实本性的能力。它是通过反思和观察,超越迷惑和糊涂的认知,认识到事物的真实性质和宇宙的本质。智慧帮助人们认识到所有事物都是无常、无我和苦的,从而超越执着和執著,追求解脱和智慧的境界。

悲智双运强调慈悲和智慧的双重修行,认为这两方面的修行是相辅相成的。悲心促使佛教徒关心他人并帮助他们,而智慧帮助佛教徒认识到如何最有效地帮助众生。只有通过悲心和智慧的双重修行,佛教徒才能实现自己的解脱和成佛,并最大限度地利益他人。悲智双运是佛教修行的核心理念之一,也是追求智慧与慈悲的佛教徒的目标之一。

In English, the concept of “悲智双运” can be expressed as the “twin cultivation of compassion and wisdom” or the “practice of compassion and wisdom in tandem.”

Compassion refers to the deep sympathy and concern for the suffering of all beings, extending beyond personal happiness. It is an altruistic and unconditional love and compassion that seeks to alleviate the suffering of others and help them transcend the cycle of suffering.

Wisdom, on the other hand, involves going beyond surface appearances and gaining a profound understanding of the true nature of things. It is cultivated through reflection and observation, allowing one to see the impermanent, selfless, and unsatisfactory nature of all phenomena. Wisdom helps individuals transcend attachment and delusion, leading them towards liberation and the realization of the ultimate truth.

The twin cultivation of compassion and wisdom emphasizes the simultaneous development of these two aspects of spiritual practice. Compassion motivates individuals to care for others and provide assistance, while wisdom guides them in discerning the most effective ways to help sentient beings. By cultivating both compassion and wisdom, practitioners of Buddhism aim to attain personal liberation and enlightenment while benefiting others to the fullest extent. The twin cultivation of compassion and wisdom is a core principle in Buddhist practice and a goal for those seeking wisdom and compassion in Buddhism.

使用 chatGPT 编写自动添加 beancount balance 断言语句

我使用 beancount 记账流程中的有一步是这样的,将每张信用卡的账单日添加到滴答清单中,每月重复。 每当到达账单日时,提醒我在 beancount 文件中添加一条对应帐目的 balance 断言语句,由于大部分信用卡 的出账是有滞后的,所以该balance断言通常需要同时加上!标记,便于后续账单出来后修改。

这个过程是比较机械的,所以我想到了使用 chatGPT 来自动化这个过程,这样我只需要在出账后手动更新自动添加 的断言语句,将金额修改为正确的还款金额,同时去除!标记。最终的脚本如下。

import datetime

def add_balance_statement(ledger_path, account, date, balance, currency):
    with open(ledger_path, 'a') as file:
        file.write(f"{date} balance {account} {balance} {currency}\n")

def auto_add_balance_statements(ledger_path, credit_cards):
    today = datetime.date.today()
    for card in credit_cards:
        bill_date = card['bill_date']
        accounts = card['accounts']
        balance = card['balance']
        currency = card['currency']
        if today.day == bill_date:
            for account in accounts:
                add_balance_statement(ledger_path, account, today, balance, currency)
                print(f"Balance statement added for {account} on {today}.")

# Specify the path to your Beancount ledger file
ledger_file_path = "<ledger_path>"

# Specify your credit card details (bill date, accounts, balance, and currency)
credit_cards = [
    {
        'bill_date': 1,  # Example: 1st of the month
        'accounts': [
            {'account': 'Assets:CreditCards:Card1:Account1', 'currency': 'USD'},  # Example: Account1 for Card1 with USD currency
            {'account': 'Assets:CreditCards:Card1:Account2', 'currency': 'EUR'},  # Example: Account2 for Card1 with EUR currency
        ],
        'balance': 1000.00,  # Example: Current balance for Card1
        'currency': 'USD'  # Example: Currency for Card1
    },
    {
        'bill_date': 15,  # Example: 15th of the month
        'accounts': [
            {'account': 'Assets:CreditCards:Card2:Account1', 'currency': 'USD'},  # Example: Account1 for Card2 with USD currency
            {'account': 'Assets:CreditCards:Card2:Account2', 'currency': 'GBP'},  # Example: Account2 for Card2 with GBP currency
        ],
        'balance': 2000.00,  # Example: Current balance for Card2
        'currency': 'USD'  # Example: Currency for Card2
    },
    # Add more credit card details as needed
]

# Call the function to automatically add balance statements
auto_add_balance_statements(ledger_file_path, credit_cards)

对于有兴趣的读者,可以看我和 chatgpt 的几轮对话。

Q: Write a python script, it check today’s date, if it match a specific day in a month, writing some content to a file, whois path is <path>.

A: Certainly! Here’s a Python script that checks if today’s date matches a specific day in a month and writes some content to a file:

import datetime

def write_content_to_file(path, content):
    with open(path, 'a') as file:
        file.write(content + '\n')

def check_and_write_content(path, day, month, content):
    today = datetime.date.today()
    if today.day == day and today.month == month:
        write_content_to_file(path, content)
        print("Content written to the file.")
    else:
        print("Today's date does not match the specified day.")

# Specify the path, day, month, and content
file_path = "<path>"
day = 15
month = 7
content = "This is the content to be written."

# Call the function to check and write content
check_and_write_content(file_path, day, month, content)

In the script above, you need to replace "<path>" with the actual path to the file where you want to write the content. Also, specify the daymonth, and content variables according to your requirements.

The script checks if today’s date matches the specified day and month. If it does, it calls the write_content_to_file function to append the content to the file. If the date doesn’t match, it prints a message indicating that today’s date doesn’t match the specified day.

Q:I have many credit cards, each card have different bill date. I want a python script can auto add a balance statement to my beancount ledger. please help me writing this script. A:Certainly! Here’s a Python script that can help you automatically add a balance statement to your Beancount ledger based on the bill dates of your credit cards:

import datetime

def add_balance_statement(ledger_path, account, date, balance):
    with open(ledger_path, 'a') as file:
        file.write(f"{date} balance {account} {balance}\n")

def auto_add_balance_statements(ledger_path, credit_cards):
    today = datetime.date.today()
    for card in credit_cards:
        bill_date = card['bill_date']
        account = card['account']
        balance = card['balance']
        if today.day == bill_date:
            add_balance_statement(ledger_path, account, today, balance)
            print(f"Balance statement added for {account} on {today}.")

# Specify the path to your Beancount ledger file
ledger_file_path = "<ledger_path>"

# Specify your credit card details (bill date, account, and balance)
credit_cards = [
    {
        'bill_date': 1,  # Example: 1st of the month
        'account': 'Assets:CreditCards:Card1',  # Example: Account for Card1
        'balance': 1000.00  # Example: Current balance for Card1
    },
    {
        'bill_date': 15,  # Example: 15th of the month
        'account': 'Assets:CreditCards:Card2',  # Example: Account for Card2
        'balance': 2000.00  # Example: Current balance for Card2
    },
    # Add more credit card details as needed
]

# Call the function to automatically add balance statements
auto_add_balance_statements(ledger_file_path, credit_cards)

In the script above, you need to replace "<ledger_path>" with the actual path to your Beancount ledger file. Also, specify the bill_dateaccount, and balance for each of your credit cards in the credit_cards list.

The script checks if today’s date matches the bill date for each credit card. If it does, it calls the add_balance_statement function to add a balance statement to the ledger file. The balance statement includes the account, date, and balance for the credit card. If the date doesn’t match the bill date for a particular credit card, it moves on to the next card.

Q:one bill_date can have multiple accounts, refine your code. A:Certainly! Here’s an updated version of the script that allows multiple accounts for a single bill date:

import datetime

def add_balance_statement(ledger_path, account, date, balance):
    with open(ledger_path, 'a') as file:
        file.write(f"{date} balance {account} {balance}\n")

def auto_add_balance_statements(ledger_path, credit_cards):
    today = datetime.date.today()
    for card in credit_cards:
        bill_date = card['bill_date']
        accounts = card['accounts']
        balance = card['balance']
        if today.day == bill_date:
            for account in accounts:
                add_balance_statement(ledger_path, account, today, balance)
                print(f"Balance statement added for {account} on {today}.")

# Specify the path to your Beancount ledger file
ledger_file_path = "<ledger_path>"

# Specify your credit card details (bill date, accounts, and balance)
credit_cards = [
    {
        'bill_date': 1,  # Example: 1st of the month
        'accounts': [
            'Assets:CreditCards:Card1:Account1',  # Example: Account1 for Card1
            'Assets:CreditCards:Card1:Account2',  # Example: Account2 for Card1
        ],
        'balance': 1000.00  # Example: Current balance for Card1
    },
    {
        'bill_date': 15,  # Example: 15th of the month
        'accounts': [
            'Assets:CreditCards:Card2:Account1',  # Example: Account1 for Card2
            'Assets:CreditCards:Card2:Account2',  # Example: Account2 for Card2
        ],
        'balance': 2000.00  # Example: Current balance for Card2
    },
    # Add more credit card details as needed
]

# Call the function to automatically add balance statements
auto_add_balance_statements(ledger_file_path, credit_cards)

In this updated version, each credit card in the credit_cards list has a bill_dateaccounts, and balance. The accounts field is a list of all the accounts associated with that credit card. The script iterates through each credit card and its associated accounts. If today’s date matches the bill date, it adds a balance statement for each account with the specified balance.

Please replace "<ledger_path>" with the actual path to your Beancount ledger file. Also, update the credit card details in the credit_cards list according to your specific accounts and balances.

Q:different accounts can have different currency, please add currency info to account. A:Certainly! Here’s an updated version of the script that includes currency information for each account:

import datetime

def add_balance_statement(ledger_path, account, date, balance, currency):
    with open(ledger_path, 'a') as file:
        file.write(f"{date} balance {account} {balance} {currency}\n")

def auto_add_balance_statements(ledger_path, credit_cards):
    today = datetime.date.today()
    for card in credit_cards:
        bill_date = card['bill_date']
        accounts = card['accounts']
        balance = card['balance']
        currency = card['currency']
        if today.day == bill_date:
            for account in accounts:
                add_balance_statement(ledger_path, account, today, balance, currency)
                print(f"Balance statement added for {account} on {today}.")

# Specify the path to your Beancount ledger file
ledger_file_path = "<ledger_path>"

# Specify your credit card details (bill date, accounts, balance, and currency)
credit_cards = [
    {
        'bill_date': 1,  # Example: 1st of the month
        'accounts': [
            {'account': 'Assets:CreditCards:Card1:Account1', 'currency': 'USD'},  # Example: Account1 for Card1 with USD currency
            {'account': 'Assets:CreditCards:Card1:Account2', 'currency': 'EUR'},  # Example: Account2 for Card1 with EUR currency
        ],
        'balance': 1000.00,  # Example: Current balance for Card1
        'currency': 'USD'  # Example: Currency for Card1
    },
    {
        'bill_date': 15,  # Example: 15th of the month
        'accounts': [
            {'account': 'Assets:CreditCards:Card2:Account1', 'currency': 'USD'},  # Example: Account1 for Card2 with USD currency
            {'account': 'Assets:CreditCards:Card2:Account2', 'currency': 'GBP'},  # Example: Account2 for Card2 with GBP currency
        ],
        'balance': 2000.00,  # Example: Current balance for Card2
        'currency': 'USD'  # Example: Currency for Card2
    },
    # Add more credit card details as needed
]

# Call the function to automatically add balance statements
auto_add_balance_statements(ledger_file_path, credit_cards)

In this updated version, each account in the accounts list of each credit card includes both the account name and the currency. The add_balance_statement function is modified to include the currency parameter when writing the balance statement to the ledger.

Please replace "<ledger_path>" with the actual path to your Beancount ledger file. Also, update the credit card details in the credit_cards list according to your specific accounts, balances, and currencies.

Obsidian 同步方案

Obsidian 是一款优秀的双链笔记软件,这里不多做介绍,能搜索到这篇文章的读者应该对此有了解。 我的笔记使用历程非常久远了,简单而不完全的回忆包括:Evernote、vimwiki、simplenote、onenote 、notion、roam research、logseq、obsidian。这些笔记软件都有各自的优势,但是目前我使用的是 Obsidian。

在桌面的使用场景下,使用 Dropbox 同步可以满足 Windows、Ubuntu、MacOS 三个平台的同步需求。 但是移动端 iOS 场景下,由于 iOS 的机制问题,Dropbox 同步无法获得好的体验。下面整理相关同步方案, 供读者备选。先后顺序表示优先级。

官方同步服务 Obsidian Sync🔗

官方链接 <obsidian.md/sync>

除了贵没有什么缺点,正常用户年付价格 8 USD/month,学生年付价格6折即 4.8 USD/month。早鸟用户 年付价格5折即 4 USD/month。

一个降低费用的方法是合租,因为一个 Obsidian Sync 付费账可以建立5个 remote vault (< https://help.obsidian.md/Obsidian+Sync/Limitations>) 每个 vault 可设置独立的密码 ( https://help.obsidian.md/Obsidian+Sync/Set+up+Obsidian+Sync ) 因此不用担心你的数据泄漏。 但是账户密码公开,每个成员均有权限删除仓库、删除账户、修改账户邮箱及密码,以上风险后果是损失一年的订阅费用,但是数据是安全的。相关信息可参考参考链接部分中的论坛合租讨论。 以及淘宝/闲鱼中也有相关车位出售。

rev-obsidian-sync 官方同步服务的逆向实现🔗

来自高中生 @acheong08 大神的逆向实现。

相关链接

livesync🔗

https://github.com/vrtmrz/obsidian-livesync

Self-hosted LiveSync (自搭建在线同步) 是一个社区实现的在线同步插件。 使用一个自搭建的或者购买的 CouchDB 作为中转服务器。兼容所有支持 Obsidian 的平台。

使用 CounchDB 数据库,可以做到实时同步,我自己折腾了两次,移动端使用体验一言难尽。

remotely-save 使用 webdav 同步🔗

https://github.com/remotely-save/remotely-save

git sync🔗

https://github.com/oscarspalk/obsidian-git-sync

对于比较大的仓库,手机上 git pull 的效率较低。

其他与本文类似的文章🔗

MiniFlux Starred as Feed

Miniflux 是一个非常好用的 RSS 自托管方案,支持自建,支持多种客户端,支持多种订阅方式。 最近由于在折腾 Archivebox,需要将 Miniflux 中的 Starred Feed 作为一个 Feed 输出,以便于 导入星标条目到 Archivebox。 Miniflux 本身并不支持这个功能,但是其提供了 API,可以比较简单的导出 Starred 内容。

备选方案🔗

如果是自己使用 Python 写的话,可以利用 https://github.com/miniflux/python-client 这个库,配合 feedgen 也能写个大概的,核心代码大概如下:

import miniflux
from feedgen.feed import FeedGenerator

client = miniflux.Client("https://miniflux.example.com", api_key="api_key")
entries = client.get_entries(starred=True, limit=50)

def create_rss_page(data):
    fg = FeedGenerator()
    fg.title('Miniflux Starred Feed')
    fg.link(href='https://miniflux.wogong.net', rel='self')
    fg.language('en')
    fg.description('Miniflux Starred Feed')

    for entry in data['entries']:
        fe = fg.add_entry()
        fe.id(entry['id'])
        fe.title(entry['title'])
        fe.link(href=entry['url'])
        fe.description('nothing')
        fe.author(name=entry['author'])
        fe.pubDate(entry['published_at'])

    rss_feed = fg.rss_str(pretty=True)
    fg.rss_file('rss.xml')
    return rss_feed

但是本着不自己造轮子的原则,找到了一些现成的工具,例如

  1. Small CLI which can be used to export all your miniflux RSS feeds into an OPML file and to export all starred/bookmarked entries https://github.com/rogierlommers/miniflux-exporter
  2. Atom feed exporter for Miniflux starred items https://github.com/erdnaxe/miniflux-luma

两个项目的 star 数都寥寥,miniflux 有这么小众么,第一个工具尝试了一下,导出 starred item 出问题了, 估计太久没维护,提交了一个 issue https://github.com/rogierlommers/miniflux-exporter/issues/8

第二个项目同样有问题,编译都没通过,我对 go 也是两眼抹黑,同样提交了 issue https://github.com/erdnaxe/miniflux-luma/issues/1

这个作者反应迅速,直接修复了,而且可以通过 web 方式提供 feed,决定就用他了。

Docker-compose 部署🔗

当然可以选择直接用编译好的二进制文件,但是我还是喜欢用 docker-compose 来部署,方便管理。 这也不只是一个偏好问题,多维护一个独立的 Web 服务显然是不合理的,而且这个服务只是 Miniflux 的附属,所以要是能集成到 miniflux 的 docker-compose 中就好了。一番折腾,获得如下的 docker-compose.yaml 文件:

version: '3.4'
services:
  miniflux:
    image: miniflux/miniflux:latest
    ports:
      - "127.0.0.1:8080:8080"
    depends_on:
      - db
    environment:
      - DATABASE_URL=postgres://miniflux:secret@db/miniflux?sslmode=disable
      - RUN_MIGRATIONS=1
      - DEBUG=0
      - CREATE_ADMIN=1
      - ADMIN_USERNAME=
      - ADMIN_PASSWORD=
  db:
    image: postgres:latest
    environment:
      - POSTGRES_USER=miniflux
      - POSTGRES_PASSWORD=
    volumes:
      - miniflux-db:/var/lib/postgresql/data
      - ./back:/back
    healthcheck:
      test: ["CMD", "pg_isready", "-U", "miniflux"]
      interval: 10s
      start_period: 30s
  luma:
    build: miniflux-luma
    ports:
      - "127.0.0.1:8081:8080"
    command: -endpoint http://miniflux:8080 -listen-addr 0.0.0.0:8080
    volumes:
      - ./miniflux-luma/api_token:/api_token
volumes:
  miniflux-db:

miniflux-luma 官方并没有提供 Dockerfile,可参考我的仓库 https://github.com/wogong/miniflux-luma

之后无论是自己反代 8081 端口还是通过 Cloudflare Tunnel 反代,都可以方便的使用了。 和 miniflux 共同维护也比较方便,挂了一个另一个也没意义了反正。

用于 beancount 快速记账的 Telegram Bot

当年从随手记迁移到桌面记账方式(Excel/GnuCash/Beancount)后,确实有一段时间的不适应。 后来实在没有找到好用的移动端记账 APP,同时也适应了桌面记账,遂被驯化认为不需要在移动场景 记账。Costflow 出来之后没有第一时间尝试的原因也在于此,使用一段时间基于 costflow 语法 的 Telegram 机器人之后,发现经常是想要的账户没有配置,导致使用频率并不高。

前段时间的某一天突然意识到,为什么要提前配置账户信息呢?账户信息全部都在账本文件中,直接 查询账本文件不就可以避免冷启动的问题么。遂自己开坑写了一个新的记账机器人 beancount-bot

使用一月有余,今天完善了一下相关功能,更新了文档和使用例子。下面是几点简要说明:

  1. 适合手动记账党 :D
  2. 适合有自己服务器的人(境内服务器需要配置代理),部署在本地 NAS 上也是可行的
  3. 不兼容 costflow 语法,不需要账户信息的配置,账户的匹配是读取账本文件,类似编辑器的账户补全

在这里分享给大家,希望可以节省一点记账/对账的时间,有兴趣的欢迎尝试。

Clash 作为网关的透明代理

距离上一篇介绍该主题的文章已经过去了接近三年,[Clash 作为网关的透明代理]({% post_url 2020-11-27-clash-transparent-proxy %}) 中间使用到的方案其实多次变更,例如使用了很长一段时间 的 shellclash,这个方案胜在省心,可以直接在支持的 路由器上部署,但是内核更新缓慢,作者对配置加了很多自定义设置,虽然出发点是为了方便大部分小白用户,但是 严重降低了自定义的能力。而且默认的一些设定大概率会导致 DNS 泄漏问题,关于这个话题可以参考 不良林的相关视频。这是不可接受的,因此前段时间又回归到使用 PVE 上虚拟机的方案。

简单摸索了一下最新方案发现 redir-host 模式已经被 Clash 官方放弃,不建议再使用。 TProxy 模式当然 没啥问题,但是毕竟得自己处理 iptables 规则。在没有性能瓶颈的情况下,更推荐使用 tun 模式,可以自动 处理路由等问题。下面简单介绍一下相关配置。

首先,在网关机器上打开 ipv4 转发, echo net.ipv4.ip_forward=1 >> /etc/sysctl.conf && sysctl -p

其次 Clash 配置文件头部添加如下

tun:
  enable: true
  stack: system # or gvisor
    #dns-hijack:
    #    - any:53
    #    - tcp://any:53
  auto-route: true
  auto-detect-interface: true
dns:
  enable: true
  ipv6: false
  listen: 0.0.0.0:53
  enhanced-mode: fake-ip       # redir-host or fake-ip
  fake-ip-range: 198.18.0.1/16    # Fake IP addresses pool CIDR
  use-hosts: true                 # lookup hosts and return IP record
  nameserver:
    - 114.114.114.114

最后在局域网的 DHCP 服务器设置网关为该机器 IP 即可,也可以手动在希望走代理机器的网关设置未该机器 IP。

GitHub notification cannot clear bug

A few days ago I received a new type of spam email. Basically they create a GitHub repo and then spam everyone they want in the issues by @ them. Of course this gets banned after being reported. I do not do anything because I think someone else will do the reporting work.

Days later, when I log in to GitHub, I notice that there is a dot in the notification box, which means that there are unread notifications. So I tried to mark all notifications as read. The problem is that the spam notifications refuse to be deleted. Why is that? After checking I found that the spam repo has been deleted, maybe by GitHub. I tried everything in the Wed UI but failed.

I am not busy that day, so I decided to create a ticket in GitHub support, which is

Days ago I received a spam email subjected as Re: [kl-heisenberg/AI-hiring] Initial commit (a1a534d).

Somebody use this method to send ad emails. I just ignored it.

Today when I go to my notification box https://github.com/notifications?query=is%3Aunread

There is an annoying item shows this repo, but without any content (you deleted this user).

In the end, I can not clear the notification box.

See this image of my notification box: https://imgur.com/a/qRgBDcq

You can see the screenshot at https://imgur.com/a/qRgBDcq.

3 days later I got the solution. Why so long? Github claims they are busy lol. Maybe Microsoft needs to do something right :)

The solution worked like a charm, I attach it below.

Note: following paragraphs are from GitHub Support.

Thank you for reaching out to GitHub Support. Apologies for the late response and I am sorry you are having trouble with your inbox notifications. ​ We have had a few reports of this bug and our engineers are looking into it. I’ve informed our engineers regarding your report as well. It’s very useful for us to have more data points, so thank you for submitting this to us!

In the meantime, you can try the curl command below, it will mark all of your notifications as read, clear the notification indicator, and with any luck, take care of that phantom notification for you.​ Note that the 1-0 of 1 message may still persist after the curl command is run; our engineers are looking into this as well.

A few things I’d like to note:

  • In order to use this command a Personal Access Token (PAT) will be required and $TOKEN needs to be replaced by a personal access token you can create here: https://github.com/settings/tokens/new. Creating a Personal Access Token also has the steps to create a token. After it is created, replace $TOKEN in the command with your new PAT.
  • Note: Please ensure that the PAT has the notifications scope.
  • Please update the date and time to your current date and note the time values must be in ISO 8601 format: YYYY-MM-DDTHH:MM:SSZ.
curl -H "Authorization: bearer $TOKEN" -X PUT -H "Accept: application/vnd.github.v3+json" https://api.github.com/notifications -d '{"last_read_at":"2023-01-25T19:42:00"}'

You can also export the current date and time in bash by running:

export now=$(date +%Y-%m-%dT%H:%M:%SZ)

Then you can use the date and time variable in the curl command as follows:

curl -H "Authorization: bearer $TOKEN" -X PUT -H "Accept: application/vnd.github.v3+json" https://api.github.com/notifications -d '{"last_read_at":"'"$now"'"}'

For your reference, here is the documentation for the Notifications REST API endpoint.

在 cron/systemd timer 任务中的 git 认证

本文回答如何在 systemd timer 任务或者 cron 任务中进行 git 认证,方便进行 git pull/push 操作。

首先,不推荐 ssh-key 方式,不推荐,因为安全性和粒度控制不够。设置无 passphrase 的私钥(不安全),无法分 repo 控制权限。

推荐使用 https 配合 GitHub Personal Access Token 的方式,主要使用 gitcredentials - Providing usernames and passwords to Git,参考文档链接 https://git-scm.com/docs/gitcredentialshttps://git-scm.com/book/en/v2/Git-Tools-Credential-Storage

首先在 https://github.com/settings/apps 生成 Personal Access Token (PAT),建议使用细粒度的 token,降低泄露 token 的损失。

其次在需要操作的 repo 根目录进行设置

# 使用文件的方式储存认证信息
git config --local credential.helper store
# 使用路径来区分不同的认证信息
git config --local credential.useHttpPath true

设置完毕后手动操作一次,保存好 repo 的认证信息即可,认证信息储存在 ~/.git-credential.

【译文】理查德·汉明《你和你的研究》

本文翻译自 https://www.cs.virginia.edu/~robins/YouAndYourResearch.html 最初了解该文来自 [[阮一峰]] 对该文的精简版介绍,https://www.ruanyifeng.com/blog/2016/04/you-and-your-research.html

理查德·汉明《你和你的研究》🔗

贝尔通信研究所学术研讨会发言 1986 年 3 月 7 日 J. F. Kaiser  J. F. Kaiser 贝尔通信研究所 445 South Street
Morristown, NJ 07962-1910 [email protected]

在贝尔通信研究学术报告系列的一个研讨会上,加利福尼亚州蒙特雷海军研究生院的教授、退休的贝尔实验室科学家理查德·W·哈明博士于 1986 年 3 月 7 日在莫里斯研究与工程中心向约 200 名贝尔核心员工和访客发表了一场非常有趣和激励人心的演讲,题为“你和你的研究”。这次演讲集中讨论了汉明对问题“为什么很少有科学家做出重大贡献,而很多人在长期内被遗忘?”的观察和研究。他在贝尔实验室工作了 30 年,拥有超过 40 年的经验,直接观察了许多科学家的行为,向科学家提出了非常尖锐的问题,问他们做了什么、如何做以及为什么做,他还研究了伟大科学家的生活和伟大贡献的产生,进行了内省并研究了创造力理论。这次演讲讨论了他在独立科学家的特性、能力、特点、工作习惯、态度和哲学方面所学到的东西。

为了使演讲中的信息更广泛地传播,本文对该演讲进行了仔细的录音转录。这份转录包括随后在问答环节中进行的讨论。与任何演讲一样,转录版本因为失去了演讲者的声音语调和手势而受到影响;必须听录音才能重新捕捉到演讲的那部分内容。虽然# 理查德·汉明的演讲录音完全可理解,但有些提问者的言论却不是。在录音不可理解的地方,我已经在括号中加入了我对提问者言论的印象。在有疑问且能确认提问者身份的情况下,我和每个提问者核实了对其言论解释的准确性。

关于理查德·W·汉明博士的介绍🔗

作为贝尔通讯研究公司学术研讨会系列的演讲者,来自加利福尼亚州蒙特雷海军研究生院的理查德·W·汉明博士由贝尔通讯研究公司应用研究副总裁艾伦·G·钦诺威斯介绍。

Alan G. Chynoweth:各位同事,以及我了解到许多来自贝尔实验室的前同事今天也在这里与我们共聚一堂,我谨代表大家表示问候。今天是一个特别幸福的日子,我非常高兴地向大家介绍我多年的老朋友和同事 Richard Hamming,或者我们都熟知的 Dick Hamming。

汉明是数学和计算机科学领域中的伟大人物之一,我相信在座的观众不需要提醒。他在芝加哥大学和内布拉斯加大学接受了早期教育,并在伊利诺伊大学获得了博士学位;然后他在战争期间加入了洛斯阿拉莫斯项目。之后,于 1946 年,他加入了贝尔实验室。当然,那就是我遇到汉明的地方——当我加入贝尔实验室的物理研究组织时。那些日子里,我们习惯一起午餐,而这个来自数学领域的奇怪家伙总是很高兴加入我们。我们总是很高兴有他在一起,因为他带来了很多非正统的想法和观点。我可以向你保证那些午餐是很有启发性的。

虽然这些年来我们的职业道路并不是非常接近,但我一直在贝尔实验室的走廊里和碰到汉明,并一直非常钦佩他所做的事情。我认为事实证明了一切。要详细说明太长了,但是让我举个例子,他已经写了七本书,讲述了各种数学、计算机、编码和信息理论领域的书籍,其中三本已经进入了第二版。这毫无疑问证明了理查德·汉明的多产和地位。

我想上次见到他应该是在十年前的都柏林一个相当有趣的小型会议上,我们都是演讲者。像往常一样,他非常有趣。这只是他提出的挑衅性思想的又一个例子:我记得他说过,“有些波长人们看不见,有些声音人们听不到,也许计算机有些思维人们想不到。”有了理查德·汉明,我们不需要计算机。我认为我们将会听到一场非常有趣的演讲。

讲座:Richard W. Hamming 博士的 “你和你的研究”🔗

很高兴来到这里。我怀疑我是否配得上这样的介绍。我演讲的题目是:“你和你的研究”。这不是关于管理研究,而是关于你个人如何做你的研究。我可以讲另一个主题,但我现在不会,因为这次演讲是关于你的。我不是在谈论普通的研究,我说的是伟大的研究。为了描述伟大的研究,我偶尔也会说诺贝尔奖级别的工作,不过它不一定要获得诺贝尔奖,我说的是那些我们认为重要的事情。例如相对论、香农的信息理论,任何一种杰出的理论——我所说的就是这种东西。

那我是如何开始这项研究的呢?在洛斯阿拉莫斯,我被召来管理那些其他人已经运行起来的计算机,这样那些科学家和物理学家就可以回到他们的工作中。我认为我是一个替罪羊。我发现虽然身体上我和他们一样,但他们与我不同。坦白地说,我非常羡慕。我想知道他们与我不同的原因。我近距离看到了费曼,我也看到了费米和泰勒。我看到了奥本海默。我看到了汉斯 · 贝特:他是我的老板。我看到了许多非常有能力的人。我对那些做事的人和那些可能会做事的人之间的差异非常感兴趣。

当我来到贝尔实验室时,我加入了一个非常有成效的部门。那时 Bode 是部门主管;香农也在那里,还有其他人。我继续思考“为什么”和“有什么区别”。后来我通过阅读传记、自传,并向人们询问“你是怎么做到这一点的?”来进一步探究这些问题。我试图找出区别所在。这就是这次演讲的内容。

现在,为什么这次演讲很重要呢?我认为它很重要,因为据我所知,每个人只有一次生命。即使你信奉轮回,它对一生到下一世并没有任何好处!为什么你不应该在这一生中做一些重要的事情呢?无论你如何定义“重要”,我不会给出定义 —— 你知道我的意思。我主要谈论科学,因为那是我学习的领域。但就我所知,也有其他人告诉过我,我的话同样适用于许多其他领域。在大多数领域中,杰出的工作在很大程度上都有相同的特点,但我会限制自己只谈论科学。

为了直接影响到你们,我必须使用第一人称。我必须让你们放下谦虚,对自己说,“是的,我想做一流的工作。”我们的社会不赞成那些立志做出真正好的工作的人。你们不应该这样,运气应该降临在你们身上,你们应该靠偶然做出伟大的事情。这是种愚蠢的说法。我想说的是,为什么你不应该尝试去做一些重要的事情呢?你不必告诉别人,但你应该告诉自己,“是的,我想做一些重要的事情。”

为了进入第二个阶段,我必须放下谦虚,用第一人称谈论我所见到的、做过的以及听到的事情。我将谈论一些人,其中一些你们认识。我相信离开时,你们不会把我刚才所说的话引用出来。

让我从心理学上而不是逻辑上开始。我发现主要的反对意见是人们认为伟大的科学都是无意识中发生的。这都是运气的问题。好了,我们看看爱因斯坦。注意到他做了多少不同的伟大的工作。这是运气吗?这是不是有点太多了?再看看香农。他不仅仅提出了信息论。几年前,他做了一些其他很好的研究,有些事情仍然被加密保护着。他做了许多不错的研究。

你会一遍又一遍地看到,一个厉害的人不只是做了一件事情。偶尔有人一生只做了一件事,我们稍后会谈论这个问题,但很多时候会存在重复。我认为,运气并不能涵盖一切。我会引用巴斯德的话,“机遇总是眷顾有准备的心智。”我想这句话表达了我的信念。确实有一些运气的成分,但不是全部,有准备的人迟早会找到一些重要的事情并把它完成。因此,我认为,它确实是运气。你做的特定的事情是运气,但你完成了某些研究不是。

例如,当我来到贝尔实验室时,一段时间我和香农共用一个办公室。当他在研究信息理论的同时,我在研究编码理论。这两个人在同一地点、同一时间做类似的事情是令人怀疑的事情——就是在这种氛围下工作。你可以说:“是的,这是运气。”但换另一个角度看待,你可以问:“在贝尔实验室的所有人中,为什么只有这两个人?”。是的,这部分是运气,但也有一部分是准备妥当。尽管我会一再提到运气,但我想明确地表达:仅仅靠运气是否能判断你是否能够取得卓越的成就是不够的。我认为,你在此方面有一定的控制力,虽然不是完全的。纽顿也有过这样的说法:“如果别人能像我一样努力思考,他们就能取得类似的成果。”

许多卓越的科学家都有一个共同的特点:年轻时就有独立思考的能力并且有勇气去追求自己的研究。例如,爱因斯坦在十二岁或十四岁左右问自己一个问题:“如果我以光速移动去观察光波,会是什么样子?”此时他已经知道电磁理论表明不可能有一个静止的局部最大值。但是如果他和光速一起移动,他会看到局部最大值。他在十二、十四岁左右就看到了这个矛盾,就知道了一切似乎都不对劲,光速运动也有一些特殊性质。那么,他是否仅仅是运气好最终创造了特殊相对论呢?他从初期的思考、片段性思考中奠定了某些基础,这是非常必要但不充分的条件。我要说的这些特点,是运气和实力的结合。

有没有众多“聪明”的人?听起来不错。可能在场的大部分人都有足够的智力去做出一流的工作。但伟大的工作不仅仅靠智商。智商有许多不同的衡量标准。在数学、理论物理和天体物理中,智商往往与操纵符号的能力高度相关,因此典型的智商测试得分较高。但在其他领域,情况就不同了。例如,Bill Pfann 这个做区域熔化实验的人曾经来找过我。他在脑中模糊地想到了自己想要研究的问题,并且有了一些方程式。很明显,他并不精通数学,也不太善于表达。他的问题似乎很有趣,所以我带回家研究了一下,最后我告诉他如何操作电脑以计算他自己的答案。我赋予了他计算能力。他在自己所在的部门几乎没有得到任何认可,但最终却获得了该领域所有的奖项。一旦他开始了,他的羞怯、笨拙和语无伦次都消失了,他在许多其他方面也变得更有成效,当然他的表达能力也得到了显著提高。

我还可以引用另一个类似的人来说明。他可能不在场,他叫 Clogston,他在约翰·皮尔斯的团队中为我解决了一个问题。我不认为他很有才华,我问学校里和他一起学习的我的朋友们:“他在研究生阶段也那样吗?”他们答复我:“是的。”然而我会解雇这个人,但 J.R. Pierce 很聪明,他留下了这个人。Clogston 最终发现了 Clogston 线缆,然后就有了源源不断的好点子,一次成功带给他自信和勇气。成功的科学家的特点之一就是勇气。一旦你勇往直前、相信自己能够解决重大问题,那么你就能够做到。如果你认为自己不能,那几乎肯定你是做不到的。勇气是伟大的科学家的特点之一。他们会在惊人的情况下继续思考和思考。那么香农的一个主要定理表达出了什么?他想创造一种编码方法,但他不知道该做什么,所以他就编了一个随机代码。然后他陷入困境。然后他问出了不可能的问题:“随机代码的平均效果如何?”然后他证明平均代码的效果是任意好的,因此必须至少有一个好的代码。除了拥有无限勇气的人,谁还能够想到那样的想法呢?这就是伟大的科学家的特征,他们有勇气。

年龄是物理学家特别担心的另一个因素。他们总是说你必须年轻时做好,否则你永远也做不好了。爱因斯坦很早就做了很多事情,所有的量子力学家也在做他们最好的工作时非常年轻。大多数数学家、理论物理学家和天体物理学家都在年轻时做出了我们认为最好的工作。不是他们年纪大了不做出好的工作,而是我们最重视的往往是他们年轻时做出的贡献。另一方面,在音乐、政治和文学方面,我们认为最好的作品通常是在晚年完成的。我不知道你所从事的领域如何符合这个规律,但年龄确实会产生一定的影响。但让我说一下为什么年龄似乎会产生这样的影响。首先,如果你做了一些好的工作,你会发现自己在各种委员会中,并且无法再做更多的工作。你可能会像我看到布拉坦那样,当他获得诺贝尔奖时。宣布获奖的那天,我们都聚集在阿诺德礼堂里;三位获奖者站起来讲话。第三个人,布拉坦,几乎含着眼泪说:“我知道这个诺贝尔奖的影响,我不会让它影响我;我会一直做好老华特尔·布拉坦。”我对自己说:“那很好。”但是几周后我发现它确实影响了他。现在他只能用于解决重大问题。当你出名后,很难解决小问题。这就是莫尔的问题所在。在信息理论之后,你还能干什么?许多杰出的科学家经常犯这个错误。他们不能继续从小事做起,而是试图一步到位。然而事情并不是这么简单的。这就是为什么你会发现,当你获得早期的认可时,它似乎会使你停滞不前。事实上,我会给你我的最爱之一,多年根据。在我的眼里,普林斯顿高等研究院毁了更多的优秀科学家,而不是创造了更多,根据他们来之前和之后所做的事情来判断。并不是他们到那里之后变得不好了,而是他们在到达那里之前是卓越的,到那里之后只是好的。这就引出了一个不按顺序的话题,即工作条件。大多数人认为最好的工作条件并不是最好的。很明显不是因为人们在工作条件很差的时候常常最有生产力。剑桥物理实验室最好的时期之一就是当他们几乎只有简陋的小屋 - 他们做出了一些最好的物理学。我来讲一个我自己的故事。我很早就意识到,贝尔实验室不会给我传统的让程序员用绝对二进制编程机器的一亩地。很明显他们不会这样做。但这是每个人都这样做的。我可以去西海岸,在飞机公司找到一份工作,不需要任何麻烦,但令人兴奋的人在贝尔实验室,而飞机公司的人并不这样。我思考了很长时间,想在这个两难的境地中如何才能得到最好的两个可能的世界。最后我对自己说:“Hamming,你认为机器几乎能做任何事。为什么你不能让它们写程序?”起初,我认为这是个缺陷,但它却把我推向了自动编程的道路。一开始看来似乎是个缺点,但是通过改变思路,它反而成为你最宝贵的财富之一。但当你第一次面对它,并说:“天哪,我永远不会得到足够的程序员,所以我怎么能做出好的程序设计?”的时候,你不太可能想到这一点。

还有许多类似的故事;格雷斯·霍珀(Grace Hopper)也有类似的经历。我认为,如果你仔细观察,会发现很多伟大的科学家通过稍微转换一下问题,将缺陷变成优点。例如,许多科学家在发现无法解决一个问题时,最终开始研究为什么无法解决它。然后他们将问题反过来,说:“当然,这就是答案”,并得出了重要的结果。因此,理想的工作条件非常奇怪。你想要的条件并不总是最适合你的条件。

现在谈到动力的问题。你会发现大多数伟大的科学家都有极强的动力。我曾在贝尔实验室与约翰·图基(John Tukey)共事十年。他有极强的动力。有一天,在我加入贝尔实验室三四年后,我发现约翰·图基比我年轻一点。约翰是个天才,而我显然不是。我愤怒地冲进鲍德(Bode)的办公室说:“为什么和我年龄相仿的人会像约翰·图基那样聪明?”他向后靠在椅子上,双手放在头后面,微微笑了一下,说:“如果你像他那样拼命工作这么多年,你会很惊讶的,你所知道的比他多得多。”我就这样灰溜溜地走出了办公室!鲍德的意思是:“知识和生产力就像复利。”假设有两个人的能力差不多,其中一个人比另一个人多工作 10%,后者将比前者产出超过两倍。你知道得越多,你学到的越多;你学到的越多,你能做的就越多;你能做的越多,机会就越多——这非常像复利。我不想告诉你一个具体的数字,但这是一个非常高的比率。假设有两个能力完全相同的人,那么那个每天都多思考一个小时的人,一生中将会非常有成就。我认真对待了鲍德的话;为了努力工作更多的时间,我放弃了很多事情。这是没有疑问的。

关于驱动力的问题,爱迪生说:“天才的 99% 是汗水,1% 是灵感。”他可能有所夸张,但是这个想法是坚实的工作,持之以恒,会使你达到令人惊讶的高度。用一点点额外的工作,加上明智的应用,就可以做到这一点。问题在于,驱动力,如果被错误地运用,就不会带来任何成果。我常常想知道,为什么在贝尔实验室与我一起工作并且像我一样或者更努力的好朋友们,却没有我有那么多的成果。误用努力是个非常严重的问题。仅仅是努力工作是不够的——必须明智地应用它。

还有一个我想谈谈的特点;那就是歧义性。我花了一些时间才发现它的重要性。大多数人喜欢相信某件事是真的还是假的。伟大的科学家非常善于容忍歧义性。他们相信这个理论,足以继续前进;他们对它有所怀疑,足以注意错误和缺陷,以便向前迈进,创建新的替代理论。如果你过于相信,你永远不会注意到缺陷;如果你过于怀疑,你不会开始。这需要一种可爱的平衡。但是,大多数伟大的科学家非常清楚他们的理论为什么是正确的,他们也非常清楚一些不太合适的小问题,并且不会忘记它们。达尔文在自传中写道,他发现有必要将每个与他的信念相反的证据都写下来,否则它们就会从他的脑海中消失。当你发现明显的缺陷时,你必须敏感并跟踪这些事情,留意它们如何可以解释,或者理论如何可以被改变以适应它们。这些常常是伟大的贡献。伟大的贡献很少仅仅是多加一位小数,它归根结底是情感的承诺。大多数伟大的科学家完全致力于他们的问题。那些不致力于问题的人很少能够产生杰出的一流作品。

现在,情感承诺并不足够。显然,这是一个必要的条件。我想我能告诉你为什么。所有研究创造力的人最终都会说,“创造力来自你的潜意识。”不知何故,突然间它就出现了。我们知道潜意识很少,但你很清楚的一件事就是你的梦也来自你的潜意识。你知道你的梦,在很大程度上,是对一天的经历的重新加工。如果你深入沉浸并致力于一个主题,日复一日,你的潜意识只有处理你的问题。所以你某天早上醒来,或者某个下午,答案就在那里了。对于那些不专注于当前问题的人来说,意识会放松并转向其他事物,无法产生巨大的结果。所以管理自己的方法就是,当你有一个真正重要的问题时,不要让其他任何事情成为你关注的中心 - 保持你的思想集中在问题上。让你的潜意识需要处理你的问题,这样你就可以安心睡觉,在早上获得自由的答案。现在艾伦·奇诺维斯提到我曾经在物理学表上吃饭。我曾经和数学家们一起吃饭,发现我已经知道相当多的数学;事实上,我没有学到很多。正如他所说,物理学表是一个令人兴奋的地方,但我认为他夸大了我的贡献。听 Shockley,Brattain,Bardeen,J.B.约翰逊,Ken McKay 和其他人讲话很有趣,我学到了很多。但不幸的是,诺贝尔奖和晋升来了,剩下的只有渣滓了。没有人想要剩下的。既然没用吃他们!食堂的另一边是一张化学桌。我曾和其中一个家伙,戴夫·麦考尔合作过;此外,他当时正在追求我们的秘书。我走过去说,“你介意我加入吗?”他们不能说不,所以我一段时间内开始和他们一起吃饭。然后我开始问,“你们领域的重要问题是什么?”再过一周左右,“你们正在处理哪些重要问题?”再过一段时间,我一天走进去说,“如果你正在做的事情不重要,而且如果你不认为它会导致重要结果,那么你为什么在贝尔实验室工作?”之后我就不受欢迎了;我不得不找别人一起吃饭!那是在春天。到了秋天,戴夫·麦考尔在走廊上拦住了我,说:“Hamming, 你那句话惹恼了我,我整个夏天都在想,即我的领域中有哪些重要问题。我的研究没有改变,”他说,“但我认为它是非常有价值的。”我说,“谢谢,戴夫。”事后我注意到,几个月后他被任命为部门负责人。我最近注意到,他成为了国家工程院的成员。我注意到他已经成功了。我从未听说过该表的其他人在科学和科学圈子中的名字。他们无法问自己,“我领域中的重要问题是什么?”如果你不解决一个重要的问题,你很少会做出重要的工作。这是非常明显的。伟大的科学家已经以审慎的方式思考过自己领域中的一些重要问题,并且一直关注如何攻击这些问题。让我警告你,“重要问题”必须仔细措辞。从某种意义上说,物理学中的三个突出问题在我在贝尔实验室期间从未被研究过。我所说的重要是指获得诺贝尔奖和你想提出的任何金额的问题。它们并不是重要的问题,因为我们没有攻击。重要的问题并不在于后果,而在于你有一个合理的攻击。这就是使问题重要的原因。当我说大多数科学家不解决重要问题时,我是指在这个意义上。就我所知,普通科学家几乎所有的时间都在解决他认为不重要的问题,并且他们也不相信这些问题会导致重要问题。

我之前谈论过播种橡子以生长橡树的事情。你不总能准确地知道在哪里会有机会,但你可以在可能发生事情的地方保持活跃。即使你相信伟大的科学是幸运的结果,你也可以站在闪电击中的山顶上;你不必躲在安全的山谷里。但是平均科学家几乎一直在进行例行而安全的工作,因此他(或她)没能有所成就。很简单,如果你想做出伟大的工作,你必须明确地工作在重要问题上,并且你应该有一个想法。沿着这条线,在 John Tukey 等人的敦促下,我最终采用了我所称的“伟大思想时间”。星期五中午我去吃午饭时,之后我只谈论伟大的思想。我所说的伟大思想是指:“在 AT&T 中计算机将发挥什么作用?”“计算机会如何改变科学?”比如,我那时发现九成的实验是在实验室里完成的,只有一成是在计算机上完成的。我曾向副总裁们发表评论,即这种情况将被逆转,即九成的实验将在计算机上完成,只有一成在实验室里完成。他们知道我是一个疯狂的数学家,没有现实感。我知道他们错了,而我是正确的。他们建造实验室,但他们并不需要。我看到计算机正在改变科学,因为我花了很多时间询问“计算机对科学的影响将会是什么,我该如何改变呢?”我问自己,“这将如何改变贝尔实验室?”在同一个演讲中,我曾说过,在我离开之前,贝尔实验室的一半以上的人将会与计算机接触密切。现在,你们都有终端了。我认真考虑我的领域会走向何方,哪里有机会,哪些事情是重要的。让我去那里,这样我就有机会做重要的事情。大多数伟大的科学家知道许多重要的问题。他们有 10 到 20 个重要的问题需要攻击。当他们看到一个新的想法出现时,就会听到他们说:“这很有关系。”他们会放下其他所有的事情,开始行动。现在我可以告诉你一个恐怖的故事,这是我听说过的,但我不能保证它的真实性。我和一位来自洛斯阿拉莫斯的朋友坐在机场里,谈论到幸运的是,裂变实验发生在欧洲,因为那让我们在美国开始了原子弹计划。他说:“不,我们在伯克利收集了一堆数据;我们没有时间对其进行分析,因为我们正在建造更多的设备,但如果我们对这些数据进行了分析,我们就会发现裂变。”他们手里拿着这份资料,却没有去追求它。他们只是获得了第二名!当一个机会出现时,伟大的科学家会去追求它。他们放下其他的事情,追求这个想法,因为他们已经把这件事想通了。他们的思维已经做好准备了;他们看到了机会,他们去追求它。当然,很多时候它不起作用,但你不需要击中很多次,就可以做出一些伟大的科学。这很容易。其中一个主要的诀窍是长寿!另一个特点,我花了一段时间才发现。我注意到与门开着或门关着工作的人的以下事实。我注意到,如果你的办公室门关闭,你今天和明天会完成更多的工作,你比大多数人更有生产力。但是 10 年后,你不太知道哪些问题值得解决;你所做的所有艰苦工作在重要性上都有些离题。那些与门开着工作的人会有各种各样的干扰,但他们也偶尔能够得到世界和可能重要的东西的提示。现在我无法证明因果关系,因为你可能会说,“关闭的门是心灵关闭的象征。”我不知道。但我可以说,那些与门打开工作的人和那些最终做出重要成果的人之间有相当大的相关性,尽管门关闭的人通常工作更努力。不知怎的,他们似乎一直在做错事情——不算太多,但足以错过荣誉。

我想谈另一个话题。它基于一首歌,我认为你们中的许多人都知道,“不是你做什么,而是你做的方式。”我将以自己的一个例子开始。在绝对二进制时代,我被骗去使用数字计算机解决一个连最好的模拟计算机都无法解决的问题。我正在得到一个答案。当我仔细思考并对自己说,“你知道,Hamming,你将不得不就这个军事工作提交一份报告;在你花费大量的钱之后,你将不得不解释它,并且每个模拟安装都会要求报告,以查看是否能找到任何缺陷。”我正在使用相当差劲的方法来进行所需的积分,最起码可以这么说,但我正在得到答案。我意识到,事实上问题不仅是要得到答案;这是第一次,毫无疑问,证明我可以用数字机器在模拟计算机的基础上取得胜利。我重新设计了解决方法,创建了一个漂亮而优雅的理论,并改变了计算答案的方式;结果没有任何不同。发表的报告采用了一种优雅的方法,后来被称为“Hamming 微分方程积分方法”,并被知道多年。现在它有点过时了,但曾经是一种非常好的方法。通过稍微改变问题,我做了重要的工作,而不仅仅是微不足道的工作。同样地,在早期使用阁楼上的机器时,我一个接一个地解决了一个又一个问题;相当多的是成功的,也有一些失败的。有一天我星期五上完课回家,偶然地,我不高兴;我沮丧了。我可以看到生活是一个长长的问题序列。经过相当长一段时间的思考,我决定,“不,我应该是可变产品的大规模生产者。我应该关注明年所有的问题,而不是只关注我面前的问题。”通过改变问题,我仍然得到了同样类型的结果或更好的结果,但我改变了事情并做了重要的工作。我攻击了主要问题 - 我如何征服机器并在我不知道它们将要面对的情况下解决明年所有问题?我如何为此做好准备?我如何做这个,所以我会掌控它?我如何遵守牛顿的规则?他说,“如果我比别人看得更远,那是因为我站在巨人的肩膀上。”这些天我们彼此踩脚!你应该用这样的方式做你的工作,这样别人就可以建立在它的基础上,这样他们确实会说,“是的,我站在某某的肩膀上,我看得更远了。”科学的本质是累积的。通过稍微改变问题,你经常可以做出伟大的工作,而不仅仅是好工作。我决定再也不解决孤立的问题,而只是解决一类问题的特征。如果你是一名数学家,你会知道概括的努力通常意味着解决方案很简单。经常通过停下来说,“这就是他想要的问题,但这是某一个特定的问题。是的,我可以用一种比特定问题更优异的方法攻击整个类,因为我之前嵌入了不必要的细节。”抽象的业务经常使事情变得简单。此外,我将这些方法存档并为未来的问题做好了准备。为了结束这一部分,我提醒你,“怪工匠总是责备工具——好人会用他手头的工具干好工作,并尽力得到最好的答案。”我建议,通过改变问题,通过不同的视角来看待事物,你可以在最终的生产力上做出很大的改变,因为你可以以一种人们确实可以建立在你所做的事情上的方式来做这件事,或者你可以以这样的方式来做这件事,以至于下一个人不得不本质上再次复制你所做的一切。它不仅仅是一个问题的问题,而是你撰写报告的方式,写论文的方式,整个态度。做一个广泛、普遍的工作就像做一个特殊的案例一样容易。这样做更加令人满意,更有收获!

我现在谈的话题非常不受欢迎;光做好一件事是不够的,你还要把它卖出去。对于一个科学家来说,“卖”的确令人不爽。这很丑陋;你不应该这样做。这个世界应该在等待,当你做出伟大的成就时,他们应该迫不及待地赞扬。但事实是每个人都忙于自己的工作。你必须把它呈现得很好,让他们放下手边所有的事情,关注你做的事情,阅读它,然后回来说,“好的,做得很好”。我建议你在打开期刊时,翻阅页面时问自己为什么读一些文章而不读其他文章。你最好写一篇报告,让它在《物理评论》或任何你想发布的其他期刊上发表时,读者翻阅页面时不会只翻开你的页面,而会停下来阅读你的文章。如果他们不停下来阅读,你就得不到认可。卖出一个东西有三件事情你必须做到。你必须学会清晰流畅地写作,以便人们会读它;你必须学会发表适当正式的演讲;你还必须学会发表非正式的演讲。我们有很多所谓的“后院科学家”。在一个会议上,他们会保持沉默。三周后做出决定后,他们会提交一份报告,说明为什么应该这样做那样做。这太迟了。他们不会在热烈的会议中间,中途站起来说,“因为这些原因,我们应该这样做。”你需要掌握这种沟通形式以及准备好的演讲。当我刚开始的时候,我在发表演讲时几乎身体不适,非常紧张。我意识到我必须要学会流利地演讲,否则我将永远陷入这种状态。当 IBM 第一次要求我在纽约发表演讲时,我决定要发表一篇非常好的演讲,一篇他们所想要的演讲,不是技术上的,而是宏观的,如果他们喜欢的话,我会悄悄地说,“如果你们需要演讲,我会来做的。”结果,我得到了很多向有限的观众发表演讲的练习机会,并克服了害怕的心理。此外,我还可以研究哪些方法有效,哪些方法无效。在参加会议时,我已经在研究为什么一些论文会被记住,大多数论文会被遗忘。技术人员想发表高度专业的演讲。大多数时候,观众希望听到一个广泛的普及性演讲,并且需要更多的调查和背景知识,而演讲者不愿意提供。因此,很多演讲是无效的。演讲者列出一个话题,然后突然就进入了他们已经解决的细节。很少有人能够跟得上。你应该给出一个总体的画面,以解释为什么这很重要,然后慢慢地介绍做了什么。那么更多的人会说,“是的,乔已经做到了这一点”,或者“玛丽已经做到了这一点;我真的看到了它的重要性;是的,玛丽的演讲很好。”倾向于发表极度局限、安全的演讲,这通常是无效的。此外,许多演讲充斥着太多的信息。所以我说,这个卖出的思想是显而易见的。 让我总结一下。你必须处理重要的问题。我否认这全部都是运气,但我承认里面有相当一部分运气。我赞成巴斯德的“运气青睐有准备的头脑”。我非常赞同我所做的事。多年来,每个星期五的下午 - 只考虑伟大的想法 - 就意味着我投入了 10% 的时间来努力了解领域中更重要的问题,即什么是重要和什么不重要的问题。我发现在早期,我相信“这一点”,但一周的时间却走向了“那个”方向。这有点愚蠢。如果我真的相信行动在那边,为什么我要走向这个方向?我要么改变我的目标,要么改变我的行为。所以我改变了我做的事情,我走向了我认为是重要的方向。这很容易。

现在你可能会告诉我,你对你要处理的事情没有控制权。好吧,当你刚开始时,你可能确实没有。但是一旦你取得了一定的成功,有更多的人要求结果,而你有一些选择权,但不是完全的。我要告诉你一个故事,这与教育你的老板有关。我有一个老板叫舍尔克诺夫;他现在还是我的一个非常好的朋友。有个军事人员来找我,要求我在周五之前给出一些答案。好吧,我已经把我的计算资源用来为一组科学家实时处理数据了;我正忙于解决许多短小而重要的问题。这个军事人员想让我在周五下班前解决他的问题。我说,“不,我会在周一给你。我可以在周末工作。我现在没时间。“他去找我的老板,舍尔克诺夫,舍尔克诺夫说,“你必须为他运行这个程序;他必须在周五之前得到答案。“我告诉他,“为什么要我?“他说,“你必须。“我说,“好的,谢尔盖,但你在周五下午坐在你的办公室,等这个家伙走出那扇门的时候,你就可以回家了。“我在周五下午很晚才给这个军事人员答案,然后我去了舍尔克诺夫的办公室坐下来;当这个人走出去的时候,我说,“你看,舍尔克诺夫,这个家伙什么都没拿,但我给了他答案。“周一早上舍尔克诺夫给他打电话,问他周末来上班了吗?我听到了那个人的一瞬间的停顿;但他知道他必须签到,而且他最好不要说他做了,因为他没有,所以他说他没有。从那以后,舍尔克诺夫说:“你设定你的截止日期;你可以改变它们。“一次经历足以教育我的老板为什么我不想做那些取代探索性研究的大型项目,为什么我有理由不做吸收所有研究计算设备的紧急项目。相反,我想利用这些设施来计算大量的小问题。同样,在早期,我在计算能力方面受到限制,很明显,在我的领域里,“数学家没有机器的用途。”但是我需要更多的机器容量。每次我告诉其他领域的科学家:“不,我不能;我没有机器容量。”他们都抱怨。我说,“去告诉你们的副总裁,哈明需要更多的计算容量。”过了一段时间,我可以看到顶层发生的事情;许多人对我的副总裁说:“你的人需要更多的计算能力。”我得到了它!我还做了第二件事。当我把我们拥有的很少的编程力借给计算机早期的工作时,我说,“我们的程序员没有得到应有的认可。当你发表论文时,你会感谢那位程序员,否则你不会得到我的帮助。那位程序员将按姓名被感谢;她工作很努力。”我等了几年。然后我通过 BSTJ 文章进行了一年的计数,计算了有多少篇文章感谢了某个程序员的贡献。我拿着这些文章到老板那里去,告诉他,“这是计算机在贝尔实验室中发挥的核心作用;如果 BSTJ 很重要,那么计算机就很重要。”他不得不让步。你可以教育你的老板。这是一项艰巨的任务。在这次演讲中,我只从下往上看;我没有从上往下看。但我告诉你,你可以不顾顶层管理,做到自己想要的。你也必须在那里销售你的想法。现在我要谈谈这个话题,“成为一名伟大的科学家的努力是否值得?”为了回答这个问题,你必须问问别人。当你超越他们的谦虚时,大多数人会说,“是的,做真正的一流工作,并知道它是一件好事,就像同事、女人和歌声放在一起一样好,”或者如果是一个女人,她会说,“它就像葡萄酒、男人和歌声结合在一起一样好。”如果你看看老板们,他们 tend to come back or ask for reports, trying to participate in those moments of discovery. They’re always in the way. 显然,那些已经做过的人想再次尝试。但这是一个有限的调查。我从来没有敢去问那些没有做出伟大成就的人对这件事的看法。这是一个有偏见的样本,但我仍然认为这个努力是值得的。我认为,努力做一流的工作是非常值得的,因为实际上,价值在于努力而不是结果。努力使自己变得更好似乎本身就是值得的。成功和名气只是回报,我觉得。我告诉过你如何做到这一点。这是如此容易,那么为什么有那么多人,他们拥有所有的才能,但还是失败了呢?例如,我认为,在贝尔实验室的数学系里,有很多人比我能力更强、更有天赋,但他们没有产生更多的东西。他们中的一些人确实比我产生了更多的东西;香农比我产生的东西多,还有其他一些人也产生了很多,但和其他几个同事相比,我的产出率很高,他们的装备比我好很多。发生了什么事?他们怎么了?为什么那么多有很大潜力的人会失败?

其中一个原因是驱动力和承诺。那些虽然能力不足但对工作承诺的人比那些本领高超但是只是半途而废,一天工作后回家做其他事情,第二天再回来工作的人更能完成更多的任务。前者有一种似乎是真正必要的深刻承诺,可以创造出一流的工作。虽然后者也能产出很多优秀的工作,但我们讨论的是一流的工作,这其中有所不同。优秀、非常有才华的人几乎总能创造出优秀的工作,但我们不能忽视一流的工作——那些赢得诺贝尔奖并获得认可的工作。第二个原因我认为是个性缺陷。现在我会举一个我在尔湾遇到的人的例子。他曾是一个计算中心负责人,目前正作为大学总裁特别助理的临时工作。很明显,他有一个光明前途的工作。他曾经带我进他的办公室,向我展示他的写信方法以及如何处理信件。他指出了他的秘书有多么效率低下。他把他的所有信件都放在那里,但他知道每一个信件的位置。接着他在他的文字处理机上写出了那封信。他炫耀这是多么神奇,说这样他能不受秘书的干扰就完成更多的工作。然而,在他背后,我和他的秘书谈了谈。秘书说:“当然,我帮不了他,我不懂他的邮件在哪里。他不给我登记的信件,我不知道他把它放在地板上哪里。当然我帮不了他。”所以我就对他说: “听着,如果你采用现在的方法,单枪匹马地完成你能做的工作,你只能完成你能单枪匹马做到的那么多。如果你学会与这个系统合作,你能做到系统所能支持的一切。”不过,他从来没有进展过了。他有他的个性缺陷,想要完全控制一切,不想认识到需要系统的支持。同样的事情一遍遍的发生:好的科学家会与系统作斗争而不是学会与系统合作,利用系统提供的一切。如果你学会了如何使用系统,你会发现系统有很多用处。虽然这需要耐心,但是你可以学会如何运用系统,也可以学会如何绕过系统。毕竟,如果你想得到一个“不”的答案,直接去问你的老板就好了。如果你想做一些事情,不要问,直接去做。把已经完成的事情拿给他看。不要给他说“不”的机会。但是,如果你想得到一个“不”的答案,就很容易得到。另一个个性缺陷是自我主张,我将在本例中谈谈我的经历。我来自于洛斯阿拉莫斯,在早期我在纽约的 590 麦迪逊大道使用一台机器,我们仅仅是租用了时间。当时我还穿着西装,带有大口袋,蝴蝶领,以及其他的一些东西。我模糊地注意到,我没有得到像其他人一样好的服务。于是我开始衡量。你进去等你的机会;我感觉我没有得到公平的对待。我对自己说:“为什么?IBM 的副总裁从来没有说过‘给哈明惹麻烦’。是处在底层的秘书们在这样做。当有一个名额出现的时候,他们会急急忙忙地去找人,却去找了别人。为什么?我没有虐待他们。”答案是,我穿着方式不符合他们在这种情况下应该有的方式。这都归结为一个问题——我没有合适的着装打扮。我必须做出决定——我是要主张我的自我,穿着自己想穿的衣服,让它不断地消耗我的精力和职业生涯,还是要做出符合标准的着装。我决定,我会努力让自己看起来更符合标准。我一旦这样做了,服务就好多了。现在身为一个身上色彩鲜艳的老角色,我得到的服务比其他人好很多。你应该根据听众的期望打扮。如果我要在 MIT 电脑中心发表演讲,我会穿一个套索和一个旧灯芯绒夹克,或其他东西。我知道不能让我的服装、外表和神态妨碍我关心的事情。很多科学家感觉他们必须主张自己的自我,以自己的方式去做自己的事情。他们必须能够做到这个、那个或者其他的一些事情,而他们会付出一个稳定的代价。

约翰·图基几乎总是穿得非常休闲。他会进入一个重要的办公室,其他人要花很长时间才意识到这是一个一流的人物,他最好听一听。很长一段时间以来,约翰一直不得不克服这种敌意。这是徒劳的努力!我没有说过你应该顺从;我说,“装出符合规范的外观会让你走得更远。”如果你选择以任何可能的方式断言自己的自我,“我会按照我的方式做”,你会在整个职业生涯中付出一个小而稳定的代价。而这在整个生命中,会累积成许多不必要的麻烦。通过向秘书讲笑话和多交朋友,我得到了出色的秘书帮助。比如有一次出于某种白痴的原因,莫雷山的所有复制服务都被卡住了。别问我为什么,但它们确实被卡住了。我想做点事情。我的秘书打电话给霍姆德尔的某个人,乘坐公司车,花了一小时的时间走了一遍,把它复制了回来,然后回来了。这是我现在能得到的回报,因为我为了让她高兴一点,讲笑话,多交朋友;那是我付出的那点额外工作,后来为我带来了回报。通过认识到你必须使用这个系统,并学习如何让系统为您工作,您将学会如何将系统适应您的愿望。或者,您可以像进行小规模未宣布的战争一样,一直与它作斗争,直到您的一生结束。我认为约翰·图基不必要地付出了可怕的代价。他无论如何都是个天才,但我认为如果他愿意顺从一点而不是表现自我,情况会变得更好,更简单。他会一直这样穿衣服。它不仅适用于着装,也适用于其他许多事情;人们会继续与体制作斗争。并不是说你不应该偶尔这样做!当他们把图书馆从莫雷山中心搬到远端时,我的一个朋友提出了一个请求,要求得到一辆自行车。那么这个组织并不愚蠢。他们等了一会儿,就送回一张地图,说:“请在这张地图上标出你要走的路径,这样我们就可以为你提供保险。”又过了几个星期。然后他们问,“你要把自行车放在哪里,怎么锁上,这样我们就可以做某些事情。”他最终意识到,当然他会遭到无数耗时的付出,所以他放弃了。他后来成为贝尔实验室的总裁。巴尼•奥利弗是个好人。有一次他写信给 IEEE。当时贝尔实验室的官方货架空间很大,而 IEEE 的论文集高度更大。既然你不能改变官方货架空间的大小,他就写信给 IEEE 的出版人说,“既然这么多 IEEE 会员在贝尔实验室工作,而官方空间那么高,那么期刊的大小就应该改变。”他把信送给了他的老板签名。回来的是一份他签名的复印件,但他仍然不知道原件是否被送出。我并不是说你不应该做出一些改革的姿态。我是说,我对能人的研究表明,他们不会将自己承诺到那种战争中去。他们会稍微玩一下,然后放弃,继续他们的工作。

许多二流子都被某些系统的小问题缠住,一拍即合,将其转化成战争。他浪费自己的精力在一个愚蠢的项目上。现在你要告诉我有人必须改变系统。我同意;必须有人。你想成为哪一个?改变系统的人还是第一流的科学家?你想成为哪一个?当你与系统斗争和努力时,要清楚自己在做什么,玩的有多远,浪费多少精力与系统斗争。我的建议是让别人去做,而你继续成为一名一流的科学家。很少有人具备改革系统和成为一流科学家的能力。另一方面,我们不能总是妥协。有时候一定量的反叛是明智的。我观察到几乎所有科学家都享受某种程度的戏弄系统的乐趣。基本上,原创性在其他领域没有不同。你不能成为一个原创性的科学家而在其他方面没有一些原创性特质。但许多科学家让他们在其他领域的怪癖让他们付出了比满足自尊心更高的代价。我不反对所有的自我主张;我反对某些自我主张。另一个缺点是愤怒。科学家经常变得愤怒,这是处理事情的错误方式。娱乐,对,愤怒,不。愤怒是错误的。你应该跟随并合作,而不是一直与系统斗争。另一件你应该寻找的事情是事情的积极面而不是消极面。我已经给你们几个例子了,还有许多许多,通过改变我看待事物的方式,我将显然的缺点转化为优点。我给你举个例子,我是一个自负的人;毫无疑问。我知道大多数休学写书的人不能按时完成。所以在我离开之前,我告诉所有的朋友,当我回来的时候,那本书就完成了!是的,我会完成它——我会羞于回来没有它的!我利用我的自负来使自己按照自己的意愿行事。我吹嘘了一些事情,所以我必须表现出色。我发现很多时候,就像一个陷入真正陷阱的老鼠,我很惊讶自己的能力。我发现说,“噢,是的,我会在星期二给你答案,不知道怎么做。”没有任何想法。到星期天晚上,我正在深思熟虑如何在星期二之前交付。我经常把自己的骄傲放在一条线上,有时我失败了,但正如我所说的,像一个陷在困境中的老鼠一样,我很惊讶自己有多少次做得很好。我认为你需要学会利用自己。我认为你需要知道如何将一个情况从一种观点转化为另一种观点,这将增加成功的机会。现在自我欺骗在人类中非常普遍。您可以通过众多的方式改变事物,欺骗自己,使其看起来有所不同。当你问,“为什么你不做这样那样的事情?”这个人有一千个托辞。如果你看科学的历史,通常这些天就有 10 个人准备好了,我们支付给先到的那个人。其他九个家伙说,“嗯,我有这个想法,但我没有去做等等。”有这么多的托辞。你为什么不是第一?你为什么没做好?不要试图编造托辞。不要欺骗自己。你可以告诉别人所有的托辞,我不介意。但对于自己,尽量保持诚实。

如果你真的想成为一名一流的科学家,你需要了解自己,自己的弱点,优势和执念,比如我的自负。你如何将缺点转化为资产?在你没有足够的人力来达成目标时,如何才能朝着正确的方向前进?我再次强调,我的研究表明,成功的科学家改变了观点,原来的缺点变成了资产。总之,我认为许多掌握成功要诀的人未能成功的原因有以下几点:他们没有从事重要的问题、没有投入感情,没有试图改变困难的情况,未将其转化为容易完成但仍然重要的情况,还在寻找借口。他们还认为这是运气问题。我已经告诉过你们,这很容易,而且我也告诉过你们怎么改变。因此,大家去成为伟大的科学家吧!(正式讲话结束)。 讨论 - 问题与答案: A. G.奇诺维斯:好吧,这是 50 分钟的集中智慧和观察,积累自一个非凡的职业生涯。我迷茫了,所有那些观察都很适时。其中一个是对更多的计算机容量的呼吁;今天早上我从几个人那里听到的都是这个,一遍一遍地重复。因此,即使我们离您发表类似言论的时间已经过去 20-30 年,今天仍然非常准确。我想所有人都可以从您的讲话中获得各种各样的经验教训。作为其中之一,将来当我在走廊上走动时,我希望不会看到太多 Bellcore 的封闭门。我认为这是一个非常有趣的观察。

非常感谢你,迪克,那是一段美好的回忆。现在我会开放问题。我相信有很多人想发表一些迪克所说的观点。海明:首先,让我回应艾伦·奇诺维斯关于计算机的问题。我在研究中使用计算机,十年来一直告诉我的管理层,“把那个该死的机器从研究中移除。我们被迫一直解决问题。我们没法研究,因为我们太忙于操作和运行计算机。“最后信息传达开了。他们要将计算机移出研究到其他地方。我是名不雅的人,至少我很惊讶人们没有踢我,因为每个人都会从他们那里夺走他们的玩具。我走进埃德·大卫的办公室,说:“看,埃德,你必须给你的研究人员一台计算机。如果你给他们一台非常大的机器,我们会遇到同样的问题,每个人都忙于保持运行,我们没法思考。给他们最小的机器,因为他们非常有能力。他们将学会在小机器上做事,而不是在计算中心。”就我而言,这就是 UNIX 的来源。我们给了他们一台相当小的机器,他们决定在上面做大事情。他们必须想出一个系统来完成。这就是 UNIX!A.G.奇诺威思:我必须对此发表看法。在我们目前的环境中,迪克,尽管我们在应对监管机构要求的某些繁文缛节问题时,有一句话,一个沮丧的副总裁给出了这句话,我已经一遍又一遍地使用了它。他咆哮道:“UNIX 从来不是交付项!”问题:个人压力呢?这似乎有所不同吗?海明:是的,有所不同。如果你没有情感投入,问题就不大。我在贝尔实验室大部分年份都有潜在的溃疡。自那以后,我离开了海军研究所,放松了一些,现在我的健康要好得多。但是,如果你想成为一位伟大的科学家,你将不得不忍受压力。你可以过着美好的生活;你可以成为一个好人,或者你可以成为一个伟大的科学家。但是好人最后总是落后的,列奥·杜洛切尔说的话是这样的。如果你想过着美好的快乐生活,享受很多娱乐活动,你将过着美好的生活。

问题:关于勇气的评论无可非议;但我们这些头发灰白或已经成就很高的人就不用太担心了。但我感觉现在的年轻人在高度竞争的环境中真正担心的是冒险。您对此有何建议?

Hamming:我再引用一下 Ed David 的话吧。Ed David 对我们社会普遍的失去勇气非常担心。在我看来,我们经历过各种各样的时期。从战争中走出来,从洛斯阿拉莫斯制造出原子弹,从制造雷达等等一系列工作中,数学专业和研究领域出现了一群非常有胆识的人。他们刚刚见过一些事情被完成;他们刚刚赢得了一场惊人的战争。我们有勇气是有原因的,因此我们做了很多事情。我不能安排让这种情况再次发生。我不能责怪现在的一代人没能做到,但我同意您所说的;我只是不能归咎于他们。在我看来,他们似乎没有追求伟大的欲望;他们缺乏做到这一点的勇气。但我们有这种勇气,因为我们处在一个有利的环境中;我们刚刚走过了一场非常成功的战争。在这场战争中,我们一直处于非常艰难的境地;如您所知,这是一场非常绝望的斗争。我们的成功,我认为,给了我们勇气和自信;这就是为什么您可以看到,在上世纪四十年代末到五十年代之间,实验室出现了巨大的生产力,这是从早期开始刺激的。因为我们许多人早期被迫学习其他东西——我们被迫学习我们不想学的东西,我们被迫打开大门——然后我们可以利用我们所学的东西。这是事实,我无能为力;我也不能指责现在的一代人。这只是事实。

问题:管理层能或应该做些什么?

Hamming:管理层能做的很少。如果您想谈论如何管理研究,那就完全不同了。我要再花一个小时来做这件事。这次讲话是关于个人如何在任何管理或其他反对的情况下完成非常成功的研究的。那怎么做?就像我观察到的人所做的那样。这既简单又困难!

问题:头脑风暴是日常过程吗?

汉明:曾经那是很受欢迎的事情,但似乎并没有带来好处。对我来说,与其他人交谈是可取的,但头脑风暴的效果很少。我会去严肃地与某个人交谈,告诉他们,“瞧,我认为这里一定有些东西。我看到了什么……”然后开始交谈。但你需要选择有能力的人。用另一个类比,你知道“关键质量”的想法。如果你有足够的东西,你就有了关键质量。我曾经使用过的另一个想法是“吸声体”。当你有太多吸声体时,你提出一个想法,他们仅仅说,“是的,是的,是的。”你想要做的是让那个关键质量发挥作用。“是的,这使我想起了某某人,”或者“你有没有想过这个或那个?”当你与其他人交谈时,你想要摆脱那些只会说“哦,是的”的吸声体,并找到那些会立即激发你的人。例如,你不能和约翰·皮尔斯谈话而不受到迅速的刺激。我曾经与另一组人交谈。例如,有埃德·吉尔伯特;我经常去他的办公室问他问题,倾听,并受到刺激回来。我仔细选择与谁或不与谁头脑风暴的人,因为吸声体是一种诅咒。他们只是好人;他们充满了整个空间,除了吸收想法,他们什么都不做,新的想法仅仅消失而不是反响。是的,我发现与人交谈是必要的。我认为关起门来的人没有这样做,所以他们不能使他们的思想精细化,比如“你有没有注意到这里的什么?”我以前什么都不知道,现在可以过去看看。有人指引的方向。在我来访这里时,我已经发现了回家后必须要看的几本书。我与人交谈,认为他们可以回答我的问题并给我提供我不知道的线索。我出去看看!问题:在分配阅读、写作和实际研究的时间时,你做了哪些取舍?汉明:在我早期,我认为你应该花费至少与原始研究一样多的时间来精炼和展示。现在,至少有 50%的时间必须花在展示上。这是一个很大很大的数字。问题:图书馆工作应该投入多少精力?

汉明码:这取决于领域。我可以说这个。贝尔实验室有一个非常聪明的家伙。他总是在图书馆里;他读了所有的文章。如果你需要参考文献,你去找他,他会给你各种各样的参考文献。但是在制定这些理论的过程中,我提出了一个命题:长远来看,不会有一种效应以他的名字命名。他现在从贝尔实验室退休了,并且是一名兼职教授。他非常有价值;我不会对此产生质疑。他写了一些非常好的物理评论文章;但是没有一种效应以他的名字命名,因为他读太多了。如果你一直阅读其他人做的事情,你会思考他们的思维方式。如果你想要有不同的新思想,那么就像很多有创造力的人一样——把问题想得相当清楚,然后拒绝看任何答案,直到你仔细思考了问题如何解决,如何微调问题才能获得正确的答案。所以,你需要跟上潮流。你需要更了解一下问题是什么,而不是阅读答案。阅读是为了知道正在发生什么和可能发生什么,这是必要的。但是阅读以获得答案似乎不是做出伟大研究的方法。所以我会给你两个答案。你需要阅读;但重要的不是数量,而是你阅读的方式。问题:你如何让你的名字与事物联系起来?汉明码:通过出色的工作。我告诉你汉明窗口是怎么回事。我多次给图基惹了麻烦,他从普林斯顿打来电话给我在默里山的电话。我知道他在写功率谱,他问我是否介意他把某个窗口称为“汉明窗口”。我对他说:“来吧,约翰;你非常了解,我只做了一小部分工作,你也做了很多。”他说:“是的,汉明,但你做出了很多小的贡献;你有权享受一些荣誉。”所以他称它为汉明窗口。现在让我接着说。我经常嘲笑约翰真正的伟大。我说真正的伟大是当你的名字像安培、瓦特和傅里叶一样——用小写字母拼写的时候。这就是汉明窗口产生的原因。问题:迪克,你愿意评论发表演讲、写论文和写书之间的相对有效性吗?汉明:短期内,如果你想在明天激励某个人,论文非常重要。如果你想获得长期的认可,似乎写书对于贡献更大,因为我们大多数人需要方向。在这个几乎无限知识的时代,我们需要定位来找到方向。让我告诉你无限知识是什么。从牛顿到现在,我们几乎每 17 年就会接近翻倍的知识,或多或少。我们基本上通过专业化来应对这种情况。在接下来的 340 年里,以这种速度,将有 20 次翻番,即一百万个领域对于现在的一个领域。这是不可能的。现有的知识增长将窒息自己,直到我们拥有不同的工具。我相信,那些试图消化、协调、摆脱重复、摆脱不那么有成效的方法并清晰地呈现现在我们所知道的基本思想的书将是未来几代人所珍视的东西。公开演讲是必要的;私人演讲是必要的;写论文也是必要的。但我倾向于相信,在长远眼光看来,那些省略不重要内容的书比告诉你所有内容的书更为重要,因为你不想知道所有内容。我不想太多了解企鹅的常规回应。你只想知道本质。

问题:你提到了诺贝尔奖的问题以及一些职业生涯所带来的恶名。这难道不是名声的一个更广泛的问题吗?我们能做些什么?哈明:你可以做以下几件事。大约每七年在你的领域中进行重大的、至少部分的转换。因此,我周期性地从数值分析转向硬件、软件等领域,因为你会用完自己的想法。当你进入新领域时,你必须重新开始,就像婴儿一样。你不再是大佬,你可以重新开始,播种那些将成为巨型橡树的橡子。我认为香农毁了自己。实际上,当他离开贝尔实验室时,我说,“那就是香农科学事业的终结。”我的朋友们对我说,香农还是像以前一样聪明。我说,“是的,他还是聪明的,但他的学术生涯结束了。”我真的相信是这样的。你必须改变。你一段时间后会感到疲倦,你会用尽你在一个领域的独创性。你需要接近某些领域。我并不是说你应该从音乐转向理论物理或英国文学,而是说在你的领域内,你应该转向其他领域,这样你就不会变得陈旧。你无法在每七年内强制进行变化,但如果可以的话,我会要求进行研究的条件是:你将在每七年内改变你的研究领域,并对其进行合理的定义,或者在 10 年后,管理层有权强制你进行更改。我会坚持要求变化,因为我很认真。老同志们遇到的问题是,他们掌握了一门技术,不断地使用它。他们一直在朝着那个时候合适的方向前进,但是世界正在发生变化。有了新的方向;但是老同志们仍然朝着以前的方向前进。你需要进入一个新的领域以获得新的观点,而且要在用完所有旧观点之前。你可以采取措施,但需要努力和精力。要勇气说,“是的,我会放弃我的大名。”例如,当纠错码理论很好地启动时,我说,“哈明,你将不会再阅读该领域的论文,你将完全忽略它,你将尝试做一些其他事情,而不是依靠它。”我故意拒绝在该领域继续进行。我甚至不读论文,试图迫使自己有机会做其他事情。我管理自己,这就是我在整个演讲中宣讲的。了解我自己的许多缺点,我管理自己。我有很多缺点,所以我有很多问题,即很多管理的可能性。问题:你会比较研究和管理吗?

汉明(Hamming):如果你想成为一名优秀的研究者,就不可能成为公司的总裁。如果你想成为公司的总裁,那就是另外一回事了。我并不反对成为公司的总裁。我只是不想成为。我认为 Ian Ross 在贝尔实验室做得很好。我并不反对成为总裁,但你必须明确自己想要什么。此外,当你年轻时,可能想成为一位伟大的科学家,但随着年龄的增长,你的想法可能会改变。例如,有一天我去找我的老板,博德(Bode),问他:“你为什么成为系主任?为什么不只成为一名出色的科学家?”他说:“汉明,我有一个愿景,希望在贝尔实验室实现数学的未来。我看到如果要实现这个愿景,我必须让它成为现实;我必须成为系主任。”当你对自己想要做的事情的愿景是你能独立完成的时候,你应该去追求。当你的愿景是你独自无法完成的时候,你就必须转向管理。而你的愿景越大,你就必须越向管理角色发展。如果你有整个实验室或整个贝尔系统的愿景,你就必须到管理层去实现。你很难从下面开始实现它。这取决于你的目标和渴望。随着生命的变化,你必须有准备地改变。我选择避免管理,因为我更喜欢独立完成自己的工作。但这是我做出的选择,有偏见。每个人都有自己的选择。保持开放的心态。但是,当你选择一条路时,请天晓得你所做的和你所选择的。不要试图两头兼顾。问:一个人的期望有多重要,或者说被一群期望你取得好成绩的人包围有多重要?汉明:在贝尔实验室,每个人都期待我做出好的工作,这对我很有帮助。如果你有自尊心,每个人都期待你做好工作,所以你也会做好。我认为,身边有优秀的人对我很有价值。我寻找最好的人。当物理组失去最好的人时,我离开了。当化学组失去最好的人时,我离开了。我试图和那些有很高能力的人在一起,这样我就可以向他们学习,并期望他们能从我这里得到很好的成果。通过有意识地管理自己,我认为我做得比“自由放任”要好得多。问:你在演讲开始时,淡化或低调了运气的作用;但你似乎也忽略了让你到洛斯阿拉莫斯、芝加哥、贝尔实验室的环境。汉明:有一些运气的成分。另一方面,我不知道其他选择的后果。你能否说其他选择会同样或更成功呢?我无从得知。你做某个特定的事情是不是依靠运气?例如,当我在洛斯阿拉莫斯遇到费恩曼时,我就知道他会获得诺贝尔奖。我不知道是哪一个方向,但我很清楚他会做出伟大的工作。无论未来出现什么方向,这个人都会做出伟大的成就。在这种情况下,你只是在这个地方,而不是在那个地方。运气有些作用,但也有些取决于个人的控制。运气偏爱有准备的头脑,运气偏爱准备充分的人。他并不能保证成功,但我不能确定成功一定会到来。我认为运气改变了机会的概率,但个体仍然有一定的控制。

前进,然后做出伟大的工作吧!(总研究研讨会发言结束。)理查德·哈明的个人简介理查德·W·哈明,1915 年 2 月 11 日出生于伊利诺伊州芝加哥市。他的正式教育可以追溯到以下数学学位:1937 年获得芝加哥大学学士学位;1939 年获得内布拉斯加大学硕士学位;1942 年获得伊利诺伊大学博士学位。他在第二次世界大战末期,在洛斯阿拉莫斯工作期间(1945 - 1946 年),管理计算机用于制造第一颗原子弹。之后,他直接转到贝尔实验室,在那里度过了 30 年时间,从事计算机、数值分析和计算机管理的各个方面(即 1946 - 1976 年)。1976 年 7 月 23 日,他“移动了他的办公室”到了加州蒙特雷的海军研究生院,在那里教授、指导研究并撰写书籍。在贝尔实验室期间,他抽出时间在大学里授课,有时是当地的,有时是全职的;这些活动包括任教于纽约大学、普林斯顿大学(统计学)、纽约市立学院、斯坦福大学(1960-61 年)、史蒂文斯理工学院(数学)以及加利福尼亚大学欧文分校(1970-71 年)。

Richard Hamming 曾获得多项奖项,其中包括:1968 年 IEEE 会士;1968 年 ACM 图灵奖;1979 年 IEEE Emanuel R. Piore 奖;1980 年工程院院士;1981 年哈罗德·彭德奖,宾夕法尼亚大学;1987 年,IEEE 授予了以他的名字命名的主要奖项,即 Richard W. Hamming 奖章,“为信息科学和系统做出杰出贡献”;合适的是,他也是该奖项的首个获奖者,获奖于 1988 年。1996 年在慕尼黑,他因他对纠错编码的工作获得了享有声望的 13 万欧元 Eduard Rhein 技术成就奖。他是 ACM 的创始人和前任主席,也是 AAAS 数学部的副主席。他最著名的工作可能是他关于纠错编码的开创性工作,他在求解微积分方程和带有他名字的频谱窗口方面的工作。他广泛的写作包括了一些重要的、开创性的、备受赞誉的书籍。这些书籍包括:科学家和工程师的数值方法,McGraw-Hill 出版,1962 年;第二版于 1973 年出版;1985 年由 Dover 重印;并被翻译成俄文。微积分和计算机革命,霍顿 - 米夫林出版,1968 年。应用数值分析导论,麦格劳 - 希尔出版,1971 年。计算机和社会,麦格劳 - 希尔出版,1972 年。数字滤波器,Prentice-Hall,1977 年;第二版于 1983 年出版;第三版于 1989 年出版;并被翻译成多种欧洲语言。

《编码与信息理论》(Prentice-Hall,1980 年;第二版 1986 年),《应用于微积分、概率与统计的数学方法》(Prentice-Hall,1985 年),《科学家和工程师的概率艺术》(Addison-Wesley,1991 年),《做科学与工程的艺术:学会学习》(Gordon and Breach,1997 年)。在退休之前的 21 年里,他继续在加州蒙特雷的海军研究生院的数学和计算机科学系担任兼职教授,继续教学和写作。1997 年秋季,他还在教授一门课程。他于 1998 年 1 月 7 日意外去世。感谢 Word Processing Center 的 Donna Paradise 对录音讲话的初步转录的专业工作。她让我的编辑工作更加容易。句法分析和标点符号的错误只属于我。最后,我要衷心感谢 Richard Hamming 和 Alan Chynoweth,在把这篇讲话记录转录成现在可读的状态方面提供的所有帮助。 J. F. Kaiser 凯撒

Kindle生词本导入Anki

不翻历史记录我都快忘记自己居然还写过关于 Anki 的文章,2021年这篇日常轻松制作Anki卡片。最近两年几乎没怎么长期使用 Anki,讽刺的是制作卡片轻松后导致卡片数量剧增,一段时间没有复习就积攒太多,再也无法跟上了。

最近重新拾起 Anki 是看到这篇文章,Augmenting Long-term Memory ,其实这篇文章在几年前也看过,这次重新阅读已然可以唤起对 Anki 的热情,重新出发首先删除了积攒的 500+待复习,(即使这样还有700+待学习)。接着根据文章建议,将所有需要背诵的内容整合到一个 deck 中,这也符合当初纸质笔记本的 All in One 原则,为此整理了散落在日常笔记中所有的 word 和 anki 标签内容,对了推荐 Obsidian + Anki 用户使用这个插件 https://github.com/Pseudonium/Obsidian_to_Anki,具体细节这里不赘述。

今天的主题当然是将 Kindle 的生词本导入 Anki 中,没想到宝藏博主 @wzyboy 在多年前的博客中早就提到了,Anki —— 高效的间隔重复记忆软件,根据对应的仓库 https://github.com/wzyboy/kindle_vocab_anki 完成基本没有问题,需要注意的有以下几点:

  1. vocab.db 文件所在的 system 文件夹是隐藏的,显示隐藏文件夹即可,或者直接输入地址;
  2. kindleunpack 可以处理 azw 文件,我使用 Calibre 将 azw 词典转换为 mobi 格式后,html 标记语言完全错乱,无法使用后续脚本,所以使用 DeDRM 后的 azw 格式词典即可;
  3. 添加卡片格式,导入卡片完全按照 Readme 即可,效果完美。

2022新冠病程记录

在三年防疫结束之际,我也不能逃脱,感染新冠病毒。具体感染渠道已经不可考,猜测有二:其一为戴着口罩与阳性人员沟通(送东西),此可能性较小; 其二为楼上楼下通过排风下水系统空气传播,个人倾向于该渠道。

病程🔗

12-19,Day 1🔗

早起嗓子疼,鼻塞,以为是最近北京空气太差,嗓子因为干燥而疼痛,正常上班。中午回来午休的时候畏冷,在被窝里双脚冰凉,轻微鼻塞,测体温38.0度,此时怀疑中招,结束午休前往办公室准备工作交接的材料,避免耽误后面工作。15:47办公室抗原测试阳性。

立刻回宿舍躺着,体温渐升,15:49 38.8度,躺了一小时多一点,试图睡觉,心率超过70,被尿憋醒,起来把电解质水拿出来加热,发热初期不要喝太冰的饮品。17:22 体温38.5度,19:40 体温38.9度,布洛芬缓释片2片,之后继续躺着休息至21:57,2207体温38.9度,躺着看视频,凌晨00:13 体温37.8度,体温终于降下来,之后休息。后续皆为居家休息。

12-20,Day 2🔗

08:56醒来,36.5度,有出汗感,体温完全降下来,上午10:06 体温36.5度,此时基本无任何不适症状,轻微鼻塞。

下午躺着休息,但是由于鼻塞加重,导致无法入睡。17:00开始畏寒,寒颤。17:36 体温 38.7度,晚饭后洗澡,18:36 服用一片乐松退烧,18:49 体温 39.3度,看来洗澡后有助于升温?躺着休息,同时配合毛巾+冰块的物理降温,20:52 体温下降,大量出汗,37.8度,此后精神状态较好,可以看视频做笔记等。凌晨02:30入睡。

12-21,Day 3🔗

08:37醒来,09:27体温37.7度,下午14:49体温36.9度,白天体温都比较正常。晚上17:46体温38.2度,开始升温,同时严重闭塞,晚饭后 洗澡,18:26服用酚麻美敏2片休息,21:23睡醒,鼻子通畅了。22:18体温37.5度。

12-22,Day 4🔗

醒的比较早,未测体温,之后回笼觉,11:25醒来。睡眠质量很差,回笼觉倒还行,咽痛严重。下午13:29体温36.3度,21:05 体温36.5度,今天未服用任何药物,开始出现咳嗽和咳痰症状,同时鼻塞依旧较为严重,不过不需要服用缓解药物。

12-23,Day 5🔗

轻微鼻塞,咳痰。

12-24,Day 6🔗

晚外出就餐,冷风受寒,咳嗽出现流血症状,好在并非一直咳嗽,鼻塞依旧。

12-25,Day 7🔗

本日上午进行核酸检测,直到第二天都未出结果,应为阳性。本日注意到嗅觉丧失,味觉部分丧失。

12-26,Day 8🔗

鼻塞,咳痰。抗原转阴。

12-27,Day 9🔗

鼻塞,大量擤鼻涕。

12-28,Day 10🔗

鼻塞有缓解,几乎无鼻塞,擤鼻涕有缓解。

总结🔗

我的症状为前三天晚上反复高烧,最高测得的温度为39.3度,服用布洛芬/洛索洛芬/对乙酰氨基酚等药物配合物理降温都可以在几个小时内退烧,前三天共服用3次、5片药物(2布洛芬,1乐松,2酚麻美敏),后续最难受症状为鼻塞,其他出现症状包括咳痰,咽痛,咳嗽,味觉/嗅觉部分丧失。

免疫方面,我接种了三针科兴疫苗,最后一针为2021年12月接种。总体的个人体验类似于一个偏长的重感冒病程。

药物方面,推荐在备好布洛芬/对乙酰氨基酚等退烧药的基础上,可以酌情备上缓解鼻塞/止咳等药物,这类症状出现比起发烧更影响生活质量。

新冠病毒感染的个体差异性较大,以上个人体验仅供参考。

用 Calibre 把有趣的博客历史文章转换成电子书

偶尔在网上会碰到有意思的个人博客,欣喜之余第一件事情便是寻找 RSS 链接添加到 miniflux 订阅中,但是对于历史文章怎么解决呢?毕竟 RSS 阅读器一般只会抓取最近几十条。正常情况下,我是一般会翻上个几页看看,把感兴趣的添加到 Instapaper 等服务中稍后阅读,或者直接把网页保存到方便的地方,有空的时候在手机上用浏览器翻阅。但是对于历史文章多的博客,这么操作总会遗漏可能感兴趣的文章。最近又遇到这个问题,便准备找方案将历史博文打包成电子书放到 Kindle 上阅读。依稀记得很久之前看到过类似的需求,但是没有找到,搜索后发现找到的大部分方案都是基于 Calibre 的新闻抓取功能。

Calibre 是知名的电子书管理软件,且有抓取新闻的功能,自带了不少新闻网站,还可以添加自定义的新闻来源。正是利用其自定义新闻来源的功能,我们可以添加自己的 Python 脚本,在 Calibre 中称为 recipe,进去文章的抓取并制作成 mobi 格式的电子书,之后需要 epub 直接利用 Calibre 强大的转换功能即可。

Recipe 的编写主要是编写继承自 BasicNewsRecipe 的类,主要需要修改的函数为 parse_index(),该函数抓取索引页,返回文章的名称及链接,这里用到的主要是 BeautifulSoup 这个类,观察分析网站源码的 html 结构即可自定义出自己需要的 recipe。我将自己抓的两个博客使用的 recipe 放到 Github 上的 blog-to-ebook 仓库了,有兴趣可以参考修改使用。为了方便调试,在上面的代码仓库中还有不依赖 Calibre 函数库的测试文件 test.recipe.py

下面的参考链接包括 Calibre 的文档和 recipe 继承类的源代码,以及其他相关文章,供参考。相似项目是 Github 上其他 recipe 的仓库。

参考链接🔗

相似项目🔗

【译文】使用 WireGuard 远程接入局域网

原文地址:https://www.laroberto.com/remote-lan-access-with-wireguard/

本文中,让我们来看看如何使用WireGuard建立一个简单而安全的隧道(VPN)到你的本地局域网(homelab)。我们将采用VPS的方式,这样我们就不必向互联网暴露任何端口。

我们将模拟以下设置

角色:

  • Router - 将作为你的局域网网关(向内)的机器。
  • Server - 具有公网IP的机器,所有客户将连接到它,也被称为Bounce Server。
  • Client - 你,试图在某个地方远程连接到局域网。

配置🔗

注意:所有的机器都基于 Ubuntu,根据你选择的 Linux 发行版调整设置

Server 和 Router🔗

对于Server 和Router执行以下操作

sudo apt update && sudo apt upgrade
sudo apt install wireguard
wg genkey | tee privatekey | wg pubkey > publickey
sudo sysctl net.ipv4.ip_forward=1

注意:要持久化 IP 转发,编辑 /etc/sysctl.conf,添加 net.ipv4.ip_forward=1

对于Server,创建 /etc/wireguard/wg0.conf:

[Interface]
Address = 192.168.10.1/32
ListenPort = 51820
PrivateKey = <Server's Private Key>

# Router Peer
[Peer]
PublicKey = <Router's Public Key>
AllowedIPs = 192.168.10.0/24, 10.0.20.0/24

对于Router,创建 /etc/wireguard/wg0.conf:

[Interface]
Address = 192.168.10.3/32
PrivateKey = <Router's Private Key>
PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o ens18 -j MASQUERADE
PostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o ens18 -j MASQUERADE

# Server
[Peer]
PublicKey = <Server's Public Key>
Endpoint = <Server's Public IP>:51820
AllowedIPs = 192.168.10.0/24
PersistentKeepalive = 25

注意:根据你的接口实际情况替换 ens18

通过 wg-quick up wg0启用该接口,然后通过wg show检查状态。

在这一步,我们可以进行一次快速的检查。在我的设置中,在Server上运行 mtr 10.0.20.1 会产生如下输入

                         Packets               Pings
Host                   Loss%   Snt   Last   Avg  Best  Wrst StDev
1. 192.168.10.3        0.0%     2   61.8  41.5  21.1  61.8  28.8
2. 10.0.20.1           0.0%     2   48.3  33.0  17.6  48.3  21.7

Client🔗

Client 进行如下操作

sudo apt update && sudo apt upgrade
sudo apt install wireguard
wg genkey | tee privatekey | wg pubkey > publickey

创建 /etc/wireguard/wg0.conf:

[Interface]
Address = 192.168.10.2/32
PrivateKey = <Client's Private Key>

[Peer]
PublicKey = <Server's Public Key>
Endpoint = <Server's Public IP>:51820
AllowedIPs = 10.0.20.0/24
PersistentKeepalive = 25

通过 wg-quick up wg0 启用该接口,然后通过 wg show 检查状态。我们还需要更新 Server 的 wg0.conf,将 Client 作为一个新的 Peer。

更新 Server的配置内容

[Interface]
Address = 192.168.10.1/32
ListenPort = 51820
PrivateKey = <Server's Private Key>

# Router LAN
[Peer]
PublicKey = <Router's Public Key>
AllowedIPs = 192.168.10.0/24, 10.0.20.0/24

# Client
[Peer]
PublicKey = <Client's Public Key>
AllowedIPs = 192.168.10.2/32

注意:更新后别忘记重启 Server 上的 wg,命令为 wg-quick down wg0 && wg-quick up wg0

现在,在Client上运行mtr 10.0.20.1产生

                         Packets               Pings
Host                   Loss%   Snt   Last   Avg  Best  Wrst StDev
1. 192.168.10.1        0.0%     6   41.2  42.1  21.4  73.6  18.7
2. 192.168.10.3        0.0%     5   64.8  72.0  41.8  88.1  19.3
3. 10.0.20.1           0.0%     5   77.4  62.3  43.0  77.4  13.3

这符合我们想要的 Client->Server->Router 流程。

深入配置🔗

大部分的路由是由 [Peer] 和 AllowedIPs 配置决定的。它规定了什么可以进入和离开隧道。例如,对于以下设置。

Peer A

[Interface]
Address = 192.168.10.1/32
...snip...

[Peer]
PublicKey = <Peer B's public key>
AllowedIPs = 192.168.10.0/24```

Peer B

```plain text
[Interface]
Address = 192.168.10.2/32
...snip...

[Peer]
PublicKey = <Peer A's public key>
AllowedIPs = 192.168.20.0/24

如果Peer A试图连接到(例如)192.168.10.11,由于该地址在192.168.10.0/24之内,它将被允许 进入 Peer A 的一侧。当它从Peer B那边出来时,由于它不在192.168.20.0/24范围内,它将被放弃。当[Interface]中Address含有网络掩码时(即192.168.10.1/32变更为192.168.10.1/24),就会变得有点混乱。虽然[Interface]中Address也可以影响路由(如果有网络掩码),但最终决定总是由[Peer] AllowedIPs 决定。例如

Peer A

[Interface]
Address = 192.168.10.1/24
...snip...

[Peer]
PublicKey = <Peer B's public key>
AllowedIPs = 192.168.20.0/24

如果我们试图连接到192.168.10.11,由于192.168.10.1/24,它将被路由到这个接口,但由于它不在192.168.20.0/24范围内,它将不被允许进入隧道(丢弃)。

为了进一步证明,使用我们开头案例中的设置。

将Router的 [Peer] AllowedIPs 字段从 AllowedIPs = 192.168.10.0/24 变更为 AllowedIPs = 192.168.10.2/32

此时,尽管Server已经不能访问10.0.20.1/24,但Client仍然可以访问。

将Client的 [Peer] AllowedIPs = 10.0.20.0/24, 192.168.10.0/24 更新为 AllowedIPs = 10.0.20.0/24

Client仍然能够到达 10.0.20.1/24,但是 mtr 不再显示链上主机的IP了(如下)

                              Packets              Pings
Host                   Loss%   Snt   Last   Avg  Best  Wrst StDev
1. (waiting for reply)
2. (waiting for reply)
3. 10.0.20.1           0.0%   222   41.7  47.1  37.3 180.8  15.5

原因是,当主机试图回复 mtr 时,数据包被丢弃。毕竟,Server(192.168.10.1)和 Router(192.168.10.3)不在 Client 的新 [Peer] AllowedIPs 范围内。

Ubuntu 20.04 安装 WRF 流程及 Docker 镜像

前几天受人之托在 Ubuntu 服务器上安装 WRF,研究了一整天搞定,下面记录一下流程以及推荐据此整理出来的 Docker 镜像。 WRF(Weather Research and Forecasting Model) 模式是有美国环境预报中心 (NCEP), 美国国家大气研究中心(NCAR)以及多个大学、研究所和业务部门联合研发的一种统一的中尺度天气预报模式。WRF 模式适用范围很广,从中小尺度到全球尺度的数值预报和模拟都有广泛的应用。(偷懒摘录自上海交大超算平台用户手册文档) 依据的流程主要是官方编译手册,已经算是非常详细。中文方面参考的主要是这篇文章。最后整理的 Docker 仓库为wrf-docker

你可以采用以下几种方式安装使用 WRF:

  1. 如果你是 Ubuntu 20.04 用户,可以直接根据我整理的 Dockerfile进行逐步的安装。除了环境变量设置地方的差异,几乎可以逐条复制 Dockerfile 中的命令(去除 RUN)。在命令行中进行环境变量设置的方法是 export DIR=/Build_WRF
  2. 如果你希望使用 Docker 方式,但是有一些自己个性化的需求(例如采用不同版本),那么下载 Dockerfile 修改后构建即可。
  3. 如果你希望使用 Docker 方式,且直接使用原始 Dockerfile 中构建特性,那么直接 docker pull wogong/wrf:latest 即可,后续使用docker run -ti wogong/wrf:latest /bin/bash 进入容器,可直接使用 real.exe wrf.exe 等命令。

说明🔗

  1. 为什么不采用现有的 Docker 方式安装?我在 Github 上确实发现了两个仓库,但是版本比较陈旧,且基于 centos,不太方便修改,故自己重新整理了基于 ubuntu 的镜像。
  2. 为什么不采用 Ubuntu 22.04?Ubuntu 22.04 的 gcc 版本过高,在编译 WRF 中会报错,故采用 Ubuntu 20.04
  3. Dockerfile 中 WPS 的 .configure 会报依赖缺少的错误(其实并不缺,我没仔细检查脚本报错的原因),导致最后生成的 configure.wps无法使用,这一行是手动编辑生成的 configure.wps 文件避免这个问题。

参考链接🔗

如何部署私人 DoH 服务器

DNS 是一个古老的协议,在互联网诞生之初的纯真年代便已出现,自然也有有古老协议的通病:不设防,或者说不安全。为了解决明文传输的问题,加密 DNS 的方案有很多,DoH 是其中之一,DoH 全称是 DNS Queries over HTTPS,其协议设计参考 RFC8484

在正常国家应该不太需要考虑自己部署 DoH 服务,但是中国大陆存在的 DNS 污染以及对国外公共 DoH 服务器的阻断导致了本文描述的这个需求。我的使用场景主要是作为 Adguard Home 的上游 DNS,提供无污染的/加密的境外服务域名解析。本文采用的技术方案是 coredns,下面简述步骤。

  1. 需要一台境外服务器,一个域名1,建议使用 acme.sh 项目申请 https 证书

  2. coredns 官网下载二进制文件,配置文件如下,注意该配置文件只启用了 DoH 服务。

    https://.:443 {
        tls ./acme/fullchain.pem ./acme/key.pem ./acme/ca.pem
        whoami
        forward . tls://1.1.1.1
        log
        errors
    }
    
  3. 使用 DoH 测试工具 https://github.com/curl/doh 进行测试

当然你也可以采用 docker 方式部署。

参考链接

脚注

  • 1 Cloudflare 的 DoH 地址是 https://1.1.1.1 ,自然是可能给 IP 颁发 https 证书的,只是更罕见,限制更多。至少 Let’s Encrypt 不允许。

《生命是什么》中文译本比较

《生命是什么?》是20世纪最有影响的科学经典著作之一,其作者奥地利物理学家埃尔温·薛定谔(1887—1961)是量子力学的奠基人之一,曾于1933年获得诺贝尔物理学奖。该书源于薛定谔1943年2月在都柏林三一学院所做的演讲,1944年由剑桥大学出版社出版,其副标题为“活细胞的物理观”,后多次再版和重印。剑桥大学出版的版本除了去掉四幅插图和相关文字,以及不再对各节连续编号,对正文未作更改。但是从1967年版开始,它把薛定谔的另一个讲演 Mind and Matter 和一个自传也包含在内。

本书中译本按照时间顺序简单介绍如下。

  1. 上海人民出版社1973年版,译者为“上海外国自然科学哲学著作编译组”[傅季重、赵寿元、胡寄南等译、校];豆瓣链接 https://book.douban.com/subject/2061887/ 内容为原始版本,不包含 Mind and Matter 部分。
  2. 湖南科技出版社2003年版,译者为罗来鸥、罗辽复。该版本译文是由上海人民版修改而来,但在译后记中未作说明。在这些改动中,虽然有一些是正确的,但有些译法甚至还不如上海人民版,还有不少明显的错误未予改正。(参考张卜天版本译后记)内容包含了 Mind and Matter 和一个自传。豆瓣链接为 https://book.douban.com/subject/1317485/
  3. 世界图书出版公司2016年版,译者为吉宗祥,豆瓣链接为 https://book.douban.com/subject/26775711/ ,翻译极差,译者不知名,无译后记。
  4. 商务印书馆2018年版本,译者为张卜天,北京大学科学哲学博士,国内杰出的中青年翻译家,译有著作40余部。该译本在原著发表70周年(译后记2014年落笔,该书2018年出版)之际商务印书馆出的新译本,对旧译本加以修正和改进,主要参考上海人民版的译文。内容为原始版本,不包含 Mind and Matter 部分。豆瓣链接为 https://book.douban.com/subject/30278178/
  5. 北京大学出版社2018年版本,译者为周程 / 胡万亨,豆瓣链接为 https://book.douban.com/subject/30345616/ 此版本为北大出版社出版的科学素养文库·科学元典丛书系列中的一本。内容包括原始版本和薛定谔晚年出版的我的世界观 My View of the World。无译后记。

目前比较推荐的是商务印书馆2018年版本,至于北京大学出版社2018年版本我尚未细读,无法给出意见,也无译后记可参考,如果对我的世界观部分内容感兴趣可选择该版。

Fitbit Ionic 召回事件

最近 Fitbit Ionic 大规模召回告一段落,由于第一次体验这种产品召回,经历比较神奇,特此记录一下。 Fitbit 是 2007 年在加州成立的一家公司,主营产品是运动追踪器和智能手环手表等。与这家公司结缘是在2016年4月17日,当时在京东购买了 Fitbit Surge,一款运动手表。2016 年 Apple Watch 已经非常成熟了。当时在选购运动手表的时候,不选择 Apple Watch 的原因主要有两点,首先是价格昂贵,其次是一天一充当时的我无法想象。因此作为试水尝试在京东购买了时价 1398 CNY 的 Fitbit Surge,显然价格便宜多了,而且由于是黑白屏幕和功能简单,Surge 的续航应该有接近一周,远远超过 Apple Watch 了。

接下来的两年里,这支运动手表主要是陪伴我跑步,记录睡眠,续航够长,功能也满足我的需求,整体体验还是非常满意的。因此,在2018年2月的时候发现 Fitbit 发布了新一代产品 Fitbit Ionic 的时候,略作犹豫便在美国亚马逊海淘了这款产品。由于时间过于久远,当时记得买之前最大的期待是更新了防水功能,因此 Ionic 是支持游泳的,作为偶尔会游泳的 Surge 用户,对此颇为激动。2018年那个时间点没有买 Apple Watch 的原因同样是续航问题。 然而这次的使用体验并不佳,首先是游泳记录功能,界面丑陋就算了,功能本身的准确度也低的可怜,记录的数据几乎没办法用,此时我是非常羡慕 Apple Watch 用户的,准确度不谈,至少页面好看啊。最重要的是,这款产品在1年多后就变砖了,无法开机,无法充电。此后犹豫了一段时间便在 2019年9月的时候买了 Apple Watch S5,前几年担心的续航问题根本没有成为烦恼,游泳记录功能也准确多了,这些都是后话,暂且不表。

2019年中便成为尸体的 Fitbit Ionic 我并没有第一时间扔掉,而是静静躺在抽屉角落,直到去年的时候才挂上闲鱼几十元出掉了。是的,你没看错,没有没人要的垃圾,只是定价不够低,变砖的智能手表也有需要它的人。 几个月前在社交媒体上看到了Fitbit Ionic 由于电池问题导致损害人身安全的报道,因为官方决定召回。当时并未细想。直到今年3月5日收到这样一封邮件:

点击链接跳转到一个登记网页,应该只需确认一下,不需要提供任何资料,召回形式是全额退款,此时有点惊喜了。刚好一个月之后,4月5日,又收到了 Fitbit 官方发来的 Payoneer 注册链接,本次退款是和 Payoneer 合作进行的。输入个人基本信息和银行卡信息完成注册,4月8日我的国内银行卡便收到了退款,301.26 USD,折合 1873.72 CNY,手续费只有 6.02 CNY,大大低于我的预期。

整个退款的周期一个月,总体体验还是不错的。没想到一个4年前买的电子产品,还能全额退款。作为一名没有因为安全问题受到损失的消费者,我倍感幸运。但是那些因此受到人身伤害的,可能退款并不足以覆盖医疗成本,我也没有去确认是否有另外的赔偿。

虽然现在已经不再使用任何 Fitbit 的产品,甚至最后一段时间的使用体验也谈不上好,但是这次产品召回至少说明这是一家有勇气承担责任的公司。反观 Apple 公司的 [Flexgate]({% post_url 2020-12-07-flexgate %}) 事件,令人非常失望了。 对了,2021年Fitbit已经被 Google 收购。所以 Google 这回赢了 :)

如何获得 Youtube 视频字幕

现在视频成了传递信息的重要媒介,但是并不是所有的信息都适合使用视频这个媒介。厨师王刚的介绍做菜使用视频当然没有问题,财经类的信息使用视频实在是降低了信息获取速度。本文介绍如何获取视频的文字稿。内容直接启发自 https://twitter.com/shell909090/status/1351371503019847681 由于原推主锁推,引用如下。

最近在看很多财经频道,里面一个人说说说讲了半天,其实干货可能就十句话。问题是怎么从几十分钟的内容里看到这10句干货呢?我找了一个简单办法。先用youtube-dl -f ’bestaudio[ext=m4a]’下载音频。然后用下面这个项目转换为字幕。最后直接看字幕,三分钟完事。https://github.com/agermanidis/autosub

下载 Youtube 视频的音频内容

youtube-dl -f 'bestaudio[ext=m4a]' "URL"

使用 autosub 获取字幕,autosub 的原始仓库现在已经不维护,我使用的是目前活跃维护的 fork 版本,简介有简体中文。

Ubuntu 下的安装

pip install git+https://github.com/BingLingGroup/autosub.git@alpha ffmpeg-normalize langcodes```

使用

```autosub -s zh-CN -i audio.m4a```

简单尝试发现使用的效果一般。不过总比看十几分钟的视频快多了。转文字利用的是 Google Cloud Speech 的 API,需要将音频文件分段转为文字,所以速度不算快。不过敲好命令可以看别的去。总体来说还是节约了大量时间的。

如果懒得自己折腾的,可以考虑提供类似功能的商业服务 (未尝试): Get The tldr Of Any YouTube Video In Seconds <https://you-tldr.com/>

数字生活 2021

个人数字生活一览。距离上次发布类似的文章已经 3 年了,这三年变化当然很大。受 Julian Shapiro 启发,以后每季度对个人工具库进行更新。

输入🔗

  • 社交网络:Twitter,朋友圈和微博看的频率非常低了已经
  • 论坛:V2EX, Hacker News
  • RSS 订阅 (Inoreader),主要信息来源,订阅了包括博客、newsletter、微信公众号、微博时间线等内容
  • 视频信息:Youtube, Netflix, BiliBili
  • 音乐:Spotify
  • 播客:Overcast, Spotify
  • 书籍:微信读书

输出🔗

工具🔗

  • Telegram, Wechat 即时通信
  • Dropbox, Google Drive 文件同步与备份,在线文档
  • Pinboard 网络书签/全文存档
  • Toggl 时间记录
  • Anki 背诵
  • Instapaper 稍后阅读
  • Bitwarden 自建的密码管理及两步验证管理工具
  • RSSHub 自建 RSS 辅助工具
  • Surge 代理
  • 滴答清单 待办管理工具
  • Google Calendar 个人日程管理
  • Beanocunt 个人金融数据
  • Airtable 个人物资管理
  • Evernote 作为扫描小票收纳仓库

硬件🔗

  • 计算机 Macbook Pro 2016 late, 15’
  • 鼠标 Logitech MX Anywhere 2s
  • 键盘 PFU HHKB Professional HYBRID Type-S
  • iPhone 12, 128G
  • Apple Watch series 5
  • AirPods Pro

信息流🔗

主要使用 IFTTT 和 Pinboard 进行管理,所有的信息存档在 Pinboard,因为购买了 Archive 账户,全文搜索也是可能。

  • RSS/Instapaper/Inoreader stared → Pinboard (IFTTT)
  • Douban RSS → Pinboard (IFTTT)
  • Swarm → Google Calendar (IFTTT)
  • Twitter → Pinboard (self)
  • Web → Pinboard (manual)

Beancount 账户命名

命名是计算科学中最难的两件事,Beancount 的账户的命名尤其困难。对于从其他记账工具迁移过来的用户,直接将原先的账户结构迁移过来当然是可以的。但是 Beancount 这种文本记账工具,对于账户的处理几乎没有成本,可以任性地添加更多的账户。直接复制原来工具的账户结构可能无法完全发挥 Beancount 的能力。

我个人为 Beancount 的账户命名有提供以下几点指导:

  1. 账户命名在可接受的范围内尽量详细,有账户补全这样的功能在,多级账户名锁造成的额外负担是很小的。带来的好处是显而易见的,最终形成的报表详尽而清晰。此外,在后期使用正则替换合并账户是很容易的,但是拆分账户只能对每一条记录进行检查。
  2. 多使用多级账户,在 fava 中折叠次级账户后,可以清晰地看到上一级账户的总额。
  3. 尽量遵从你的直觉,想象你在以后遇到一笔账户,直觉告诉你应该放到哪个账户。这样可以最大地降低记账的认知负担。当然,这一点可以随着使用慢慢优化自己的账户命名,毕竟文本账本的一大优点就是可以方便地进行正则替换。

最后附上一些其他记账工具默认的账户命名,可供参考。

  • MoneyWiz 默认账户名

      Automobile
          Accessories
          Car Insurance
          Gas/Fuel
          Lease
          Maintenance
          Other
          Parking
      Bills
          Cable
          Electricity
          Gas
          Internet/Broadband
          Mobile Phone
          Other
          Phone
          Water
      Clothing
          Accessories
          Clothes
          Jewelry
          Other
          Shoes
      Digital
          Apps
          Books
          Movies
          Music
          Other
          Podcasts
          TV Shows
      Food & Dining
          Dining/Eating Out
          Groceries
          Other
      Health Care
          Dental
          Eye Care
          Health Insurance
          Medical
          Other
          Pharmacy
      Housing
          Furniture/Accessories
          Home Insurance
          Maintenance
          Mortgage
          Other
          Rent
      Leisure
          Entertainment
          Fitness/Sport
          Other
          Personal Care
      Loans
          Other
          Taxes
          Transportation
          Travel
    
  • mint-categories https://www.mint.com/mint-categories

      Expenses (all types)
          1. Rent/Mortgage
              a. Home Owners Association Dues
              b. Rental Insurance
              c. Home Owners Insurance
          2. Fixed Expenses
              a. Utilities
              b. Gas
              c. Electric
              d. Water/Trash/Sewer
              e. Cable/Internet/Phone
              f. Cell Phone
              g. Credit Cards
              h. Car Expenses
              i. Maintenance
              j. Gas
          3. Extra Expenses
              a. Grocery (Food)
              b. Clothes/Shoes/Hygiene
              c. Extra for Home Expenses
          4. Savings
              a. Savings Account. Speak with employer; some saving plans can pull from paycheck before taxes. That means less of your paycheck is taxable.
              b. Create an Emergency Fund; it should be at least 6 months of expenses. Emergencies can happen and drain a well-established savings account
          5. Taxes
              a. No explanation needed
          6. Fun Cash
              a. Out with friends
              b. Movies
              c. Vacations
    
  • GnuCash

      Adjustment
      Auto
          Fees
          Gas
          Parking
          Repair and Maintenance
      Bank Service Charge
      Books
      Cable
      Charity
      Clothes
      Computer
      Dining
      Education
      Entertainment
          Music/Movies
          Recreation
          Travel
      Gifts
      Groceries
      Hobbies
      Insurance
          Auto Insurance
          Health Insurance
          Life Insurance
      Laundry/Dry Cleaning
      Medical Expenses
      Miscellaneous
      Online Services
      Phone
      Public Transportation
      Subscriptions
      Supplies
      Taxes
          Federal
          Medicare
          Other Tax
          Social Security
          State/Province
      Utilities
          Electric
          Garbage collection
          Gas
          Water
    
  • beancount-boilerplate-cn 这个项目中的账户命名也可以参考。

Beancount 投资回报计算与可视化

TL;DR 使用 fava-portfolio-returns1 ,可在 fava 中直观展示投资回报率详细数据,该插件的数据来源是 beangrow2

几种方案概述🔗

fava-portfolio-returns + beangrow🔗

对于使用 Beancount 记录投资帐目的人来说,如何评估自己的投资回报一直是一个未解决的问题。前一段时间 Beancount 的开发者 Martin 写了一个计算回报率的小工具32,姑且可以算是 v3 版本功能的一个小前瞻,尝试使用之后,虽然目前还是比较粗糙的脚本,但是基本可以计算出来年化的投资回报率了。Beancount 用户 Redio 也写了详细的 Review4,可以作为第一个文档的补充,使用时参考。

2023-08-29 更新 近日在邮件列表看到了 fava-portfolio-returns1 项目,这是一个用于在 fava 中展示投资历史回报的插件,后端数据来自 beangrow,尝试了一下发现运行良好,当然运行良好的前提是解决一堆报错,这个插件对 beangrow 配置文件的错误容忍程度较低,遇到错误时可开启 debug 模式查看报错信息。这里放两张官方的截图,展示了该插件的功能。具体使用方法参见官方仓库 README。

![report_overview]({{ site.cdn_url }}/img/report_overview.png)

![report_vht]({{ site.cdn_url }}/img/report_vht.png)

fava_investor🔗

fava_investor 5 是另一个试图在 fava 中进行投资回报可视化的插件,目前处于开发中,由于我的投资帐目比较复杂,目前没有办法成功运行。对于简单的投资帐目(例如不包含数字货币),可以尝试使用。

beancount_portfolio_report🔗

另外还有一些比较小的工具,例如 beancount_portfolio_allocation6是一个根据当前市值计算持有资产比例的脚本,方便用来进行资产重新配置。我在此插件的基础上,进行了一些简单的修改,重新命名为 beancount_portfolio_report7,用于输出当前各类资产的市值、回报和总体回报率(非年化)。

beancount-boilerplate-cn🔗

beancount-boilerplate-cn 有部分净值计算的工具,但是同样不适合我这种比较复杂的投资记账。没有尝试。

beancount.io🔗

beancount.io 在网站上也提供了 Stock Analysis 工具,可惜没有看到开源,处于数据安全顾虑,目前没有体验。从 demo 来看完成度还是比较高的。侧重点在于比较不同风险资产的盈利情况。

读者可以根据自己的实际情况,选用上述工具,进行投资回报的计算。其实我理想中的功能,是类似且慢小账本,绘出净值变化曲线,自动计算回报率,以及和大盘指数进行对比。对于 Beancount 来说,前二者需要的数据都是存在的,大盘指数这个可以通过 beanprice 指定来源来进行对比。只能期待 v3 版本早日出来了。

注意🔗

关于资产价格。计算投资回报的前提是 Beancount 账本文件中有对应资产的价格数据,大部分用户可能没有这个数据或者数据不全,可以使用 bean-price 或者 beanprice8 (分离出来的新版本)进行资产价格获取。现在新版本的 beanprice 已经支持时间段的价格获取,可补全资产的历史价格。

参考链接🔗

3

Calculating Portfolio Returns 4: Martin’s Returns Computation Review 5: Asset allocation plugin for fava/beancount (personal finance software) https://github.com/redstreet/fava_investor 8: beanprice https://github.com/beancount/beanprice 6: Reports on portfolio asset allocations in beancount. Useful for risk analysis and for rebalancing purposes. https://github.com/ghislainbourgeois/beancount_portfolio_allocation 7: Reports on portfolio performance in beancount. Useful for risk analysis. https://github.com/wogong/beancount_portfolio_report 2: beangrow 1: fava-portfolio-returns

日常轻松制作 Anki 卡片

Anki 是一款能让记忆事物变得简单的程序。Anki 比传统的学习方法更为有效,因此你可以大幅减少花在学习上的时间,或是大幅提升学习量。(来自 anki 官方中文介绍)。

我个人很早就耳闻 anki 的大名,2019 年 10月份够买了 iOS 上的官方 APP。但是日常使用仅限于背诵单词,有一搭没一答的在使用。2020 年底学习了 Youtuber Ali 关于 Anki 的课程 Learn Anything With Flashcards The Ultimate Guide To Anki,了解到很多之前不知道的 anki 的强大功能。新的一年开始,希望能坚持 anki 打卡,背诵单词。下面简单介绍一下使用 anki 的 workflow。

我一直不太习惯背诵单词书,一来没有备考的压力,动力不足,其次没有语境的背诵单词,对我来说印象不够深刻。这么多年的英语学习经历,我几乎没有背诵过单词书。高中积累单词的方法是,在日常考试中遇到的生词,记录到生词本,之后有空没空多翻翻。这样的效果是十分显著的,在后期英语阅读理解速度比较同龄人提高了很多,个人积累的单词量也显著进步。这样的习惯一直断断续续保持着,这么多年使用过有道的单词本,欧陆词典的生词本,用来记录在互联网上浏览遇到的生词,但是效果不佳。原因主要是,互联网上遇到的生词数量太多(有些难度较大的文章可能一篇就会积累数十个),没有了应试压力后很难经常性地回顾,这就导致生词本中不熟悉的单词越来越多,定期背诵带来的沮丧感大增,很难坚持下去。

Anki 通过自己的算法可以完美的解决这个问题。所以要解决的问题是,如何将生词本迁移到 Anki 词库?

最直观的办法是,直接将生词本导出,简单处理下格式,并导入 Anki。这样当然是可行的,但是日常积累遇到的新词如何处理?定期从生词本导入到 Anki 当然是可以的,不过毕竟增加了额外的步骤。永远不要低估自己的惰性,时间长了可能就这多的一步阻碍你继续背诵单词。我们需要的方案是,能够将遇到的生词直接添加到 anki 中,非常幸运的是,现在有很多这样的工具。本文主要介绍我个人经常遇到的两种场景。

在浏览器中添加生词到 Anki🔗

幸运的是,有现成方案可以完美解决这个场景需求。大力推荐 在线词典助手 (含Anki制卡功能) 这个 Chrome 扩展,插件安装地址。项目的是开源的,代码托管在 Github

安装完毕,简单配置后,可以直接在浏览器进行划词翻译,一键添加到预先配置好的 Anki 词库。个人使用一年多,偶尔遇到不能制卡多是配置失效,重新配置即可。

查单词的同时添加到 Anki🔗

在非浏览器页面遇到生词,查单词后希望添加到 anki,如何解决这个需求呢?具体来说,我查单词的地方默认是命令行,感谢 ydcv,能够在命令行迅速方便的查询单词。但是该工具只是一个非常简单的查词工具,没有更复杂的,例如单词本这样的功能。 最初我是这样解决这个问题的,手动添加了生词本功能。实现的非常简单,就是在查单词的同时,将单词保存到一个文本文件。通过 shell 函数实现:

# youdao  
function s() {
    local spath="${HOME}/sh/ydcv.py"
    $spath $*
    echo $* >> ${HOME}/Dropbox/Dat/words.txt
}

在决定使用 Anki 之后,这个实现当然不够,如何能够让在 ydcv 中查询的单词保存到 Anki 词库呢?前段时间特地抽时间搜索了一下,找到了一个在命令行中与 anki 词库交互的工具 apy,该工具没有采用 Ankiconnect 等接口,可以在 Anki 没有运行的情况下,通过读取 Anki 数据库的方式,直接添加新卡片。那么问题就简单了,我们可以用该工具将使用 ydcv 查询的单词和返回的意思直接添加到 Anki 词库,简单升级下上面的 shell 函数:

# youdao  
function s() {
    local spath="${HOME}/sh/ydcv.py"
    output=$($spath $*)
    echo "$output"
    apy add-single -d Default -m Basic $* $output
    apy sync  
}

该函数的功能就是,查询单词的同时,将单词和返回的意思直接制卡,保存到 Default 词库,使用的模板是 Basic。目前的处理比较粗糙,没有细分音标,意思,短语等字段。希望更进一步细分就需要处理 ydcv 返回的内容了。当然要达到这个目的,直接修改 ydcv 的代码可能更简单。

至此,通过这两个小工具,我们已经可以覆盖在桌面环境遇到的所有生词了,随手查询添加到 Anki。至于移动端,暂时没有找到非常方便的添加到 anki 词库的方法,我猜测通过 shortcuts 应该是可以实现这一点的,奇怪的是没有搜索到相关方案。不过由于本人大部分查单词的场景都在桌面,暂时先放下这个需求。

希望可以帮助到有需求的人,同样,添加单词只是第一步,更重要的是日常的坚持背诵,Anki 的算法非常有效,但是能否克服惰性还是得看个人。努力吧 XD (Flag:希望 2021 年 Anki 的打卡天数能超过300天。

关于 bottleneck 的几种含义

机器学习的语境中,经常可以看到 Bottleneck 这个词,其含义差别较大,为了解决自己的困惑,本文整理了几种常见的含义。

  1. information bottleneck theory 由 Naftali Tishby 2000 年的论文 The information bottleneck method 中提出,后来试图解释深度学习的泛化性能。当然关于这个理论本身也有不少反驳意见。

  2. ResNet 中的结构名称,bottleneck design 2015 年底最新给出的,也是当年的 imagenet 比赛冠军。可以说是进一步将 conv 进行到底,其特殊之处在于设计了“bottleneck”形式的 block(有跨越几层的直连)

  3. bottleneck 是我们经常用于描述网络最后一层之前的那些实际完成分类任务的网络层的一种非正式称谓 http://shartoo.github.io/tensorflow-retainmodel/

  4. MLP 中一类隐层 源于1994年的《CONNECTIONIST SPEECH RECOGNITION A Hybrid Approach》,里面首先提出到 BN 层应该要同时比input&output结点数都要少的概念。参考 https://www.zhihu.com/question/51793452

Ubuntu LTS 版本升级

Ubuntu 16.04 升级到 18.04 过程中,出现了和 miktex 相关的一个错误。升级顺利完成,但是发生了这个错误。导致了一些包并没有更新,以及 apt 的依赖被搞崩了,提示如下

You might want to run 'apt --fix-broken install' to correct these.
The following packages have unmet dependencies
miktex : Depends: libcurl3 (>= 7.16.2) but it is not installed
E: Unmet dependencies. Try 'apt --fix-broken install' with no packages (or specify a solution).

这时候使用 apt remove miktex 也是没有用的,提示这个错误

Removing miktex (2.9.6650-1) ...
miktexsetup: /usr/lib/x86_64-linux-gnu/libcurl.so.4: version
`CURL_OPENSSL_3' not found (required by miktexsetup)
dpkg: error processing package miktex (--remove):
installed miktex package pre-removal script subprocess returned error exit status 1
Errors were encountered while processing:
miktex
E: Sub-process /usr/bin/dpkg returned an error code (1)

错误的原因是 Ubuntu 18.04 将 libcurl3 升级成 libcurl4,对应的库也进行了更新,导致依赖 libcurl3 的应用程序例如 miktex 崩坏,进而导致 apt 崩坏,小白用户面对这种情况基本就手足无措了。

以错误关键字搜索,网上很多这样的问题,这个 bug 也算旷日持久,例如这里1的讨论。

搜索到的大部分网页要么没有提供解决方法,要么提供的方法是错误的2,其实问题很简单,既然要依赖 libcurl3,我们安装上 libcurl3 不就可以了?问题在于 Ubuntu 不允许同时安装 libcurl3 和 libcurl4。我们只能手动给 miktex 提供 libcurl3 对应的库,具体步骤如下 (参考链接3)

# download libcurl3
mkdir ~/libcurl3 && cd ~/libcurl3
apt-get download -o=dir::cache=~/libcurl3 libcurl3
ar x libcurl3* data.tar.xz
tar xf data.tar.xz
# backup
cp /usr/lib/x86_64-linux-gnu/libcurl.so.4.5.0 /usr/lib/x86_64-linux-gnu/libcurl.so.4.5.0.back
cp ~/libcurl3/usr/lib/x86_64-linux-gnu/libcurl.so.4.5.0 /usr/lib/x86_64-linux-gnu/

此时应该可以正常卸载 miktex 了,sudo apt remove miktex,如果还是提示错误记得检查下软链接

ls -alh /usr/lib/x86_64-linux-gnu/ | grep curl

卸载之后记得将之前备份的 libcurl4 对应的库文件恢复,最好再检查下软链接是否正确。这时候 apt 应该也正常工作了。

参考链接

1

https://bugs.launchpad.net/ubuntu/+source/curl/+bug/1754294 2: https://askubuntu.com/questions/1130137/remove-miktex-from-ubuntu-18-04-2 3: https://dev.to/jake/using-libcurl3-and-libcurl4-on-ubuntu-1804-bionic-184g

Flexgate 苹果背光门事件

简介🔗

Flexgate 背光门事件是指苹果公司 2016 或者 2017 款的 Macbook 在长期使用后出现的屏 幕质量问题,具体表现为屏幕背光完全消失(黑屏)或者出现严重的漏光现象,国内外很多 文章视频对此已经有详细的介绍1。美国也出现了针对 Flexgate 事件的集体诉讼。2019年5 月19日,苹果官方推出了 2016/2017 款 13 寸 Macbook Pro 的显示屏背光服务计划2,但是对于存在同 样问题的 2016 款 15 寸 Macbook Pro 却没有对应的服务计划。这也正是我购买的机型。

回顾🔗

  • 2017-01-05 购买 2016 款 15寸 Macbook Pro 便携式笔记本电脑。
  • 2017-06-22 购买该设备的延长保修服务 Apple Care+。
  • 2020-12-14 因电池鼓包授权维修点送修,免费更换 C 面(尚在 Apple Care+ 保修期限内)。
  • 2020-03-24 晚间发现笔记本屏幕黑屏,不显示任何内容,显示器背光完全停止工作。上网搜索发现原因是苹果的产品设计缺陷 Flexgate 背光门确认。
  • 2020-03-25 电话苹果客服确认该问题,由于疫情期间行程受阻,未能送去线下维修。
  • 2020-06-28 前往长沙苹果官方授权维修点,确认该设备出现的问题,但是拒绝免费维修,付费维修费用高达 6100 元人民币。放弃维修
  • 2020-09-11 淘宝寄修
  • 2020-09-16 淘宝维修返回,测试机器,发现底部背光有问题,背光不均匀,在低亮度的时候尤其严重。和店家交涉,第二天重新寄回。
  • 2020-09-21 淘宝维修再次返回,测试完美。总计花费 800 CNY。淘宝商品地址3

总结🔗

遇到同样问题的苹果用户,希望我们都能力所能及地投诉并关注这件事情。对于不想在官方换屏维修的用户,可以尝试在淘宝或者华强北维修,我个人的体验比较满意。

Flexgate 背光门出现的原因是苹果在 2016 款 Macbook 中引入了蝶式键盘,新设计降低了屏幕排线的强度,长期使用造成疲劳损坏。 无数的案例已经切实证明了这一设计缺陷,苹果官方对 2016 款 13 寸 Macbook Pro 提供背光服务计划,却罔顾大量 15 寸用户和 2017 款用户的权益损失。 苹果的不维修只更换服务也导致维修费用天价,不具有实际操作性,令人失望。此事件发生后,我也尝试在 12315 投诉,接到苹果的来电非常强硬,拒不承认自己的错误。 不提供任何补救措施。更是令人心寒。

相关链接🔗

Clash 作为网关的透明代理

注意:作者目前使用的方案已经更新,请参考[最新文章]({% post_url 2023-07-14-clash-gateway %}),使用 TUN 方案,不需要自己维护 iptables 规则

一直以来的方式是在各个终端进行代理,因为没有一定网关/路由层面处理的理由。之前也在路由器上折腾过几次,成功大抵算是成功,但是偶尔的稳定性问题,以及不方便更改代理状态和调试,最终还是放弃。

前段时间折腾了 DIYNAS,安装了 PVE 系统,折腾了虚拟机好久。想着既然没什么后顾之忧,不如在虚拟机上试试软路由?使用 OpenWRT 原生系统 + openclash 使用了一周左右,稳定性尚可,就是更新频繁(强迫症无法不点更新啊),配置文件看得人眼花缭乱。

在翻 Clash 的 GitHub 仓库时,发现最近 TProxy 支持了转发 TCP1,遂想起来在 Ubuntu 上折腾一下透明代理作为网关,成功后发现这种方式相对于 OpenWRT + openclash 简单省心,维护一份配置文件,不用频繁更新。记录方案于此。

提前声明本人网络知识欠缺,配置大多参考他人,尽力给出原始链接供参考。

普通 linux 主机设置🔗

首先,在网关机器上打开 ipv4 转发, echo net.ipv4.ip_forward=1 >> /etc/sysctl.conf && sysctl -p Clash 配置文件添加如下

# Transparent proxy server port for Linux (TProxy TCP and TProxy UDP)
tproxy-port: 7893

设置路由和 iptables 的脚本

# ROUTE RULES
ip rule add fwmark 1 table 100
ip route add local 0.0.0.0/0 dev lo table 100

# CREATE TABLE
iptables -t mangle -N clash

# RETURN LOCAL AND LANS
iptables -t mangle -A clash -d 0.0.0.0/8 -j RETURN
iptables -t mangle -A clash -d 10.0.0.0/8 -j RETURN
iptables -t mangle -A clash -d 127.0.0.0/8 -j RETURN
iptables -t mangle -A clash -d 169.254.0.0/16 -j RETURN
iptables -t mangle -A clash -d 172.16.0.0/12 -j RETURN
iptables -t mangle -A clash -d 192.168.50.0/16 -j RETURN
iptables -t mangle -A clash -d 192.168.9.0/16 -j RETURN

iptables -t mangle -A clash -d 224.0.0.0/4 -j RETURN
iptables -t mangle -A clash -d 240.0.0.0/4 -j RETURN

# FORWARD ALL
iptables -t mangle -A clash -p udp -j TPROXY --on-port 7893 --tproxy-mark 1
iptables -t mangle -A clash -p tcp -j TPROXY --on-port 7893 --tproxy-mark 1

# REDIRECT
iptables -t mangle -A PREROUTING -j clash

最后在局域网的 DHCP 服务器设置网关为该机器 IP 即可,也可以手动在希望走代理机器的网关设置未该机器 IP。

OpenWrt 设置🔗

下载好对应版本的 clash 执行文件,移动或软链接至系统路径。 编写自动启动文件 # /etc/init.d/clash

#!/bin/sh /etc/rc.common
START=99
STOP=15
 
start() {
  echo start
  clash &
  /root/.config/clash/iptables.sh
}
 
stop() {
  echo stop
  killall clash
}

配置文件中的 iptables.sh 即为上文中的 iptales 设置命令。

参考链接:

self-hosting is good

最近折腾整理了一下服务器上自建的服务,顺便给添加上了 https,下面简单记录一下,推荐自建服务的同时,也大致给同样想要折腾的人提供一点记录。

密码管理服务🔗

自从 2009 年 CSDN 爆出明文存储密码,密码泄漏事件之后,便开始使用密码管理软件。最初使用 LastPass,之后长期使用 Keepass,最近一年迁移到了 1Password,在论坛发现对 Bitwarden 的推荐后,顺手在服务器上部署了,目前使用几个月,体验良好。

推荐使用 docker 部署,官方仓库对性能要求比较高,推荐使用 Rust 重写的服务端 bitwarden_rs,采用 docker-compose 方式部署,注意为了使后面部署的其他服务也能使用 Caddy,我们不采用上面这个 repo 提供的 docker-compose.yaml,采用以下

$ cat docker-compose.yml 
# docker-compose.yml
version: '3'

services:
  bitwarden:
    image: bitwardenrs/server
    restart: always
    volumes:
      - ./bw-data:/data
    environment:
      WEBSOCKET_ENABLED: 'true' # Required to use websockets
      SIGNUPS_ALLOWED: 'false'   # set to false to disable signups
    ports:
      - "127.0.0.1:3012:3012"
      - "127.0.0.1:3011:80"

最后我们统一采用 Caddy 进行反向代理。

RSS 阅读器🔗

2010 年前后开始使用 RSS 订阅,经历了 2012 年 Google Reader 关闭带来的晴天霹雳,后来在 Digg, feedly, inoreader 之间辗转,目前是 inoreader 的 Pro 付费用户,前几天在推上看到有人提到 miniflux,遂去瞄了一眼,看起来比较简洁,本着尝试的态度部署了一下,体验还可以,虽然暂时无法替代 inoreader,采用官方提供的 docker-compose.yaml 即可,如下:

$ cat miniflux/docker-compose.yml 
version: '3'
services:
  miniflux:
    image: miniflux/miniflux:latest
    ports:
        - "127.0.0.1:8080:8080"
    depends_on:
      - db
    environment:
      - DATABASE_URL=postgres://miniflux:secret@db/miniflux?sslmode=disable
      - RUN_MIGRATIONS=1
      - CREATE_ADMIN=1
      - ADMIN_USERNAME=xx
      - ADMIN_PASSWORD=xx
  db:
    image: postgres:latest
    environment:
      - POSTGRES_USER=miniflux
      - POSTGRES_PASSWORD=secret
    volumes:
      - miniflux-db:/var/lib/postgresql/data
volumes:
  miniflux-db:

最后我们统一采用 Caddy 进行反向代理。

RSShub 服务器🔗

不多说,在这个 RSS 衰落的年代,能有这样一个开源项目简直是人间希望,非常感谢开发者。使用官方提供的 docker-compose 部署方式即可。

Caddy 反向代理服务器🔗

最近因为可以自动申请 https 证书了解到这个使用 go 写的 web 服务器,折腾了一下将上述部署的所有服务都采用了反向代理,免费省心上了 https,美哉。由于不想折腾,Caddy 没有采用 Docker 方式,只需要 apt 安装一下设置下配置文件即可,不用 Docker 也不麻烦。我使用的配置文件如下:

(common) {
  header {
    # Enable HSTS. https://mdn.io/HSTS
    Strict-Transport-Security max-age=31536000;
    # Prevent MIME-sniffing. https://mdn.io/X-Content-Type-Options
    X-Content-Type-Options "nosniff"
    # Prevent clickjacking. https://mdn.io/X-Frame-Options
    X-Frame-Options "DENY"
    Referrer-Policy no-referrer-when-downgrade
  }
  encode gzip
  log
}

xx.wogong.net {
    import common
    tls [email protected]
    reverse_proxy localhost:8080
}

xx.wogong.net {
    import common
    tls [email protected]
    reverse_proxy localhost:1200
}

xx.wogong.net {
    import common
    tls [email protected]
    reverse_proxy /notifications/hub/negotiate localhost:3011
    reverse_proxy /notifications/hub localhost:3012
    reverse_proxy localhost:3011
}

可能有读者会质疑,为什么要采用自建服务?免费或者付费的商业服务他不香么?确实,自建无论体验优劣,肯定是比商业服务要多折腾一些(当然可以argue部署这些服务其实并不难,但是大部分普通用户可能连自己的服务器都没有),对我而言,主要组建的服务不是太劣于商业服务,我还是倾向于使用开源方案自己部署。

支持开源的意义在于,可以对商业服务说 fuck you. 在这个个人和大企业力量完全不对等的时代,保护自己的数据和隐私显然非常困难,正因为如此,作为有能力的个人,更要在反思之余,亲自去实践。这些自建服务,不止可以自己使用,还可以分享给家人,身边的朋友。以一己的微薄之力,做点小小的贡献。

最后,感谢 Docker,感谢 Caddy,感谢这些开源项目的开发者。希望这个世界变得更好,至少自己变得更好 XD

关于笔记软件

作为一名资深的磨刀人,对于笔记软件自然使用过无数款。简单总结一下所有的产品和过往的一些记录。

  • Workflowy
    • 非常棒的大纲工具,我使用的时间并不长。界面流畅,交互体验顺滑。
  • 幕布
    • 国内的 Workflowy,添加了思维导图的功能,然而我几乎不用思维导图,长期付费会员,可惜还没到期就放弃不使用了,以后记得这类千万不要买超过一年的会员。
  • Bear
    • macOS 上的文本编辑,我怎么也不习惯用文件的方式记笔记。
  • Ulysess
    • 类似 Bear,本质上是个写作工具。
  • Vimwiki
    • 最早接触的,我最初公开分享的 wiki 页面就是 vimwiki 生成的。
  • Drafts
    • iOS 上的文本书写工具。
  • Simplenote
    • 简洁,共享功能很棒。
  • Google Keep
    • 日志记录,搜索功能强大, OCR 功能很棒。
  • Notes.APP
    • Apple 生态下的随手记录,可以尽量不使用。
  • Day One
    • 日记,界面优美,可惜不跨平台。
  • Evernote
    • 存放各种 Review 笔记,扫描的收据,剪藏的文章,目前个人用来做各种渠道的信息收集。还没放弃它的原因是可以检索图片中的文字。但是实在太重了。新人不建议使用了。
  • notion
    • 结构化信息,书评,主要笔记场所,但是中文搜索有问题
  • Jrnl
    • 作为日常随手笔记应用,记录工作日志,日常日志
    • 启发自 jrnl,一个 pyhton package 用于命令行记录的日志工具
    • integrated with Telegram, so I can journal by telegram messaging to the bot
    • developed a server API, so I can journal by command line using [[Alfred
  • Roam Research
    • 主力使用,存放任意类型笔记,读书观影万物皆可,目前的增量信息都使用 RR 来管理吧。关于是否可以替代 Day One 成为日常 log 工具还需要考虑。
    • 优点:
      • 省钱了,Day One 订阅费用一年 35 USD
      • 统一的集中数据库
    • 缺点
      • 移动端暂时没有好的方案
      • 私人信息会污染数据库
      • 没有华丽的 UI 和当年今日等回顾性质的内容
  • Joplin
    • an open source note taking and to-do application with synchronization capabilities for Windows, macOS, Linux, Android and iOS. Forum: https://discourse.joplinapp.org/
    • 没有使用过,可以将 Evernote 笔记导出为 markdown 文件,很棒。

附上8年前的一些想法:

  • Evernote 与 vimwiki 的比较: 今天无意看到xbeta对evernote的评价,反思最近对evernote的迷恋与对wiki的质疑,恍然大悟,明白自己应该怎样去选择。Evernote应该是知识积累收集的,尤其是在网页上看到需要的资料,在写论文时搜索的各种材料,简单的点击一下鼠标,便收集到evernote中,方便日后整理。至于wiki,应该是个人经验的整理收集,例如学了什么东西,有什么想法,怎样解决一个问题的,这些都是可以打开vim作下记录,文字并不多,但是对日后的作用却是非常大的。课程笔记什么的根本没有必要在wiki上作详细记录,复习时有个提纲足矣。[20120318]

红米 K30i 安装欧版 ROM

解锁🔗

  • 手机登录小米账号。
  • 进入设置→我的设备→全部参数,反复点击MIUI版本开启开发者选项。
  • 进入设置→更多设置→开发者选项→设备解锁状态,按系统提示的步骤绑定账号和设备。
  • 下载官方解锁工具,按照工具自带的引导教程解锁即可,或参考图文教程。遇到问题可以参考小米手机解锁 Bootloader 教程和常见问题。一般新机会要求等待7天才能解锁。

安装ADB🔗

点击链接下载ADB:

刷入TWRP🔗

  • 下载地址 https://androidfilehost.com/?w=files&flid=50678 根据机型下载对应的 TWRP
  • 掏出手机,进入设置→更多设置→开发者选项开启USB调试后,用数据线连接电脑,手机会询问USB用途,选传输文件
  • 打开cmd,输入以下命令重启手机到Bootloader。 adb reboot bootloader
  • 重启至Bootloader后(屏幕内容为兔子修理安卓机器人),继续输入命令 fastboot devices -l, 若返回串号, 则说明手机连接成功。
  • 刷入 TERP
    fastboot flash recovery twrp_xxx.img
    fastboot boot twrp_xxx.img
    

刷入欧版MIUI🔗

MIUI v12 下载地址 https://sourceforge.net/projects/xiaomi-eu-multilang-miui-roms/files/xiaomi.eu/MIUI-STABLE-RELEASES/MIUIv12/ 根据机型下载对应 ROM

接着手机关机,长按“电源键”+“音量+”,重启手机到TWRP。

具体步骤

  • 进入TWRP首页,依次进入清除→格式化Data分区→输入yes格式化;
  • 返回上一级菜单,进入高级清除选项,勾选Dalvik/ART Cache,Data,内部储存,Cache,System并滑动滑块确认清除。
  • 返回TWRP首页,依次进入重启→Recovery。
  • 重启进入TWRP首页后,手机USB连接电脑,将下好的rom包放进手机内部储存根目录。
  • 从TWRP首页进入安装,选中你复制进去的ROM包,拖动底部滑块滑动确认刷入即完成了欧盟版MIUI的刷入。
  • 重启手机,等待首次启动读条,进去便是干净的欧盟版MIUI。

刷入Magisk取得Root权限🔗

如果你需要Root(推荐root),则继续留在TWRP里操作:

  • 返回TWRP首页,依次进入高级→root系统,滑动滑块即可刷入Magisk。(由于K30 5G版的TWRP已内置root功能,所以能这样直接刷入。)
  • 如果你手机的TWRP没有内置root,则需要手动下载Magisk卡刷包,像刷入ROM一样刷入即可。

参考链接🔗

KeePass 迁移到 1Password,再迁移到 Bitwarden

使用密码管理器有些年头了,2010 年前后最初选择的是 lastpass,后来短暂尝试过 1password,使用时间最为久远的是开源的 KeePass。 Keepass 的跨平台是基本满意的,Windows 下的客户端支持最全面,Linux 下使用 KeepassXC,macOS 下使用 macpass,iOS 下的客户端非常多, 免费付费的都有,我尝试过的有 MiniKeePass,Kypass,在这次迁移前一直使用的 Kypass。

迁移的原因无外乎 Kypass 的一些细节还是不如 1Password。简单记录一下迁移流程。

使用 Windows 上的 Keepass 客户端导出 csv 文件,使用 vim 对 csv 文件进行预处理,使得能够导入 1Password,涉及到的主要命令有

%s/\r/r/ 将 ^M 替换为换行

%s/\([^"]\)\n/\1 / 将注释中的换行符替换为空格

%g/^$/d 删除空行```

另外由于 1Password 支持两步验证,OTP 协议。所以将之前所有的两步验证从 Authy 迁移,参考 https://gist.github.com/gboudreau/94bb0c11a6209c82418d01a59d958c93#gistcomment-2224133

/Applications/Authy Desktop.app/Contents/MacOS/.Authy\ Desktop –remote-debugging-port=5858


不满意 1Password 的地方
- 没有文件夹管理
- 数据类型复杂(logins, Credit Cards, Secure Notes)导致的导出迁移困难

满意的地方
- OTP 集成
- 交互体验优于 KeePass (iOS macOS 上的自动填充等细节)


2020-11-20 Update:

最近又决定尝试一下 Bitwarden,很早之前就耳闻过,以为部署麻烦,没想到使用 docker 部署如此顺畅,
部署的细节参考另一篇[文章](https://www.wogong.net/blog/2020/11/self-host)。
跨平台的体验,产品细节各方面个人体验并不逊色于 1Password,还是开源自己部署服务器的方式,迁移过来不需要更多理由了吧?

后浪

5月4日前夕,BiliBili 在央视发布了一则 2 分钟的广告短片,网站同时放出了接近 3 分钟的完整版本。题为“后浪”,写给年轻一代,完整版链接

我最早是在朋友圈看到好几个人转发,遂点进去看了,稍受感动,也转发了,当时的配文大意是,尴尬的年龄,要保持心态的年轻。 后来看到了翻转电台痛骂这段视频的节目,听完觉得很有道理,虽然听的时候忍不住笑起来。由于当时已经很晚,凌晨三点,遂没有在朋友圈转发。白天起床后,转发了另一篇公众号的文章。《后浪》,更像是一出盛大的、虚伪的奶嘴派对,原始链接。 当然完全能理解,这样的文章在朋友圈会受到什么样的待遇,大部分的回复是否定这篇文章。言辞包括,“说的不是一件事情”“这也太能杠了”“槽点太多”,确实这种评论只需要结论,不需要任何论证过程。我也没有回复,有些回复发出了又删除了。这种现象不止我,好几个好友都有类似行为。 后来在群聊中看到了,基于该视频再创作的另一个视频。 同样的音频,但是混剪的视频更“接地气”,这种与官方叙事迥异的民间叙事手段,通过解构原视频,给人以非常大的冲击力。戏谑的手法,比翻转电台的播客或者批判的公众号文章效果更佳,严苛程度也更轻。

这一事件中,我要反思的是,为何第一次看到这个视频时,没有生出部分人提到的生理不适感。直到听到翻转电台的播客,才意识到整个视频的荒谬?更进一步,可以问这样一个问题,是我的观点不够坚定随波逐流么?作为对比可以问其他看到公众号文章反驳的人,他们反驳的点在哪里?是下意识的反驳还是深思熟虑后的结果? 另一个态度是从商业的角度出发,夸赞B站的营销手段之高明,毕竟这只是B站出圈的商业广告而已,能获得如此多的讨论已经非常成功了。这种散发着油腻气息的言论令人作呕,但却有相当大的市场。毕竟无论多愚蠢的言论都会有人喝彩的。

以上是关于后浪事件的一些私人记录。

阅读挑战计划

三月底的时候,看到方可成老师在 Youtube 发布的推荐书籍视频,是早先在公众号“新闻实验室”发起的阅读挑战活动。看完视频感到一丝惶恐,因为推荐的书籍几乎全部不在我的舒适圈内,自认为喜爱读书,回顾一下发现看的书籍品类非常单一,多是小说或科幻,以及网络推荐较多的“网红”类书籍,历史哲学社科类几乎没有。

一时心血来潮,决定参考方可成推荐的书单结合自己积累的看不到头的待阅读书籍清单,确定了自己的2020阅读挑战书单。

  1. 一本名字里带有2的书:第22条军规
  2. 一本关于沟通的书:明亮的对话
  3. 一本封面只有文字,没有图片的书:政治秩序与政治衰败 : 从工业革命到民主全球化
  4. 一本反思互联网科技的书:算法霸权
  5. 一本描写乡村小镇生活的书:乡土中国
  6. 一本关于人类社会进步历程的书:当下的启蒙
  7. 一本关于气候变化的书:天翻地覆
  8. 一本打破性别刻板印象的书:我知道笼中鸟为何歌唱
  9. 重读一本曾经读过的书:钢铁是怎样炼成的
  10. 一本出版于你出生那一年的书:1991 如何阅读一本书
  11. 一本出版于2020年的书:待定
  12. 一本一天内能读完的书:小王子的领悟
  13. 一本关于2020年你想去旅行的城市的书:江城
  14. 一本时代背景在1920年代的书:了不起的盖茨比
  15. 一本关于纳粹的书:噩梦年代
  16. 一本你在路上看到别人在读的书:我的孤单我的自我,单身女性的时代
  17. 一本书名中或封面上有鼠的书:鼠疫
  18. 一本你想读但是没有信心能都下来的书:哥德尔、艾舍尔、巴赫
  19. 一本主人公和你从事相同职业的小说:太阳照样升起
  20. 一本访谈录:八十年代访谈录
  21. 一本诗集:事物的味道 我尝的太早了
  22. 一本和最亲密的朋友约好一起读完的书:内向高敏者
  23. 一本和日本有关的书:拥抱战败
  24. 一本诺贝尔奖得主的书:贫穷的本质/非理性繁荣

《明亮的对话》短评

[阅读挑战2020]({% post_url 2020-05-01-read-challenge %})这个书单看完的第一本书,是徐贲老师的《明亮的对话》,阅读体验是欣喜甚至可用狂喜来形容,一方面是欣喜这本书解答了自己关于公共对话的一些困惑,另一方面是欣喜自己参与了这个阅读挑战,后面可能还会遇到很多类似书籍。

一气呵成读完之后,想着应该推荐给身边的朋友。可是如何推荐才能不辜负这样一本好书?对于大部分书籍,一般只是在豆瓣上写几句话的短评,偶尔有些篇幅较长的书评,也是随性所至,不求章法。依旧这样的态度,可能会适得其反。好在书单上的那本《如何阅读一本书》可以作为参考,尤其是关于如何成为一个自我要求的读者章节。接下来的文字,可以认为是我对这本书的阅读笔记,供自己以后翻阅,也是向各位推荐。

《明亮的对话》,副标题公共说理十八讲。作者是徐贲(音同奔),长期在美国教授论证说理和人文教育课程。这本书的内容副标题已经道明本书的主题是关于公共说理。说理就是讲道理,公共说理即如何在公共空间讲道理,公共说理的内涵很广泛,我们日常对于时事的谈论,也可以算作公共说理。这本书围绕公共说理总计十八讲,介绍了公共说理的概念、结构、技巧、必要性以及公共说理和伦理、公民教养、民主等相关主题的关系。

为什么选择读这本书?一个对当下社会有所关注的人,应该能感受到公共舆论环境的恶化。互联网上充斥着非理性的言论,反智、犬儒以及各种充满极端情绪的文字,我们还有可以好好说话的公共空间么?如何进行理性、以求知交流为目的的对话?因为对现实的失望,很多人选择不发声,压抑自己的表达,或者用冷嘲去隐晦地表达。个体如何面对这一切?大部分人或者说我自己是缺失公共说理的训练的。带着这些失望和疑问,翻开了这本书。

这本书由前言和后续十八讲组成,前言直说中国需要公共说理教育和公民理性(本书出版于2014年,在今天谈这个话题比当初更为重要),列举了一些让人失望的非理性言论,主角不只是个别网民,还包括一些严肃媒体。究其原因,是我国缺乏说理教育,对比了美国从小学、中学到大学的说理教育。强调了说理是需要刻意学习的。自说自话与高调宣传都不是公共说理,而我们的日常生活却充斥着这两者。

接下来八讲是关于说理的技术讨论,主要按照古希腊的修辞学框架(这里使用的是广义的修辞含义)。结合逻辑论证的三段论,讨论了说理中的各个部分,例如主张,理由,论证等。这一部分包括了一些说理的概念、定义和原则。

剩下的部分包括的内容比较广泛,介绍了美国教育体系中的“随笔”写作和说理的关系,说理与公民教育、政治民主、伦理道德层面的联系,以及非说理宣传对人的危害。这部分的逻辑结构不是非常清晰,毕竟是随笔的形式,每一讲中也有重复出现的内容。这一点也是被读者较多批评的点。 读毕这本书,让我了解到公共说理是有一整套技术细节的,不是辩论中的各种奇技淫巧,更不是不容质疑的断言。了解这些人类文明的积淀,可以让我们有更理性的思维,更能清晰明白地表达自己的观点。同时,也能帮助识别那些非理性的话语,例如商业广告和官方机构的话术。逻辑谬误并不都显而易见,刻意的训练才能让你获得识别这些谬误的技能。 说理教育不是为了使人论辩获胜,也不仅是单纯技能的传授,而是与人的文化教养和道德素质联系在一起,传承着人类共同文明和自由、平等、理性的说理价值。这才是公民社会要培养的“公共说理教育”和“公共理性”。

我们相信说理比不说理更能找到真实和公正的东西。我们希望,说理可以成为明亮的对话,一种自由、理性而持续的公共交谈。

关于 as with

2020年3月3日,桥水基金的老板 Ray Dalio 发布了一篇关于疫情的文章 My Thoughts About the Coronavirus,文章并不长,理解起来也没有太大难度。比较有争议的可能是最后一段。

The most important assets that you need to take good care of are you and your family. As with investing, I hope that you will imagine the worst-case scenario and protect yourself against it.

一部分人(包括本人)在理解最后一句话的时候,是这样的:“至于投资,我希望你考虑到最坏的情况……”,在受到质疑后,Google 查证后,发现 as with 的含义应当是 just like. 所以正确的理解应该是:“正如投资一样,我希望你考虑到最坏的情况……”。

故事到这里本应结束,直到我看到了微信公众号上这篇文章的中文翻译。当时在阅读原文时觉得有些地方理解不清楚,便收藏了这篇译文。点开文章发现译文的最后一段的理解正是我之前错误的版本。(我最初看到的中文版本链接已经无法找到,通过关键字搜索找到的文章同样是错误理解,估计用的同一个人的翻译)。两个毫无关系读者的理解错误,让我对这件事情有了兴趣。究竟有多少人会犯这样的错误,或者这句话正确的理解是否就应该是前者?我在微信的聊天群组和朋友圈以及私聊等渠道问了一些朋友,希望了解他们对这句话的理解。

扩大样本数量得到的结果也比较有趣,虽然“至于”理解人数并不少,但是大部分人(包括 native speaker)都认为正确的理解应当为“正如”。理解成“至于”确实更符合上下文,如果最后一句话说的是家庭方面需要,“考虑最坏的情况,保护自己免受伤害”,有耸人听闻制造惶恐之感,而且我们真的到了那一步么?然而从字面含义,as with 确实就是“正如”的含义,并无“至于”的含义(as for),作者告诫读者,做最坏的打算,也是强调对疫情的重视。

对这句话的理解偏差,到底还是归结于对短语意思理解的偏差,巧合的是这种偏差指向了一个逻辑上更“合理”的含义,大概这也是为什么这么多人理解错误。实际上,我在最初遭到质疑的时候,还是很坚定自己的理解是正确的,真是无知。想到自己在日常英文阅读中,不知道多少作者的含义被曲解,不禁后怕,以后还是应该多学习。

感谢在这一问题上指教的朋友们。疫情期间,各位保重。

关于疫苗

2020年3月17日,微信群聊看到转发了这样一条新闻重组新冠疫苗获批启动临床试验,上一次看到类似新闻是在科大一位老师的朋友圈,发了陈薇院士注射“疫苗”的照片。当然是乌龙事件,事实上当时注射的是胸腺肽。即使是疫苗,院士也不可能以身试药。看到新闻后我是有点惊讶的,因为这段时间以来,我获得到的信息是,传染病流行期间,指望疫苗来结束疫情是不大可能的,因为疫苗的研发周期过长。从1月份疫情正式肆掠,到目前三月中,疫苗就进入临床试验这个速度还是让我有点不可思议,即使考虑到免去了很多阶段。网上检索了一下,发现美国新冠疫苗开始人体试验,时间早于预期,(对于两条消息先后出来背后有无政治含义留给读者自行解读)。两条几乎是一前一后的消息让我对疫苗感到好奇,这也是这篇文章的由来。

中国这边进入临床试验采用的是重组疫苗技术,美国 Moderna Inc. 采用的是 mRNA 技术。好在国泰证券的一份研究报告做了足够的普及,感兴趣的朋友可以直接阅读这份报告 新型冠状病毒 肺炎 疫苗 系列 研究之一: 研发进展,里面对当前国际上的疫苗研发技术做了总结,也算是更新了一下我这方面几乎空白的知识。

另一个发现是关于埃博拉病毒疫苗的。我在检索陈薇院士时,发现网上有2017年的新闻,提到陈薇院士和康希诺生物公司合作研发埃博拉疫苗成功。这更是让我吃惊。埃博拉病毒之所以如此恐怖,一方面是症状可怖,另一方面也是目前尚无好的治疗药物以及疫苗(我一直这么认为,直到看到这条新闻)。既然 2017 年就已经研发成功,通过了 CFDA 的审批,为何一直没有听到关于这款疫苗的消息?好奇之下,我去找来了康希诺生物公司2019年中的财报,感兴趣的朋友可以网上自行搜索,这是公开资料。在财报中有这么一段介绍。

Ad5-EBOV由軍事醫學科學院生物工程研究所與我們共同研發。 其使用腺病毒載體技術來誘導免疫反 應。 Ad5-EBOV是中國第一種獲批准作應急使用及國家儲備的埃博拉病毒疫苗。 中國並無其他獲批准的 埃博拉病毒疫苗。

與現有疫苗及在研疫苗相比, Ad5-EBOV擁有下列優勢, 包括(i)因屬凍乾劑型及經證實可於2 °C 至8 °C 之 間保存12個月, 故具有更好的穩定性;(ii)其為失活非複製型病毒載體疫苗, 安全性問題較小;及(iii)其 為潛在可大範圍預防扎伊爾型埃博拉病毒的疫苗。

於2017年10月,Ad5-EBOV在中國獲得新藥申請批准,僅作應急使用及國家儲備。根據新藥申請批准, 獲批的每劑Ad5-EBOV含有8.0 × 10 10 個病毒顆粒, 基礎免疫建議劑量為一劑(2瓶)。 Ad5-EBOV的保質期 為12個月。我們已就Ad5-EBOV獲得GMP資格證書。

目前我們預計Ad5-EBOV將不會於未來對我們的業務作出重大商業貢獻, 主要原因是Ad5-EBOV的全球 庫存及應急用途市場有限, 於未來十年將維持於每年200百萬元人民幣, 預計到2030年潛在旅客市場 規模將少於300百萬元人民幣, 如招股章程中所披露。 我們預計不會就Ad5-EBOV的進一步研究產生重 大成本或分配重大資源, 亦不會就Ad5-EBOV作出任何重大承擔。 我們會否對Ad5-EBOV進行進一步研 究,將視乎中國政府對於埃博拉疫苗的計劃,我們預期將主要依賴政府補助進行該等研究(如有)。

看起来非常令人遗憾,投入重金研制成功的疫苗被束之高阁,仅被用于国家紧急储备。2018-2019年,非洲又爆发了埃博拉疫情,这款 2017 年通过审批的药物并没有起到任何作用。我不禁要问,这款疫苗真的可用么?

在搜索过程中,我看到了另一款埃博拉疫苗的情况,是来自美国默沙东公司研发,2019年11月通过FDA审批,2020年2月在非洲几个国家已经注册成功,预计2020年第三季度上市。

摘自 新闻链接

进度最快的是默沙东的Ervebo,这是一种利用埃博拉病毒经过基因改造的单剂量注射减毒活疫苗。由于Ervebo保护力几乎百分之百,且疫苗的副作用又相当轻微,因此FDA授予了Ervebo突破性药物资格。又由于预防埃博拉病毒病对公众健康的重要性,FDA在不到6个月的时间内完成了对Ervebo安全性和有效性的评估,较处方药用户收费法(PDUFA)目标日期2020年3月14日提前了近4个月。而在11月11日,Ervebo疫苗刚被欧盟委员会批准有条件上市,预计2020年生产上市。

在 WHO 的网站上,我看到了一个这样的文件,关于埃博拉疫苗研发情况的回顾 https://www.who.int/immunization/sage/meetings/2019/october/6_Ebola_Candidate_Vaccines_19-09-19.pdf

中国研发的这款最近更新是 “EUAL application was submitted to WHO in July 2018 and is currently under review”。

作为一个局外人,我不太清楚这背后有什么故事,仅仅把个人在网上公开检索到的信息放在这里。难免有错误,仅供参考。

期待新冠病毒疫苗早日上市,虽然道路漫长。

疫情与经济

2020 年新冠疫情期间,被困在西北边陲。新疆这边由于地广人稀,武汉至乌鲁木齐的人员流动也较少,总体来看疫情形式并不严峻。但是这边的管控措施可能不弱于全国除武汉外任和地方。好在有着大量“管控”的经验。这么长的空闲时间,本应该更多用来做些事情。大部分时间却用在看剧与刷新网页之上,非常的可惜。乐观点说,一辈子能遇到一次这种 pandemic 已经不易,希望多留下一点文字记录。

疫情期间时间充裕,花了很长时间来看股市。关于疫情对经济的影响,一个广泛的共识是,短期会被高估,长期会被低估。市场上也充斥着关于疫情对经济影响的声音。这里摘录一些影响力比较大的个人或机构的观点。

Ray Dalio🔗

https://www.linkedin.com/pulse/my-thoughts-coronavirus-ray-dalio

三个方面

  1. 病毒
  2. 因应对病毒造成的经济影响
  3. 资本市场的行为

(年底总结发现,这个坑就放在这里了,容我不要脸地先放出来,不然永远都在草稿里面了。

普鲁斯特问卷

从播客节目《不丧》十月的一期:“你最大的恐惧是什么?”——再做普鲁斯特问卷,了解到普鲁斯特问卷,链接 https://busangpodcast.simplecast.com/episodes/the-proust-qustionnaire-round-two-7RxZph6_ 普鲁斯特就是写《追忆似水年华》这本大部头枕边书的作者。

摘录一下中文维基百科对此的介绍。

普鲁斯特问卷(Proust Questionnaire)是一种用来调查被提问者个人生活方式、价值观、人生经验等问题的问卷调查。普鲁斯特问卷其名称来自于《追忆逝水年华》的作者马塞尔·普鲁斯特(Marcel Proust),但普鲁斯特并不是此问卷的发明者,只是因为他曾对问卷给出过著名的答案,此后人们才把其命名为普鲁斯特问卷。据说普鲁斯特在13岁和20岁时各做过一次普鲁斯特问卷,后来的研究者曾用这两次问卷结果分析普鲁斯特的个人成长经历。

奔三之际,留下一点记录。问题列表也来自中文的维基百科

  1. 你认为最完美的快乐是怎样的? 无后顾之忧的。

  2. 你最希望拥有哪种才华? 表达能力。

  3. 你最恐惧的是什么? 知其不可、手足无措的绝望。

  4. 你目前的心境怎样? 轻度焦虑,社交困惑。

  5. 还在世的人中你最钦佩的是谁? 没有。

  6. 你认为自己最伟大的成就是什么? 选择改变方向。

  7. 你自己的哪个特点让你最觉得痛恨? 不够勇敢,不够专注。

  8. 你最喜欢的旅行是哪一次? 一个人走西北。

  9. 你最痛恨别人的什么特点? 我不喜欢不守时的和以自我为中心的人,对自己和对别人要求不一样。

  10. 你最珍惜的财产是什么? 健康的身体和不差的大脑。

  11. 你最奢侈的是什么? 花很多时间折腾并不功利之物。

  12. 你认为程度最浅的痛苦是什么? 空虚的痛苦。

  13. 你认为哪种美德是被过高的评估的? 仁义礼智信我选择礼。

  14. 你最喜欢的职业是什么? 码农。

  15. 你对自己的外表哪一点不满意? 身高。

  16. 你最后悔的事情是什么? 鲁莽行动。

  17. 还在世的人中你最鄙视的是谁? 没有。

  18. 你最喜欢男性身上的什么特质? 勇敢。

  19. 你使用过的最多的单词或者是词语是什么? 哈哈?

  20. 你最喜欢女性身上的什么特质? 真诚

  21. 你最伤痛的事是什么? 没有。

  22. 你最看重朋友的什么特点? 真诚

  23. 你这一生中最爱的人或东西是什么? 我自己。

  24. 你希望以什么样的方式死去? 睡梦中。

  25. 何时何地让你感觉到最快乐? 羽毛球场上精彩的多拍,并且取胜。

  26. 如果你可以改变你的家庭一件事,那会是什么? 有钱哈哈哈哈哈哈

  27. 如果你能选择的话,你希望让什么重现? 没有。

  28. 你的座右铭是什么? 知行合一。

RSS 记录

本文记录如何使用 RSS 订阅几个常用网站的方法。

微博🔗

https://rssfeed.today/weibo/

饭否🔗

饭否用户所发消息的 RSS 输出地址:

http://api.fanfou.com/statuses/user_timeline/USER_ID.rss

其中用户的 USER_ID 可参见该用户饭否页面地址:

http://fanfou.com/USER_ID

这个地址可在 RSS 阅读器中订阅,无需登录。仅对公开账号有效。

微信公众号🔗

“今天看啥“免费账户可以订阅两个公众号试用,付费。

“瓦斯阅读“据说也是一个不错的方案,不过没有尝试,付费。

微信的反爬虫措施比较恶心,自己写爬虫抓取方案要解决验证码问题,不是太好处理。

知乎专栏🔗

感谢 lilydjwg 的工作,提供了知乎等网站的转 RSS 方案

网站 https://rss.lilydjwg.me/

项目代码 https://github.com/lilydjwg/morerssplz

V2EX🔗

1、全站RSS输出:

https://www.v2ex.com/index.xml

2、单独节点RSS输出:

http://www.v2ex.com/feed/{节点名}.xml 

以shadowsocks为例:http://www.v2ex.com/feed/shadowsocks.xml 

3、其他节点输出:

最热 / 最新主题:参考:编程 | RSSHub https://docs.rsshub.app/programming.html#v2ex 

也可以直接在Feedly里搜索,里面有现成的。

4、单独订阅某个帖子评论:

参考:各种转 RSS 服务 https://rss.lilydjwg.me/ 

5、未读提醒RSS源:

登陆账号之后: https://www.v2ex.com/notifications 的最下面。

参考:

其他🔗

使用 RSSHub 方案。自己搭建感觉不是非常稳定,约束于反爬虫等等方案。

cross compile h3c on merlin

学校用的华三认证,几年前折腾了一下在 openwrt 平台上的华三认证,主要就是交叉编译获得二进制文件。后来入手了 ASUS AC66U B1,硬件同 ASUS AC68U,懒得折腾系统,就接在之前的路由下,当二级理由使用,一级路由(openwrt)负责华三认证,用着也没什么问题。最近一级路由另有他用,所以抽空(熬夜)完成了 asus-merlin (梅林)平台上华三认证脚本的交叉编译。本文做一个简单的记录。

交叉编译的概念是在一个平台上编译另一个平台使用的二进制文件,在本文中,具体是在 X86 架构的 Ubuntu 18.04 上编译 arm 架构的 asus-merlin 系统中使用的二进制文件。

首先,下载 merlin 固件源码。改版的固件也是使用梅林的交叉编译工具链。注意下载对应版本的源码。由于我使用的是 380.x 旧版固件(380.70_0-X7.9.1 koolshare 改版),源码在 Github 的仓库链接为 https://github.com/RMerl/asuswrt-merlin,在仓库的 release 页面下载对应版本的源码到本地,解压备用。梅林的交叉编译工具链在梅林源码 release/src-rt-6.x.4708/toolchains/hndtools-arm-linux-2.6.36-uclibc-4.5.3,release 下应该是固件版本的不同,但几个固件版本下的 toolchains 均指向这个文件夹,应该是 toolchains 没有改变过。

其次,本地编译环境准备,推荐使用 Docker,参考其他教程,使用这个链接的 Dockerfile https://github.com/mritd/dockerfile/tree/master/asuswrt-merlin-build。参考 readme 应该问题不大,不过因为 docker 版本的改变,有些命令需要调整。我用到的主要命令如下

docker image build -t build asuswrt-merlin-build
docker container run -v /home/wogong/asuswrt-merlin-380.70:/home/asuswrt-merlin -v ~/nu-h3c:/root/nu-h3c -it build:latest bash
export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:/home/asuswrt-merlin/release/src-rt-6.x.4708/toolchains/hndtools-arm-linux-2.6.36-uclibc-4.5.3/lib:/usr/local/lib:/u
sr/lib
export CC=/home/asuswrt-merlin/release/src-rt-6.x.4708/toolchains/hndtools-arm-linux-2.6.36-uclibc-4.5.3/bin/arm-linux-gcc
$CC <name> -o <name>

到这一步应该就结束了,scp 二进制文件到 merlin 系统,测试成功。

参考🔗

# 我校静态 IP 配置
option ipaddr '172.18.201.233'
option netmask '255.255.255.0'
option gateway '172.18.201.254'

如何进行内网穿透

内网穿透,又称 NAT 穿透,主要目的是为了访问位于 NAT 后的计算机。我的使用场景是访问位于实验室的机器,实验室网络环境为中国联通的 4G,这种情况下端口映射之类的方法是无能为力的,下面主要回顾一下自己用过的几种内网穿透方法。

SSH 端口转发🔗

花样繁多,暂时没有搞清楚,待补充。

Zerotier🔗

https://www.zerotier.com/

不需要公网服务器。

商业服务,免费用户有一定限制,但是可用。有跨平台的客户端,非常适合懒得自己动手的人。但是速度一般。

frp🔗

https://github.com/fatedier/frp

需要公网服务器。

配置简单,样例丰富,稳定。个人使用体验非常不错,适合两个节点之间的连接。

WireGuard🔗

https://www.wireguard.com/

需要公网服务器

开源,现代。组建好个人虚拟局域子网后,在此子网内的设备可以相互进行无感的连接,非常方便。

tinc🔗

tailscale🔗

基于 wireguard 的 mesh vpn 服务 magic dns

nebula🔗