《黑客与画家》重读书摘

d2b5ca33bd970f64a6301fa75ae2eb22 1

很早之前就看过《黑客与画家》,但彼时的我并不能很好的理解和了解这本书到底在讲些什么。时至今日,当我在践行独立开发者的时候,我才真正意识到为什么这本书如此值得读。

推荐序 “黑客精神”过时了吗?答案是永远不会

  • 黑客精神的真谛是动手去创造性地解决问题。“解决问题”必须跟人的需求有关,需要持久地满足越来越多人的需求。“动手”需要有勇气,很务实,以行动为导向,除此以外,黑客还必须是一个积极向上的人。

保罗·格雷厄姆其人其事

  • “运营创业公司,每天都像在战斗;而为大公司工作,就像在窒息中挣扎。”
  • 保罗·格雷厄姆有一套完整的创业哲学,他的创业公式是: (1)搭建原型; (2)上线运营(别管bug); (3)收集反馈; (4)调整产品; (5)成长壮大。
  • 所有学员刚刚来到YC的时候,每人都会拿到一件白色T恤衫,上面写着“Make something people want”(制造用户需要的东西),等到他们的项目得到风险投资以后,又会收到一件黑色T恤衫,上面写着“I made something people want”(我制造了用户需要的东西)。

精装版译者序 向着未来而生

  • 未来就在眼前,伸手可及。《黑客与画家》就是这次旅程的指南,为你指出通往那扇门的方向。正如格雷厄姆所说,你要做的就是“活在未来,然后造出现在还没有的部分”(Live in the future, then build what’s missing)。 阮一峰 2

平装版译者序

  • 黑客行为必须包含三个特点:好玩、高智商、探索精神。只有其行为同时满足这三个标准,才能被称为“黑客”。
  • 《黑客:计算机革命的英雄》(Hackers: Heroes of the Computer Revolution)
  • 在该书中,他进一步将黑客的价值观总结为六条“黑客伦理”(hacker ethic),直到今天这几条伦理都被视为这方面的最佳论述。 (1) 使用计算机以及所有有助于了解这个世界本质的事物都不应受到任何限制。任何事情都应该亲手尝试。 (Access to computers—and anything that might teach you something about the way the world works—should be unlimited and total. Always yield to the Hands-On Imperative!) (2)所有信息应该都是自由的。 (All information should be free.) (3)不信任权威,提倡去中心化。 (Mistrust Authority—Promote Decentralization.) (4) 判断一名黑客的水平应该看他的技术能力,而不是看他的学历、年龄或地位等其他标准。 (Hackers should be judged by their hacking, not bogus criteria such as degrees, age, race, or position.) (5)你可以用计算机创造美和艺术。 (You can create art and beauty on a computer.) (6)计算机使生活更美好。 (Computers can change your life for the better.)

1 为什么书呆子不受欢迎

  • 在一个人产生良知之前,折磨就是一种娱乐。
  • 最好的情况下,那些事情也不过是遥远的将来我们可能从事的实际工作的练习。它所面向的目标是如此遥远,以至于当时我们都不知道自己练习这些到底是为了干什么。更常见的情况是,那些事情不过是一系列随意设置的绳圈,你被要求一个个跳过去。你在学习中遇到的文字都是专为考试而设计的,目的就是出题,而不是讲清楚问题。(例如,南北战争的三个主要原因是……等到考试的时候,就会有一道题:请列出南北战争的三个主要原因。) 而且,没有办法回避那些事情。成年人已经达成共识,认定通往大学的途径就是这样的。逃离这种空虚生活的唯一方法,就是向它屈服。

2 黑客与画家

  • 黑客与画家的共同之处,在于他们都是创作者。与作曲家、建筑师和作家一样,黑客和画家都试图创作出优秀的作品。他们本质上都不是在做研究,虽然在创作过程中,他们可能会发现一些新技术(那样当然更好)。
  • 所以,大学和实验室里的黑客,就不去做那些真正想做的事情(设计优美的软件),而是觉得自己应该写一些研究性的论文。
  • 优美的软件并不总是论文的合适题材。首先,科学研究必须具有原创性。写过博士论文的人都知道,确保自己正在开垦新领地的方法,就是去找那些没有人要的土地。其次,科学研究必须是能够产生大量成果的,而那些不成熟、障碍重重的领域最容易写出许多篇论文,因为你可以写那些为了完成工作而不得不克服的障碍。没有什么比一个错误的前提更容易产生大量待解决的问题了。
  • 创造优美事物的方式往往不是从头做起,而是在现有成果的基础上做一些小小的调整,或者将已有的观点用比较新的方式组合起来。这种类型的工作很难用研究性的论文表达。
  • 经过岁月的洗礼,优美的东西生存发展的机会更大,丑陋的东西往往会被淘汰。
  • 人们无法考核你的工作,甚至误解你的工作,都不是最糟的事。更大的危险是你自己也会误解自己的工作。
  • 我发现,黑客新想法的最佳来源,并非那些名字里有“计算机”三个字的理论领域,而是其他创作领域。与其到“计算理论”领域寻找创意,你还不如在绘画中寻找创意。
  • 它意味着,编程语言首要的特性应该是允许动态扩展。编程语言是用来帮助思考程序的,而不是用来表达你已经想好的程序。它应该是一支铅笔,而不是一支钢笔。如果大家都像学校教的那样编程,那么静态类型4是一个不错的概念。
  • 我们需要的是一种可以随意涂抹、擦擦改改的语言,我们不想正襟危坐,把一个盛满各种变量类型的茶杯,小心翼翼放在自己的膝盖上,为了与一丝不苟的编译器大婶交谈,努力地挑选词语,确保变量类型匹配,好让自己显得礼貌又周到。
  • 直到最近我才发现这一点。雅虎收购Viaweb的时候,他们问我想做什么。我对商业活动从来都没有太大兴趣,就回答说我想继续做黑客。等我来到雅虎以后,发现在他们看来,“黑客”的工作就是用软件实现某个功能,而不是设计软件。在那里,程序员被当作技工,职责就是将产品经理的“构想”(如果这个词是这么用的话)翻译成代码。
  • 真正竞争软件设计的战场是新兴领域的市场,这里还没有人建立过防御工事。只要你能做出大胆的设计,由一个人或一批人同时负责设计和实现产品,你就能在这里战胜大公司。微软公司自己一开始就是这样走向成功的,苹果公司和惠普公司也是如此。我觉得几乎所有的创业公司都是这样取得成功的。
  • 所有创作者都面临这个问题。价格是由供给和需求共同决定的。好玩的软件的需求量,比不上解决客户麻烦问题的软件的需求量;
  • 黑客如何才能做自己喜欢的事情?我认为这个问题的解决方法是一个几乎所有创作者都知道的方法:找一份养家糊口的“白天工作”(day job)。这个词是从音乐家身上来的,他们晚上表演音乐,所以白天可以找一份其他工作。更一般地说,“白天工作”的意思是,你有一份为了赚钱的工作,还有一份为了爱好的工作。
  • 几乎所有的创作者在职业生涯的早期都有一份“白天工作”。画家和作家尤其显著。如果幸运的话,你能找到一份与你的“真正工作”非常相关的“白天工作”。音乐家似乎常常是在唱片行工作。同样,钻研某种编程语言或操作系统的黑客,很可能会得到一份使用这些工具的“白天工作
  • 令我惊讶的是,雇主都很犹豫,不愿意手下的黑客为开源软件项目工作。但是,在Viaweb,要是你不愿意这样干,我们会很犹豫要不要雇用你。我们在面试程序员时,主要关注的事情就是业余时间他们写了什么软件,因为如果你不爱一件事,你不可能把它做得真正优秀,要是你很热爱编程,你就不可避免地会开发你自己的项目。7
  • 我想大多数创作者是这样学习和工作的,作家和建筑师似乎都是如此。也许对于黑客来说,采取像画家这样的做法很有好处:应该定期地从头开始,而不要长年累月地在一个项目上不断工作,并且试图把所有的最新想法都以修订版的形式包括进去。
  • 绘画还有一个值得借鉴的地方:一幅画是逐步完成的。通常一开始是一张草图,然后再逐步填入细节。但是,它又不单纯是一个填入细节的过程。有时,原先的构想看来是错的,你就必须动手修改。无数古代油画放在X光下检视,就能看出修改痕迹,四肢的位置被移动过,或者脸部的表情经过了调整。 绘画的这个创作过程就值得学习。我认为黑客也应该这样工作。你不能盼望先有一个完美的规格设计,然后再动手编程,这样想是不现实的。如果你预先承认规格设计是不完美的,在编程的时候,就可以根据需要当场修改规格,最终会有一个更好的结果。(大公司的内部结构,使得它们很难这样做。这是创业公司的又一个优势。)
  • 如果黑客只是一个负责实现领导意志的技术工人,职责就是根据规格说明书写出代码,那么他其实与一个挖水沟的工人是一样的,从这头挖到那头,仅此而已。但是,如果黑客是一个创作者,他从事的就不是机械性的工作,他必须具备灵感。
  • 黑客就像画家,工作起来是有心理周期的。有时候,你有了一个令人兴奋的新项目,你会愿意为它一天工作16个小时。等过了这一阵,你又会觉得百无聊赖,对所有事情都提不起兴趣。
  • 对于画家和黑客这样的创作者,有些工作需要投入巨大的热情,另一些工作则是不需要很操心的日常琐事。在你厌倦的时候再去做那些比较容易的工作,这是一个不错的主意。
  • 消灭bug的过程就像解一道数学题,已知许许多多的约束条件,你只要根据条件对方程求解就可以了。
  • 正确的合作方法是将项目分割成严格定义的模块,每一个模块由一个人明确负责。模块与模块之间的接口经过精心设计,如果可能的话,最好把文档说明写得像编程语言规范那样清晰。
  • 了解别人对于事情的看法,并不代表你为他的利益服务。在某些情况下,比如在打仗的时候,了解对手正是为了打击对手12
  • 大多数创作者是为人类用户而创作。为了吸引用户,你必须理解用户需要什么。
  • 普通黑客与优秀黑客的所有区别之中,会不会“换位思考”可能是最重要的单个因素。有些黑客很聪明,但是完全以自我为中心,根本不会设身处地为用户考虑。这样的人很难设计出优秀软件,因为他们不从用户的角度看待问题。
  • 软件的部分功能就是解释自身。为了写出优秀的软件,你必须假定用户对你的软件基本上一无所知。你要明白,用户第一次使用你的软件的时候,不会预先做好功课,他们没有任何准备就开始用了,所以软件的使用方式最好能符合用户的直觉,别指望用户去读使用手册。
  • 程序必须写得能够供人们阅读,偶尔供计算机执行。

机制

  • 我并不是说斗争从来就与思想无关,而是要强调,不管实际上是否有思想斗争,斗争总是会以思想斗争的形式表现出来。正如刚刚过气的时尚并非一点儿也不时尚,失败一方的思想其实也并非一无是处。

为什么这样做

  • 在科学领域,质疑他人的结论和公认的假设是尤其重要的一件事,会提供巨大的科学创造的机会。科学家(或者至少是优秀科学家)做事的方式,准确地说,就是寻找传统观点无法自圆其说的地方,然后试着拆开那里,看个究竟,瞧瞧里面到底出了什么问题。新的理论就是这样产生的。
  • 一个好的科学家,并不仅仅是避开传统观点,还要努力打破传统观点。科学家就是要自找麻烦。这应该是任何学者的研究方式,但是科学家似乎特别愿意一探究竟。
  • 智力越高的人,越愿意去思考那些惊世骇俗的思想观点
  • 做出伟大产品的公司,自我评价往往以“批评”和“自嘲”为主,而不是以“肯定”和“表扬”为主。

守口如瓶

  • 讨论一个观点会产生更多的观点,不讨论就什么观点也没有。所以,如果可能的话,你最好找一些信得过的知己,只与他们畅所欲言、无所不谈。这样不仅可以获得新观点,还可以用来选择朋友。能够一起谈论“异端邪说”并且不会因此气急败坏的人,就是你最应该认识的朋友。

永远质疑

  • 所谓“流行”(传统观念也是一种流行),本质上就是自己看不见自己的样子,否则就不会有流行了。
  • 如果自己就是潮水的一部分,怎么能看见潮流的方向呢?你只能永远保持质疑:什么话是我不能说的?为什么?

4 良好的坏习惯

  • 对于适当的不服从管教保持宽容,这不会有太大的坏处,反而很有利于造就美国的国家优势,它使得美国不仅能吸引聪明人,还能吸引那些很自负的人。
  • 计算机确实是非常精确、有条不紊的,但是黑客的所作所为完全出于兴趣,想到哪里就做到哪里,没有明确的计划,只求开心。
  • 在我看来,一个人们拥有言论自由和行动自由的社会,往往最有可能采纳最优方案,而不是采纳最有权势的人提出的方案。

用户的胜利

  • 在我家附近,一辆汽车的保险杠上贴着一张粘纸,上面写着“不方便,毋宁死”(death before inconvenience)。在大多数时候,大多数人总是选择最省事的做法。如果互联网软件能够击败桌面软件,一定是赢在更方便这一优势上。无论从用户的角度还是从开发者的角度来看,都是如此。

软件的发布

  • 互联网软件的发布规则是:它运行不了,你就无法发布;一旦它能运行了,你就可以立刻发布。

客户支持

  • Viaweb不是这样。我们的客户支持是免费的,因为我们希望知道用户的反应。如果他们使用时遇到困难,我们希望立刻知道,这样就能再现错误,从而解决问题并发布新版本。
  • 我们的这种方法让所有人都感到满意。客户很高兴,拨打厂商服务热线是免费的,而且还被当作通风报信的人,受到郑重对待;客服人员也喜欢这样,因为这使得他们可以帮助用户,而不是对着用户读操作手册;程序员喜欢这样,因为他们能够再现bug,而不是通过模糊不清的二手报告了解bug。

全身心投入

  • 如果软件的新版本要等到一年后才能发布,我就会把大部分新构思束之高阁,至少过上一段时间再来考虑。但是,构思这种东西有一个特点,那就是它会导致更多的构思。你有没有注意过,在坐下来写东西的时候,一半的构思是写作时产生的?软件也是这样。实现某个构思,会带来更多的构思。所以,将一个构思束之高阁,不仅意味着延迟它的实现,还意味着延迟所有在实现过程中激发的构思。事实上,将一个构思束之高阁,甚至会限制新构思的产生,因为你看一眼堆放在一边还没有实现的构思,就会想“我已经为下一个版本准备了很多有待实现的新东西”,你就懒得再思考更多的新功能了。
  • 大公司的做法不是立刻实现新功能,而是先为新功能做一个计划。Viaweb就因此而遇到了麻烦。投资者和分析家会问,你们对未来有何计划。真实的回答是,我们没有任何计划。我们有改进的想法,但是如果我们想到应该怎么改进,就已经把它实现了。接下来6个月我们要做什么?进行所有能想到的最佳改进。我不知道自己是否有胆量公开这么说,但这是实话。计划这个词,只是将构思束之高阁的另一种表达方式。只要想到好的构思,我们就会立刻着手实现。
  • 当然,这样写软件也有局限。它适用于小型的、由优秀且可靠的程序员组成的开发团队,不适用于大型的、充斥着大量平庸之辈的软件公司,在那里不是程序员想出好的构思,而是一个委员会集体批准坏的构思。

逆向的《人月神话》9

  • 开发软件需要的程序员人数减少,不仅意味着会省下更多的钱。正如《人月神话》一书中所指出的,向一个项目增加人手,往往会拖慢项目进程。随着参与人数的增加,人与人之间需要的沟通成本呈现指数级增长。人数越来越多,开会讨论各个部分如何协同工作所需的时间越来越长,无法预见的互相影响越来越大,产生的bug也越来越多

金钱问题

  • 软件公司有时会采用分销模式,让ISP分销互联网软件。这样做很不好。服务器必须在你自己的控制之中,因为你需要不断改进硬件和软件。如果你放弃对服务器的直接控制,就放弃了互联网软件的大部分优势。

目标客户

  • 不少公司很想知道,什么事情可以外包,什么事情不可以外包。一个可能的答案是,公司内部所有不直接感受到竞争压力的部门都应该外包出去,让它们暴露在竞争压力之下。(我这里所说的“外包”,指的是聘请另一个公司来执行,而不是指把业务部门转移到海外。)

创业公司

  • 开发互联网软件的创业公司会把与创业有关的每一件事做到极致。只用更少的人、更少的钱,就可以把软件写出来,并且开始运作。你必须打破常规、快速行动,循规蹈矩不可能成功。你完全能够在只有三个人的情况下让产品开始运营,你们唯一的办公场所就是一间公寓,里面放着一台连着ISP的服务器。我们就是这样做的。
  • 纵观创业公司的历史,你会发现它们变得越来越小,越来越快,越来越不像正规的企业

为什么不尝试一下

  • 如果你是一个黑客,并且梦想自己创业,可能会有两件事情令你望而却步,不敢真正开始采取行动。一件是你不懂得管理企业,另一件是你害怕竞争。可是实际上,这两件事都是没有通电的电篱笆。
  • 做出用户喜欢的产品,保证开支小于收入。
  • 从制造简洁的产品着手,首先要保证你自己愿意使用。然后,迅速地做出1.0版,并且不断加以改进,整个过程中密切倾听用户的反馈。用户总是对的,但是不同的用户要求不一样。低端的用户要求简化操作和清晰易懂,高端的用户要求你增加新功能。软件最大的好处就是让一切变得简单。但是,做到这一点的方法是正确设置默认值,而不是限制用户的选择。如果竞争对手的产品很糟糕,你也不要自鸣得意。比较软件的标准应该是看对手的软件将来会有什么功能,而不是现在有什么功能。无论何时,你都要使用自己的软件。
  • 只有懂得设计的黑客,才能设计软件,不能交给对软件一知半解的设计师。如果你不打算自己动手设计和开发,那就不要创业。

运气的成分

  • 通过创造有价值的东西而致富,这种方法的优势不仅仅在于它是合法的(许多其他方法如今都是不合法的),还在于它更简单,你只需要做出别人需要的东西就可以了。

金钱不等于财富

  • 创造有价值的东西就是创造财富。你最好先搞清楚什么是财富。
  • 我这里指的只是一种特定的技术层面上的“财富”——人们用金钱和你交换的东西。这是一种很有趣、很值得研究的财富,因为它使得你免于饥饿,而且人们是否用金钱交换这种财富取决于他们,不取决于你。

手工艺人

  • 程序员坐在计算机前就能创造财富。优秀软件本身就是一件有价值的东西。

工作是什么

  • 当你为一家公司工作时,这也是你所做的事情。但是,公司内部的各种层级使得这一点有时不容易觉察到。你在公司内部所做的工作是与许多人一起合作完成的,你只是其中的一分子。你觉得自己是为公司的需要而工作,可能不会觉察到你其实是为了满足顾客的某种需求而工作。你的贡献也许不是直接性的,但是公司作为一个整体必须提供某种人们需要的东西,否则不可能盈利。

可测量性和可放大性

  • 任何一个通过自身努力而致富的个人,在他身上应该都能同时发现可测量性和可放大性。

小团队 = 可测量性

  • 整家公司产生的收入是可以测量的,如果公司只有一个员工,那么就可以准确知道他的贡献了。所以,公司越小,你就越能准确估计每个人的贡献。一家健康的创业公司可能只有10个员工,那么影响收入的人员因子最多也只有10。

用户数量

  • 风险投资商有一张清单,上面写满了各种表示不应该收购的危险信号。排在榜首的信号中有一个就是公司由技术顽童掌控,只想解决有趣的技术问题,不考虑用户的需要。你开办创业公司不是单纯地为了解决问题,而是为了解决那些用户关心的问题
  • 将公司管理视同软件优化还能帮你避免风险投资人担心的另一个陷阱——开发某种产品的时间过长。现在,黑客都已经熟知这一点,并总结出一个术语“过早优化”。尽快拿出1.0版,然后根据用户的反映而不是自己的猜测优化软件。

财富和权力

  • 还记得从经济学观点看什么是创业公司吗?简单地说,就是可以让人更快速工作的地方。

偷窃

  • 中产阶级的出现使得财富总量不再是一个固定不变的值,财富的分配也不再是一种零和游戏。苹果公司的两个创始人乔布斯和沃兹尼亚克没有使得他人变得更贫穷就赚到了钱。事实上,他们创造出来的东西使得人类的物质生活变得更富有。他们只能这样做,否则不会有人付钱给他们的。

技术的杠杆效应

  • 无法被技术变得更便宜的唯一东西,就是品牌。
  • 大学入学申请制度的设计者应该参考计算机安全行业的做法,不要假设你的系统毫无漏洞,而是搞清楚多大程度上漏洞无法被利用

公理的不同意见

  • 现代社会的收入差距扩大是一种健康的信号
  • 技术使得生产率的差异加速扩大,如果这种扩大没有反映在收入上面,只有三种可能的解释:(a)技术革新停顿了;(b)那些创造大部分财富的人停止工作了;(c)创造财富的人没有获得报酬。
  • 总的来说,你要避免的是绝对贫穷,而不是相对贫穷。

8 防止垃圾邮件的一种方法1

  • 数学家诺伯特·维纳(Norbert Wiener)说,如果你与奴隶比赛,你也会变成一个奴隶

9 设计者的品味

  • 我朋友的意思是,他想要的学生不仅应该技术过硬,还应当能够使用技术做出优美的产品
  • 好设计是简单的设计。从数学领域到绘画领域,你都可以听到这种说法。在数学中,它意味着简短的证明往往是更好的证明
  • 好设计是永不过时的设计。只要没有错误,每一个数学证明都是永不过时的
  • 好设计是启发性的设计。英国女作家简·奥斯汀的作品几乎不带有任何描述
  • 好设计通常是有点趣味性的设计。
  • 好设计是艰苦的设计。如果观察那些做出伟大作品的人,你会发现他们的共同点就是工作得非常艰苦。如果你工作得不艰苦,你可能正在浪费时间。困难的问题需要巨大的付出才能解决,高难度的数学证明需要结构非常精细的解决方法(往往做起来很有趣),工程学也是如此
  • 好设计是看似容易的设计。优秀运动员比赛时,让人觉得他轻轻松松就获胜了,优秀设计师也是如此,他们的工作看上去很容易
  • 好设计是对称的设计
  • 在数学和工程学中,递归尤其有用。归纳式证明方法既简洁又美妙。在软件中,能用递归解决的问题通常代表已经找到了最佳解法。
  • 好设计是模仿大自然的设计
  • 设计是模仿大自然的设
  • 写实的目的不是给生活留下一模一样的记录,而是为你的思想提供一个咀嚼点:你的眼睛看着某样东西,你的手就代表你的思想,画出一些比较有意思的内容。
  • 好设计是一种再设计。很少有人一次就把事情做对。专家的做法是先完成一个早期原型,然后提出修改计划,最后把早期原型扔掉
  • 扔掉早期原型是需要信心的,你必须有本事看出什么地方还可以改进。举例来说,刚刚开始学画的人往往不愿意重画画错的地方。他们觉得能画成现在这样已经很不错了,如果重画某些部分,结果可能还不如现在。所以,他们就说服自己,我的画已经过得去了,没准别人也会这么看
  • 犯错误是很正常的事情。你不要把犯错看成灾难,要勇于承认、勇于改正
  • 设计是能够复制的设计。我们对待复制的态度经常是一个否定之否定的过程。刚入门的新手不知不觉地模仿他人,逐渐熟练之后才开始创作原创性作品。最后他会意识到,把事情做对比原创更重要
  • 等到你逐渐对一件事产生热情的时候,就不会满足于模仿了。你的品味就进入了第二阶段,开始自觉地进行原创。
  • 你最后发展出来的风格是自然而然形成的
  • 好设计是成批出现的。
  • 推动人才成批涌现的最大因素就是,让有天赋的人聚在一起,共同解决某个难题。互相激励比天赋更重要,达·芬奇之所以成为达·芬奇,主要原因不仅仅是他的天赋,更重要的是他生活在当时的佛罗伦萨,而不是米兰。今天,人类生活的流动性高得多,但是伟大的项目依然不成比例地集中在少数几个热点上:德国包豪斯建筑学院、“曼哈顿计划”、《纽约客》杂志、洛克希德公司的臭鼬工作室、施乐公司的帕洛阿尔托研究中心。
  • 好设计常常是大胆的设计。在任何一段历史中,人们都会把某些荒谬的东西当作正确的,并且深信不疑,以至于一旦你出言质疑,就有被排挤或者被暴力伤害的危险。

面向对象编程

  • 允许你做某事的语言肯定不差于强迫你做某事的语言,所以至少在这方面我们可以得到明确的结论:你应该使用允许你面向对象编程的语言。至于你最后到底用不用则是另外一个问题了。

11 一百年后的编程语言

  • 我认为,基本运算符是一种语言能否长期存在的最重要因素,其他因素都不是决定性的。这有点像买房子的时候你应该先考虑地理位置。别的地方将来出问题都有办法弥补,但是地理位置是没法变的
  • essay(论文)这个词来自法语的动词essayer,意思是“试试看”。从这个原始意义来说,论文就是你写一篇文章,试着搞清楚某件事。软件也是如此。我觉得一些最好的软件就像论文一样,也就是说,当作者真正开始动手写这些软件的时候,他们其实不知道最后会写出什么结果。
  • 效率低下的软件并不等于很烂的软件。一种让程序员做无用功的语言才真正称得上很烂。浪费程序员的时间而不是浪费机器的时间才是真正的无效率。随着计算机速度越来越快,这会变得越来越明显

秘密武器

  • 我们唯一擅长的事情就是开发软件。我们希望这一点可以弥补我们的劣势。任何在软件开发上面有助于我们获得优势的事情我们都不能放过。

创业公司的合气道7

  • 编程语言是技术和宗教的混合物

朝着数学的方法发展

  • Lisp和Fortran代表了编程语言发展的两大方向。前者的基础是数学,后者的基础是硬件架构。从那时起,这两大方向一直在互相靠拢。Lisp语言刚设计出来的时候就很强大,接下来的20年它提高了运行速度。

随大流的代价

  • 因此,语言的编程能力越强大,写出来的程序就越短(当然不是指字符数量,而是指独立的语法单位

一个诀窍

  • 在大型组织内部,有一个专门的术语描述这种跟随大多数人的选择的做法,叫作“业界最佳实践”。这个词出现的原因其实就是为了让你的经理可以推卸责任。既然我选择的是业界最佳实践,如果不成功,项目失败了,那么你也无法指责我,因为做出选择的人不是我,而是整个业界

可编程性

  • 一种真正优秀的编程语言应该既整洁又混乱。“整洁”的意思是设计得很清楚, 内核由数量不多的运算符构成,这些运算符易于理解,每一个都有很完整的独立用途。“混乱”的意思是它允许黑客以自己的方式使用。C语言就是这样的例子,早期的Lisp语言也是如此。真正的黑客语言总是稍微带一点放纵不羁的个性。

再设计

  • 就算委员会只有两个人,还是会妨碍“再设计”,典型例子就是软件内部的各个接口由不同的人负责。这时除非两个人都同意改变接口,否则接口就无法改变。因此现实中,尽管软件功能越来越强大,内部接口却往往一成不变,成为整个系统中拖后腿的部分

15 设计与研究

  • 设计与研究的区别看来就在于,前者追求“好”,后者追求“新”。优秀的设计不一定很“新”,但必须是“好”的;优秀的研究不一定很“好”,但必须是“新”的。我认为这两条道路最后会发生交叉:只有应用“新”的创意和理论,才会诞生超越前人的最佳设计;只有解决那些值得解决的难题(也就是“好”的难题),才会诞生最佳研究。所以,最终来说,设计和研究都通向同一个地方,只是前进的路线不同罢了。
  • 在软件领域,贴近用户的设计思想被归纳为“弱即是强”(Worse is Better)模式2。这个模式实际上包含了好几种不同的思想,所以至今人们还在争论它是否真的成立。但是, 其中有一点是正确的,那就是如果你正在设计某种新东西,就应该尽快拿出原型,听取用户的意见。
  • 士气是设计的关键因素。令我吃惊的是,大家很少提到这一点。我的一位美术启蒙老师告诉我:如果你觉得画某样东西很乏味,那么你画出来的东西就会真的很乏味。假设你必须画一幢建筑物,你决定从每一块砖头开始画起。你觉得自己可以坚持下去,但是画到一半的时候突然感到很厌倦,于是你就不再认真观察每块砖头并画出它们各自不同的特点,而是以一种机械重复的方式草草地把砖头画完了事。这样一来,你的作品效果就很差,甚至还不如一开始就不采用写实手法,只是若隐若现地暗示砖头的存在
  • 先做出原型,再逐步加工做出成品,这种方式有利于鼓舞士气,因为它使得你随时都可以看到工作的成效。在开发软件的时候,我有一条规则:任何时候,代码都必须能够运行。如果你正在写的代码一个小时之后就可以看到运行结果,这好比让你看到不远处就是唾手可得的奖励,你因此会受到激励和鼓舞。
    • nice

《知晓我姓名》书摘

d2b5ca33bd970f64a6301fa75ae2eb22 2

Some Notes

这本书读的很艰难,几次都读不下去,放下不看,但过了一会,重新捡起来继续读。值得一读。

书摘

  • 这种犯罪的独特之处在于,行凶者可以暗示受害者体验到了快乐,而人们却连眼睛都不会眨一下。世界上不存在好的刺杀或坏的刺杀,两相情愿的谋杀或非两相情愿的谋杀。但在这种犯罪中,痛苦可以被伪装和混淆为快乐。我去过医院,那是人们的身体生病或受伤时去的地方。但我还是拉下袖子盖住瘀伤,因为我害怕自己不能像一个受伤的人那样得到同样的安慰。
  • 什么时候进行全面预防和管理成了我们的工作?如果有很多年轻女孩在一些房子里受伤,我们是不是应该让房子里的男人有更高的标准,而非训斥这些女孩?为什么人们觉得晕倒比用手指侵犯晕倒的人的行为更应该受到谴责呢?
  • 相信有无瑕的过去或完美受害者这种事。然而,现在我觉得自己被一种不可思议的纯洁标准所高举着,担心达不到这个标准就会成为布罗克强奸我的理由。他的律师会简化和概括我的经历,并给我贴上错误的标签。
  • 我答应他不会在黑暗中独自行走。但即使坐来福车,我也从来没有填写过我的真实地址,司机永远不会知道我住在哪里。安全总是一种幻觉。
  • 当我听她说话时,我明白了:你必须坚持下去,看看你的生活如何展开,因为它很可能会超出你的想象。这不是一个你是否能活下来的问题,而是在你活下来以后,等待你的是什么美好的东西。
  • 审判是对真相的探索。现在,真相并不总是放在一个漂亮的包裹里,上面扎个蝴蝶结。有时候,他们会故意蒙蔽你看清真相的能力
  • 侵犯埋葬了自我。我们忘记了如何以及何时才能获准去占据空间。我们生来就怀疑自己的能力,说话时容易受到贬低。我的陈述已经燃烧,爆发,不屈不挠。但我内心深处有一种恐惧,那就是这条路一定有个尽头,他们会说,你已经得到够多了,从这条路上出去吧。我正等着被重新打回原形,回到那个我觉得属于我的小地方。我在边缘地带长大;在媒体中,亚裔美国人被分配去当配角,顺从、轻声细语的次要角色。我已经习惯了不被人注意,也习惯了永远不被人完全了解。我觉得自己不可能成为主角。我得到的认可越多,就越觉得自己不应该接受这么多的慷慨盛情。然而,人们不断地把我拉上来,直到我收到国家最高层的来信。副总统并没有降低到我的位置,而是把我举起来并感激地鞠躬。
  • 审判揭露了令人恐惧和迷惑的现实,提高了言语的恶毒程度。
  • 我们的目标不应该是侮辱,而应该是引导,去揭露更大的问题,这样我们才能学到一些东西。我想做我自己。所以我使用自己的力量不去向后推,而是控制自己的声音。
  • 社会赋予女性一项几乎不可能完成的任务,即把无害与危险区分开来,预见有些男性可能做某些事的能力。当我们受到攻击、大声呼喊时,特朗普说,我认为你不明白。只是口头上的。你这是反应过度,过度自卫,歇斯底里,粗鲁,放松!!!所以我们无视威胁的言论和警告的信号,为我们的妄想道歉。我们参加派对或会议,以为只是派对或会议。但是当我们被利用了,爬着回来的时候,他们说:“你怎么能这么天真,你没能发现危险,放松了警惕,你以为会发生什么?”特朗普明确表示,游戏是被操纵的,规则在不断变化。你认为什么是侵犯并不重要,因为到最后,由他决定。
  • 他的证词中,我听到了一种熟悉的期待:一个受害者必须是完美的才有资格活下去。
  • 我的观点可以用布罗克写的一句话来总结:“我只是生活在一个没有任何事情会出错或者没有人会认为我会犯错的现实中。”肤色浅的人享有特权,这让他坚信后果并不适用于自己。
  • 拉姆·达斯曾说过:“请允许自己此刻并没有生活在错误的地方。考虑游戏中没有出现错误的可能性。只是考虑一下。考虑到并没有出现错误,你盘子里的所有东西就是这样的,而我们在这里。”我不相信被强奸是我的命运。但我的确相信“我们在这里”是我们拥有的一切。有很长一段时间,“在这里”太痛苦了。我的头脑倾向于游离。我曾经以为目标是要遗忘。
  • 年来,性侵罪行都依赖于我们的沉默。害怕知道我们发声的后果。社会给了我们一千个理由:如果你缺乏证据,如果这件事发生得太久,如果你喝醉了,如果这个人很有权势,如果你将面对反击,如果它威胁到你的安全,那么就不要说话。福特打破了所有的规则。她不受制于那些社会在我们敢于开口之前就告诉我们的任何要求。她完全有理由隐藏起来,但她却直接走进了可以想象的最公开、最动荡、最好斗的环境,因为她只拥有她所需要的一样东西,那就是真相。

《金钱心理学》书摘

d2b5ca33bd970f64a6301fa75ae2eb22 3

第2章 运气与风险

  • 你需要注意,不把某件事的结果100%归于个人的努力和决策
  • 所以,预防失败的诀窍是:做好你的财务规划,使其不至于因为一次糟糕的投资和未能达成的财务目标而全盘崩溃,保证自己能在投资道路上持续前进,一直等到好运降临的那一刻。

第3章 永不知足

  • 知足意味着深知它的反义词——永远难以填满的欲望——会将你推向后悔的境地。
  • 在我看来,这不过是一个明知自己的名誉已经一去不返却还拼命想挽回它的人进行的无力的开脱。名誉是无价的。自由和独立是无价的。家人和朋友是无价的。你希望从某些人处获得的敬爱是无价的。幸福是无价的。要想留住这些,最好的方法是懂得什么时候停止冒险,以免伤害到它们。懂得在应该停止的时候停止。

第4章 复利之谜

  • 但是好的投资并不一定意味着长期回报最高,因为高回报的投资往往是一次性的,很难重复。好的投资是可以持续获得不错的收益并能长期重复的投资——这正是复利开始大显身手的地方。

第5章 致富vs.守富

  • 致富需要的是冒险精神、乐观心态,以及放手一搏的勇气。但守富需要做的却与冒险完全相反。守富需要谦逊和敬畏之心,需要清楚财富来得有多快,去得就有多容易。守富需要节俭,并要承认你获得的财富中一部分源自运气,所以不要指望无限复制过去的成功。
  • 生存至上的理念对财富为什么如此重要?原因有两个。第一个原因显而易见:没有任何收益值得你冒失去一切的风险。第二个原因则是第4章中谈到的看似不符合直觉的复利。只有给财富年复一年的时间去增长,复利的力量才会显现
  • 比起巨大的回报,财富的安全更重要。只要财富安全,你就知道你总能得到最大的回报,因为只要你坚持足够长的时间,复利就会创造奇迹。
  • 规划很重要,但每项规划中最重要的部分是对意外做好预案
  • 在对未来保持乐观的同时时刻提防阻碍你走向美好未来的因素的均衡心态至关重要。

第6章 尾部的胜利

  • 任何规模巨大、利润丰厚、声名远播或影响力深远的事物都源自某个尾事件——从几千甚至几百万个事件中脱颖而出的一个。我们的大部分注意力都集中在这些事物,即尾事件的结果上。而当我们关注的焦点只有尾事件的结果时,我们就很容易低估尾事件本身的稀缺和强大
  • “重要的不是你对了还是错了,”“金融大鳄”乔治·索罗斯(George Soros)曾说,“而是当你对的时候,你能赚到多少,或者当你错的时候,你会损失多少。”你即使有一半的时间都在犯错,到最后依然能赢。

第7章 自由

  • 那些历经世事沧桑的人能给你的忠告是:时间自由是财富能带给你的最大红利。

第9章 财富是你看不见的那些

  • 如果财富是你不去使用的金钱,那么财富又有什么好处呢?好吧,让我告诉你我们为什么要存钱。

第12章 意外!

  • 但是投资并非硬科学。投资从本质上说,是规模巨大的一群人根据有限的信息针对将给他们生活幸福度带来巨大影响的事情做出不完美决策的行为,而这会让最聪明的人也变得紧张、贪婪和疑神疑鬼。
  • 经济学理论的基石是“事物会随时间而改变”的道理,因为市场这只无形之手并不愿意看到太好或太坏的情形持续。投资家比尔·邦纳(Bill Bonner)曾这样描述这位“市场先生”的工作方式:“他穿着一件写有‘资本主义在运行’的T恤,手里则握着一把大锤。”很少有什么能一直存在,而这就意味着我们不能把历史当成预言。
  • 你从意外事件中领悟的真理应该是:每天都在发生意料外的事。我们不该将过去的事件当成未来可能性的指南;面对意外事件,我们应该做的是承认这一点——关于未来会发生什么,我们一无所知。

第13章 容错空间

  • 为错误留出余地的行为的智慧就在于承认不确定性、随机性和概率——“一切未知情况”——的存在
  • “安全边际的目的在于让预测变得不再必要”。

第14章 人是会变的

  • 查理·芒格曾表示,复利的第一条原则是:除非万不得已,永远不要打断这个过程。但当你的生活目标发生了改变时,你与理财相关的计划——比如你的职业规划、投资、消费、财务预算等等——怎么可能不跟着改变呢?不改变很难。

第15章 世上没有免费的午餐

  • 世间万物皆有定价。因此,面对与金钱相关的很多事物,关键是明确它们需要你付出什么,然后判断自己是否愿意为之买单。 问题就在于,很多事物的价格并不摆在明面上,你只有在亲身体验后才会知道是多少,但到了那时,一切为时已晚。
  • 投资成功需要付出的代价是我们无法立刻看到的。它不会被直观地写在标签上。所以,当你需要支付这种账单时,你会觉得这笔钱并不是为购买好东西而支付的价钱,反倒更像做错事后必须缴纳的罚款。虽然在人们看来,付账是很正常的事,缴纳罚款却是应该避免的,所以人们觉得应该采取某些明智的预防措施,让自己避免受罚。无论是来自交警还是国税局的罚款都意味着你做错了事,应该受到惩罚,因此对那些看到自己财富减少就认为是交了罚款的人来说,去逃避未来可能产生的罚款不过是一种自然反应罢了。
  • 把市场波动看作要支付的价钱而不是该缴纳的罚款的视角看似微不足道,却是培养正确理财心态的重要部分。这种心态可以让你坚持一项理财策略足够久,最终获得长期的投资收益。

第16章 每个人的情况不同

  • 金融领域内的一条铁律是:金钱会追逐回报的最大化。如果一种金融资产的续航能力优秀——它已经持续上涨一段时间了——那么短线投资者们认为这种趋势会持续的想法并没有什么不妥。它当然不会永远涨下去,但只要在他们需要的时间段持续上涨就可以了。而这种向上的动量以一种合乎情理的方式吸引着短线投资者入场。
  • 泡沫之所以会形成,并不是因为人们在非理性地参与长期投资,而是因为人们在某种程度上堪称理性地转向短线交易,以追逐不断滚雪球式增长的积极动量。
  • 我们应该从这里学到的一点是:在理财方面,很少有什么事比明确自己的投资目标且不受他人活动和行为的影响更重要。

第17章 悲观主义的诱惑

  • 对绝大多数人来说,保持乐观都是最好的选择,因为这个世界在大多时候对大多数人来说都是越变越好的。
  • 无论你是否感兴趣,有两个话题都会影响你的生活:金钱与健康。健康问题往往属于个人,而金钱问题则更具有系统性。在一个密切互联的系统中,一个人的决定往往会影响到其他所有人。于是,我们不难理解为什么金融风险获得的关注度和讨论度是其他话题难望项背的了。
  • 悲观主义者在推测未来趋势时经常没有将市场会如何适应局势纳入考虑。
  • 进步发生得太慢,让人难以发觉,但挫折却出现得太快,让人难以忽视。
  • 增长是由复利驱动的,而复利通常需要时间。毁灭却可能由独立的致命因素导致,可以在很短的时间内发生;它也可能由失去信心引发,而信心可以在一瞬间崩塌。
  • 表达悲观论调的文章更容易写作,因为其内容往往更有新意,且只需要关注最近发生的事件。乐观的叙述则需要回顾漫长的历史和事物发展的进程,而人们总会忘记这些事,并需要花很大的力气才能将分散的事实联系起来。
  • 如果你的期待值过高,那么当前条件下最好的结果在你看来也是平淡无奇的。悲观主义降低了对事物的期待值,缩小了可能出现的结果和你期待的最好结果之间的差距。

第18章 当你相信一切的时候

  • 这些做法看上去很疯狂,但如果你迫切需要解决问题,而你又不知道或者无法轻易找到有效的办法,此时对你来说阻力最小的做法便是像哈贾吉那样——什么都愿意试一试。你不只愿意尝试,而且会全盘相信。
  • 金融领域内的很多投资观点都带有这样的特性:一旦你听从它们,选择了某种策略或方法,你就同时在金钱和心理上进行了双重投资。
  • 一边是你希望获得的,另一边是你为实现一个可接受的结果而实际需要获得的。二者相差越大,你就越不容易轻信那些吸引人的投资故事。
  • 激励是一种强大的动力。我们应该永远记住它是如何影响我们的理财目标和预期的。这句话永远有它的道理:在金融领域,容错空间是一种最重要的力量,而且风险越高,容错空间就应该越大。
  • 理财最重要的事》(The Behavioral Gap)的作者卡尔·理查兹(Carl Richards)写道:“风险就是在你觉得自己已经考虑周全时被你遗漏的东西。”
  • 卡尼曼曾经列举过故事让我们对现实产生误解的情况: ● 在做计划的时候,我们会专注于我们想做的和能做的事情,而忽略了他人的计划和能力,但他人的决策也会对结果产生影响。 ● 无论是在解释过去还是预测未来时,我们都专注于技能起到的因果性作用,而忽略了运气的重要影响。 ● 我们专注于我们知道的,忽视了我们不知道的,而这让我们对自己的想法过于自信。

第19章 总结

  • 事情并没有这样简单。医疗是一个复杂的行业,医患间的互动同样是一种复杂的过程。
  • 当事态朝正确的方向发展时,要保持谦逊;当事态朝错误的方向发展时,要心怀谅解或同情。这是因为任何事都没有表面看来那样美好或糟糕。世界很大,也很复杂。运气和风险真实存在,也难以判别,所以无论是在评价自己还是他人时,都要将这句话牢记于心。你如果能尊重运气和风险的力量,就更容易把注意力投放在你真正能控制的事上,也就更容易找到正确的参照对象。
  • 虚荣越少,财富越多。你能存下多少钱,要看你彰显自我的需求与你的收入之间的差距,而财富恰恰存在于看不到的地方。因此可以说,通过缩减你今天可以购买的东西,你创造了未来可以购买更多东西或拥有更多选择的机会,而财富就是这样积累下来的。无论你的收入有多高,如果无法限制自己当下花钱享乐的欲望,你就永远无法积累财富。
  • 用能让你睡踏实的方式来理财。这并不等同于力求最高的投资回报率或将一定比例的收入存进银行。有些人只有在获得最高的回报率后才睡得踏实,而另一些人只有在保守投资的情况下才睡得安稳。每个人都有自己的偏好,但自问“这样做能让我晚上睡踏实吗?”,其答案可以成为对财务决策是否适合自己的通用判断标准。
  • 如果你想提高投资回报,最简单而有效的方法就是拉长时间。时间是投资中最强大的力量。它能让微不足道的事物成长壮大,而让重大错误的影响渐渐消失。它不能抵消运气和风险,但它会让结果对参与者而言更公平。
  • 就算很多事出了错,也不要心态失衡。你就算错了一半,依然能积累财富,因为是少数的几件事决定了整体的结果。无论你在以什么方式理财,无论有多少事物不如预期,都没有什么大不了的。这个世界就是这样的。所以,你应该始终通过衡量自己的整体投资情况,而不是根据某一笔投资的成败来评价自己的表现。同时有一大笔糟糕的和几笔出色的投资是完全可以接受的,甚至在大部分情况下是最好的局面。通过个别投资来判断整体表现,会夸大赢家的聪明才智,也会对输家过分苛责。
  • 利用财富来获取对时间的掌控,因为对人生的幸福感而言,最严重而普遍的扣分项就是时间上的不自由。在任何时候和喜欢的人去做喜欢的事而且想做多久就做多久的能力,才是财富能带给你的最大红利。
  • 多一些善意,少一些奢侈。其他人都不会像你自己那样在意你有多少财富。你或许以为自己需要的是一辆豪车或一块名表,但或许你真正想要的是来自别人的尊重和赞赏。比起依靠豪车和名表,你可能更容易通过善良和谦逊获得这些。
  • 存钱。存就是了。存钱不需要什么特定理由。为了车、首付或突发疾病存钱自然是好事,但为那些无法预测或定义的事物也是存钱的最佳理由之一。每个人的生命都是由一连串意外组成的。在生命中最糟糕的时刻,没有特定用途的丰厚储蓄可以为不可避免的意外提供一种对冲。
  • 明确成功需要付出的代价。然后做好支付的准备,因为没有什么有价值的东西是免费的。记住,理财中要付出的大部分成本是没有标价的。不确定性、疑虑和后悔是金融世界里的常见代价。它们通常是值得你去买单的,但你要把它们看作一笔费用(要为得到好东西而付出的),而不是罚款(要千方百计避免的)。
  • 重视容错空间。在将来可能发生的事情和你为了表现良好而需要满足的条件之间有一段距离。正是它给了你韧性,让复利得以在时间的长河中创造奇迹。容错空间通常看起来像一种保守的防御措施,但如果它能让你继续留在游戏场上,它就能无数次为你的错误买单。
  • 避免设定极端的财务目标。每个人的目标和愿望都会随着时间的推移而改变。随着个人的成长和提升,你过去的决定越极端,你就越容易感到后悔。
  • 你应该喜欢风险,因为长期看它能带给你回报。但你需要对具有毁灭性的风险格外敏感,因为它会让你早早退场,不再有机会去冒那些能带给你回报的风险。
  • 明确你所玩的游戏的性质。确保你的行动不会受到不同游戏的玩家的影响。
  • 尊重每一个人。在金融投资领域,聪明、有见识、有想法的人们可能出现意见分歧。因为不同人的目标和愿望是截然不同的,所以并不存在统一的正确答案。适合自己的就是最好的。

第20章 我的理财方案

  • 别人建议你做的事和他们自己的做法不同并不一定是坏事。这种现象只是说明,在处理涉及各种感情因素并会影响你自身和家庭的复杂问题时,并不存在一个标准答案。
  • 主要的秘诀是控制你的欲望,在能力范围内尽可能节俭地生活。自主性与你的收入水平无关,而是由你的储蓄率决定的。而当你的收入超过一定水平后,你的储蓄率是通过控制自己对生活方式的欲望决定的。
  • 如果说我的家庭理财计划中有哪一部分是我引以为傲的,那便是我们在年轻时就已经决定,我们对生活方式的欲望不会随着收入水涨船高。我们的储蓄率相当高,但我们很少觉得这种节俭是靠压制欲望实现的,因为我们对物质的欲望并没有随之升高多少。这并不是说我们没有欲望。我们也喜欢美好的事物和舒适的生活。我们只是不会让生活目标无限制膨胀罢了。
  • 自主是我们的最高目标。维持一种低于经济能力的生活方式的附加好处是,这会防止你产生攀比心理。在你负担得起的范围内舒适地生活,不产生过多欲望,你会避免现代西方世界中许多人要承受的巨大社会压力。
  • 纳西姆·塔勒布解释道:“退出无谓的激烈竞争,以获得内心平静为目标来调节你的行为,才是真正的成功。”我很喜欢这句话
  • 查理·芒格说:“复利的第一条原则是:除非万不得已,永远不要打断这个过程。

聊聊丽江

brown wooden house on top of mountain during daytime

今年的 6 月份, 我去了趟云南,此次去,我去了昆明、大理、丽江,泸沽湖,接下来我会依次把这几个地方都写一写。

关于丽江

我知道丽江,还是从酒吧、大冰、丽江手鼓《小宝贝》来的。酒吧和围绕着酒吧的丽江艳遇之都,丽江之名,在我的印象中不算特别好。而大冰,虽然我并不看,但堂弟的书架上常有大冰的书,也算是一个网红作者了。小宝贝则不用多说,在那段时间里,这首歌曲被疯狂翻唱,整体曲调好听轻快。

这是在没有去丽江之前,我心中的丽江印象。

丽江初印象

我是坐火车从大理到丽江的,遗憾的是忘了提前预约旅游专列 Y761 ,只是坐了普通的高铁到的,略显无聊。高铁上的体验远不如开车,而时间上也相差无几。下次,如果预约不上 Y761,我可能会选择直接从大理开车到丽江。

丽江站距离丽江古城有不远的距离,我从火车上下来,坐了半个小时的出租车,才到丽江古城边上。

d2b5ca33bd970f64a6301fa75ae2eb22 5
丽江古城北一角,我住的酒店就在这里

这里值得一提的是,丽江其实不止一座古城,我们一般意义上的「丽江古城」,其实是大研古城,而在丽江市北边,还有一个「束河古镇」,也是一座古城。

d2b5ca33bd970f64a6301fa75ae2eb22 6
丽江火车站到丽江古城的距离

古城周边,生活不便

第一次来,我选择了住在古城周边,主要考虑的还是方便浏览,且这次在丽江我没有租车,所以出行也没那么方便。

然鹅,这个决定是错误的,也是让我后续绝不住古城周边的原因。

我住的位置在大理古城附近的东岳巷,这里有不少的客栈、旅店,因为从巷子口走出去,对面就是丽江古城,所以从旅游的视角来看非常方便。但另一面是,玉缘路、金虹路并不是一个很宽敞的路,经常你出门的时候发现,这条路上堵了非常多的车,导致你在这里打车出行的体验极差。

另一方面,丽江古城里大量的商业店铺,导致这里其实晚上是略显吵闹的。我住在丽江古城外,噪音尚可。而那些丽江古城内的旅店,想想噪音怕是让你需要戴上耳塞睡觉的程度了。

d2b5ca33bd970f64a6301fa75ae2eb22 7

商业化严重的丽江古城

丽江古城给我的感觉便是,一个商业化及其严重的古城。大部分人来就是来体验一下「古城风情」,但你到了以后,可能大部分时候看到的要么是各种各样的商店, 要么是酒吧一条街的唱歌跳舞。

说好的风土人情,已经消失不见,取而代之的,是千篇一律的纳西族妆造和拍照的小姐姐。

不能免俗,我也去了丽江的小酒馆。从众多的酒吧中,找到了一个比较安静的,可以坐下来静静听民谣的酒吧。支付了人均 60 的位费,就开始听歌手唱歌。

d2b5ca33bd970f64a6301fa75ae2eb22 8
我们去的青鸟小酒馆

我去的时候,歌手已经唱了很久,于是唱了不多几首,便离开了,想着可能是去休息了,也可能是到下一个酒吧继续唱歌。

在小酒馆唱歌的歌手
thbsa8
招待完客人的老板娘,也上来唱了两首

除了酒吧,似乎没有什么值得我在夜晚在丽江古城继续逛逛的理由,于是便很早就离开古城,回去休息了。

第二天,我去了朋友介绍的唠叨坊,来尝尝特色的带皮黑山羊火锅。之前吃的比较多的是简阳羊汤火锅,这次试试云南的带皮羊肉火锅。

z8a8ln
d2b5ca33bd970f64a6301fa75ae2eb22 11

黑山羊火锅除了有点咸,别的倒是不错,独特的风味和造型,让我略微有点感受到风土人情的错觉。当然,实惠的价格令人满意,唠叨坊是自助式火锅,所以你可以大量的吃青菜(补一补旅行吃不到青菜的问题)。

4g0v7u

除了火锅,便是常规的在丽江古城找一处风景还不错的角落,拍拍照片,仅此而已。

丽江古城两天有点多,一天刚刚好

我这次给几个城市大体上都安排了 2 天的行程,在丽江的时候,是我感受到自己的时间有点多的场景。当然,也可能是因为我大部分时间是在古城里待着的原因。如果是自己开车的话,去趟束河古镇、拉市海,想来也是不错的。

如果你的行程中包含丽江,且只有一天,那么丽江古城刚刚好。如果你要安排更长的时间,可能就要考虑一下增加一些内容了。丽江古城虽好,但一天足矣。早上去拍拍照,中午吃个便宜坊,下午逛逛古城,撸撸猫,晚上到酒吧坐坐,古城至此便足够。

你支持 LGBTIQA+ 么?

group of people under garment

朋友问我:“你支持LGBTIQA+么?”

我的答案是,我不会反对。


对我来说,我始终能够感受到“有毒的男子气概”,也支持平权。但具体到某一个名词、一件事上,决策又不是那么的简单。

比如,LGBTIQA+ 对我来说,并没有什么特别的(就像美国某一个 KFC 换了一个接线员一样,对我来说可能毫无变化,当然,从蝴蝶效应的视角来看,依然有影响,但我有限的认知里,可能对我来说毫无影响),所以我既可以支持,也可以中立。

但如果落实到身边的朋友,我会选择支持。理由也很简单,既然对我来说,支持和中立一样,那我为什么不选择让朋友更开心的“支持”呢?

云南之旅支出分析

black Android smartphone

云南之旅的支出总体分析也做完了,接下来聊一下本次的支出。

支出明细参考 Airtable

总支出

本次旅行 6 月 17 号开始,6 月 25 日结束,共计 9 天。总支出 15309 元,日均开支 1701 元,日人均开支 850 元。

支出结构

对所有的支出条目进行梳理后,我发现不出意外的,在支出最大头的是出行相关。

d2b5ca33bd970f64a6301fa75ae2eb22 17

而在出行相关中,成本最高的是机票,其次是一嗨租车。一嗨租车因为实际上是我租了多天,所以单日成本可控。

d2b5ca33bd970f64a6301fa75ae2eb22 18

除了行之外,成本比较低的是住,可以看到,我在住上面花费了非常少的成本,主要的原因还是因为我去的时候云南还是属于淡季,所以整体的开销还好。

在游玩和景点方面,整体花费的不算特别多,成本大头的是伴手礼和旅拍的照片,其他的景点其实就还好。再加上我们俩基本上也没怎么去特别贵的景点,也就开销一般啦~

d2b5ca33bd970f64a6301fa75ae2eb22 28

吃的方面,这次来云南吃了不少当地的美食,所以开支比较大,符合预期(当然,比重还是有点收到惊吓),但总体还在可接受范围内。

d2b5ca33bd970f64a6301fa75ae2eb22 29

总结

旅游真的烧钱。。。不过穷家富路,出门了就别太在乎钱,不然还不如不出门。下次还去!

不过下次我可能会优化一下我的一些选择,比如租车可能会选择携程租电车 + 保险,来节约一些交通的开支。

给 mdbook 增加备案号显示

rustlang

由于 Gitbook 长期不维护,为了保障整个架构持续可用,所以导致我不得不从 Gitbook 迁移到 mdbook。

在使用 mdbook 的时候,有个问题是,我的不少电子书域名都是备案过后的,mdbook 又不像 gitbook 支持可以在目录里跳转外链,因此我需要自己实现给 mdbook 添加一个外链。

实现思路

由于没办法直接通过在 Markdown 当中实现跳转外链,那么一个比较简单粗暴的方法就是直接在模板当中添加,刚好 mdbook 在文档中有说明具体的操作方法

你只需要在 mdbook 的根目录中创建一个 theme 文件夹,并生成一个 index.hbs 文件,用于渲染页面。

接下来,你只需要在适当的位置添加上你需要的代码即可(下方的 toc 后面的 有序列表便是我手动添加的)

   <nav id="sidebar" class="sidebar" aria-label="Table of contents">
            <div class="sidebar-scrollbox">
                {{#toc}}{{/toc}}

                 <ol class="chapter">
                    <li class="chapter-item expanded "><a href="https://beian.miit.gov.cn/" target="_blank">这里是你的备案号</a></li>
                </ol>

            </div>
            <div id="sidebar-resize-handle" class="sidebar-resize-handle"></div>

        </nav>
Code language: HTML, XML (xml)

参考文档

https://github.com/rust-lang/mdBook/issues/1354

淄博之旅

d2b5ca33bd970f64a6301fa75ae2eb22 23

我去淄博其实是两个月之前了,由于拖延症,一直没写,于是我想,如果我再不写,可能我再也不会写了吧。OK,那就开始动手写吧!

缘由

我去淄博是在 5 月初,彼时我刚提车,于是便决定开车从天津前往淄博,一方面是练练车,另一方面刚好最近淄博火热,也去看看令人好奇的淄博烧烤。

人文景点

八大局

淄博作为一个以烧烤、烟火气火起来的城市,既然来,自然重点是看大家的生活,所以,到淄博的第一站,自然是少不了到八大局溜达溜达

d2b5ca33bd970f64a6301fa75ae2eb22 19

不过,当我去的时候,八大局已经在网络上火了很久,所以现场的人非常多。八大局也逐渐有了网红街的感觉了,比如紫米饼,已经被叫”网红紫米饼“了。

d2b5ca33bd970f64a6301fa75ae2eb22 20

考虑到排队正版的紫米饼时间太长,讨厌排队的我最终选择了一家非正版的紫米饼,试了试,味道还行。可能正版会更好吃,但排队实在太讨厌了…

d2b5ca33bd970f64a6301fa75ae2eb22 21

齐盛湖公园

从八大局出来,我们便开车去酒店休息,到了晚上,来到了淄博张店区的齐盛湖公园,据说这里有一个「海岱楼书店」,是曾经的最美书店,于是也跑来打卡,看看这个最美书店。

从外景来看,楼宇与湖光一起,远处还有山光,雀实不错。

pjp1az

走到近处,颜值也还算是能打

j0lopk

进入到里面后,内里的设计不像外部那么的古朴,反倒是还挺现代化的。但这个设计,挺讨喜的。

you7ru

作为一个最美书店,还是值得打卡的。

自然景观

潭溪山

由于安排了比较长的时间来淄博玩,所以我们除了逛一逛人文景观,还去了淄博的潭溪山景区,看看淄博的自然风光。

潭溪山的风光整体来说,还不错,与云南、西藏没办法比,但依然算得上清秀。

gfbh9l

潭溪山的话,我自己最喜欢的应该是这个透明栈道了。作为一个有恐高症的人,走这个透明栈道属实是胆战心惊,但,还是要走!

d2b5ca33bd970f64a6301fa75ae2eb22 27

旅行建议

淄博市是一个纵向偏长,横向较窄的城市布局,而我们在抖音上看到的八大局、烧烤一般都是在中间的张店区,而如果你只玩了张店区,你就错过了淄博的更多内容,淄博的临淄区、周村区、淄川区、博山区也有各自的特色和风格,如果你来了,我建议你除了在张店玩一玩,还要留有更多时间去看看更多不一样的淄博。

淄博市行政区划图

店铺推荐

在淄博的时候,我们吃了不少的烧烤,我最推荐的是淄川区的程大牛肉,这家店是牛肉烧烤专卖店。

一句话来描述的话,在我看来,程大牛肉是在用潮汕牛肉的思想做烧烤,这家和别家不一样,他是按部位卖牛肉烧烤的!你可以吃不同位置的牛肉做成的牛肉串!

推荐去试试看!不过,需要注意的是,他们家是预约制度的,所以你最好提前打电话联系一下,预约一个位置,以确保自己有位置。

总结

这次第一次来,我们只是简单玩了玩,对于淄博有一个更不一样的认识,而更加细致的内容,依然需要进一步的来淄博看看,体验一下淄博更细节的内涵,还要再去的!

APILetter S1E5 如何设计一个符合 RESTFul 风格的批量操作的 OpenAPI 接口?

APILetter

批量创建、批量更新、批量删除

批量获取说完了,接下来我们来聊聊批量更新,实际上批量更新、批量创建虽然有场景,但也不多,在这种场景下,我们已经很难像批量获取那样,在原有资源上进行操作,而是需要借助批量资源来实现批量操作。

以用户资源(User)为例,当我们需要对其进行批量创建、删除、更新时,我们需要创建一个批量资源 BulkUser,并通过对 BulkUser 操作,来创建用户。Bulk User 本质上是将请求的多个资源转换为了异步的任务,在发起后,开发者可以在任务结果中查询具体的值来使用。

如何理解异步的任务?
这里异步的任务更多是一种设计表现,并不强制要求一定异步。异步的表现设计和相关的接口实现,是为了给后续留出纵向扩展的空间。既 无论是否行为是否真实异步,都需要在返回结果中返回任务 ID & 任务状态,以便于开发者自行实现异步处理的逻辑。

{
    "code":0,
    "data":{
       "job":{          "id":"123",          "status":"ok"        },
        "results":[
            {
            ...
            }
        ]
    }
}
Code language: JavaScript (javascript)

批量创建

批量创建用户的操作和创建单个用户的操作是比较接近的,主要差异点在于 Path 上有区别,且传递参数时,会传递多个资源的属性。

批量创建用户

# request
POST /bulk_users/

{
    "users":[
        {
            // user1
            ...
        },
        {
            // user2
            ...
        }
    ]
}
# response
HTTP/1.1 200 OK
{
    "code":0,
    "data":[
       {
            // user1
            ...
        },
        {
            // user2
            ...
        }
    ]
}
Code language: PHP (php)

批量更新用户

批量更新时,你已经知道了你需要更新的资源的 ID,因此,可以这样设计的你的接口:

#request
PUT /bulk_users?id[]=1&id[]=2

{
    "gender":"other"
}

# response
HTTP/1.1 204 No Content
{
 "code":0,
    "data":[
       {
            // id=1
            ...
        },
        {
            // id=2
            ...
        }
    ]
}
Code language: PHP (php)

批量删除

有了上面的几个例子,批量删除就比较好定义了。就像这样:

#request
DELETE /bulk_users?id[]=1&id[]=2

# response
HTTP/1.1 200 OK
{
 "code":0,
    "data":[
       {
            // id=1
           "status":"deleted"
        },
        {
            // id=2
            "status":"deleted"
        }
    ]
}
Code language: PHP (php)

总结

批量操作在获取场景,可以考虑通过 List + Filter 的方式,或搜索的方式来实现一套更加标准的搜索接口,而规避提供定制化的自定义接口。从规范的视角,两者都是符合规范的,也可以都对用户提供,并不互斥。而对于没办法复用的创建、更新、删除,则可以考虑使用创建异步任务的方式,来实现批量操作,给开发者一个明确的异步预期,让开发者可以自行查询业务的实现方式。

云南之旅流水账

d2b5ca33bd970f64a6301fa75ae2eb22

云南之旅玩的非常的尽兴,6.17 ~ 6.25 ,全程共计 9 天,玩了昆明、大理、丽江、泸沽湖四个不同的地方,几乎每个地方待了 2 天左右,还是有非常多值得去和值得纪念的东西。不过,由于实在太多了,所以只能用流水账的方式来记录。在流水帐当中,着重说一些大面上的事情,而具体每个地方的更加详细的描述,则通过单独为每一个地方写一篇文章来说。

不过,为了方便你了解我的行程(抄作业),我在 Google Map 上准备了一份地图,方便你了解我去过的地方。如果你感兴趣的话,可以点击这个链接,看到我去的每一个地方,以及相应的评价。

行程总览(Overview)

日期地点描述
6.17天津,昆明,遵义天津飞昆明,遵义茅台机场中转; 落地后入住酒店,在昆明逛了南强街和南屏步行街
6.18昆明,大理早上去滇池,下午从昆明站出发前往大理,到大理后取车前往酒店入住后去大理古城.
6.19大理环洱海,期间去了喜洲古镇、大理圣托里尼
6.20大理,丽江逛崇圣寺三塔、坐感统索道上苍山,晚上还车并从大理坐车前往丽江,晚上住在丽江古城附近。
6.21丽江逛丽江古城、拍照、吃纳西族黑山羊火锅。
6.22丽江,泸沽湖吃过桥米线,从丽江出发去泸沽湖,晚上吃摩梭族烤鱼。
6.23泸沽湖,大理环泸沽湖,吃摩梭族烤鸡,下午开车回大理,并在大理古城拍照
6.24大理,昆明早上在大理吃过早餐,就开车出发去昆明,下午入住斗南花市旁的全季酒店,晚上逛斗南花市。
6.25昆明上午逛云南省博物馆,下午在翠湖公园溜达后,前往昆明长水国际机场。
9 天旅途的 Overview

感受

1. 云南的气候宜人

云南的气候是这次我体会最为深刻的。我在云南旅行的时候,恰逢天津正是高温的时刻,相比之下,云南的最高温不过 30 度简直是太过凉爽。

不过,虽然最高温不过 30 度,但在中午时刻,依然是比较热的,只是没有像北方是“烤”的感觉。而云南的湿度也不高,也不会有广东的“蒸”的感觉。

从气候上来讲,我觉得云南是比海南广东(太蒸),华北平原(太烤)要更好的。太宜居了。

d2b5ca33bd970f64a6301fa75ae2eb22 1
旅行期间天津的天气, 来源 2345
d2b5ca33bd970f64a6301fa75ae2eb22 2
旅行期间昆明的天气,来源 2345

不过,美中不足的是云南的紫外线强度也是太强了。云南 9 天,基本上每天都会喷安耐晒,整个旅程下来,我的小臂/脸上还是黑了一个色号。再去云南,我觉得我可能会直接选择穿防晒衣,物理防晒,最为靠谱。

2. 云南的风景美如画

云南的风光对我来说,可以比肩 19 年在西藏出差时的西藏风景。

蓝天、白云、青草地,还有洱海、泸沽湖这样的水,非常的舒服了。下面贴几张图,让大家感受一下(以下照片均出自原相机,无滤镜,但拍摄设备有 iPhone 13 和 Pixel 6):

d2b5ca33bd970f64a6301fa75ae2eb22 3
从昆明机场到塘子巷时地铁上拍的天和飞机
d2b5ca33bd970f64a6301fa75ae2eb22 4
昆明机场廊桥上拍的天空和机场
d2b5ca33bd970f64a6301fa75ae2eb22 5
滇池风景
d2b5ca33bd970f64a6301fa75ae2eb22 6
滇池水上风景
d2b5ca33bd970f64a6301fa75ae2eb22 7
洱海边拍的苍山
d2b5ca33bd970f64a6301fa75ae2eb22 8
洱海边
d2b5ca33bd970f64a6301fa75ae2eb22 9
泸沽湖夜景(晚上八点左右)
d2b5ca33bd970f64a6301fa75ae2eb22 10
泸沽湖草海
d2b5ca33bd970f64a6301fa75ae2eb22 11
泸沽湖俯瞰
d2b5ca33bd970f64a6301fa75ae2eb22 12
泸沽湖里格半岛

如此美景,我最大的感受就是,悔不该当初,我就应该带上相机来的!这次出行为了方便,我只带了拍立得和手机,所以拍不出我所看到的美景,再来我要带上我的6400、广角镜、长焦镜,把这些美景都拍下来!

3. 云南的美食很特别

这次去云南,赶上雨季推迟,所以没能吃当地的野生菌(我很想试试见手青,据说是云南的顶尖美味)。但也还是吃到了一些好吃的/ 特别的。

比如:在喜洲古镇吃到了炸蝎子🦂。

d2b5ca33bd970f64a6301fa75ae2eb22 13

比如,云南的粑粑,感觉就是各种不同的馅饼。

d2b5ca33bd970f64a6301fa75ae2eb22 14

也吃到了云南必吃的鲜花饼,现烤的是真的太好吃了。

d2b5ca33bd970f64a6301fa75ae2eb22 15

傣族风情手抓饭也少不了

d2b5ca33bd970f64a6301fa75ae2eb22 16

总结

云南这次的旅行给我的感受还是很深刻的,先简单总结三点。更细节的,后面一篇篇来。

可以肯定的是,云南,我还会再去的。

被滥用的云南十八怪

d2b5ca33bd970f64a6301fa75ae2eb22 34

这次去云南,看到了各种各样奇奇怪怪的“云南十八怪”,让我不得不来吐槽一把。

在没去云南之前,我就知道云南有个“云南十八怪”,在解释云南各种和中原地区差异比较大的生活习惯,但说实话,一直没怎么了解过具体的细节,因为不熟悉。

根据百度百科,云南十八怪是这样的:

你说奇怪不奇怪,云南就有十八怪。
四个竹鼠一麻袋,蚕豆花生数着卖;
袖珍小马多能耐,背着娃娃再恋爱;
四季衣服同穿戴,常年能出好瓜菜;
摘下草帽当锅盖,三个蚊子一盘菜;
石头长在云天外,这边下雨那边晒;
鸡蛋用草串着卖,火车没有汽车快;
小和尚可谈恋爱,有话不说歌舞代;
蚂蚱当作下酒菜,竹筒当作水烟袋;
鲜花四季开不败,脚趾常年露在外。

百度百科

但我在云南当地,见到了各种奇奇怪怪的十八怪,甚至炒酸奶也被编进了十八怪:“酸奶炒着卖”

d2b5ca33bd970f64a6301fa75ae2eb22 33
d2b5ca33bd970f64a6301fa75ae2eb22 34
d2b5ca33bd970f64a6301fa75ae2eb22 35

在 Render.com 上部署 Django 4.2

person holding sticky note

最近在写 Linux 中国的翻译工具的时候,后端我使用的是 Django,版本则选择了 Django 4.2,Python 3.11。在部署 Django 的时候,我选择使用 Render.com 来部署。 不过,在部署的时候,我遇到了一些问题,Render 官方提供的 Getting Started with Django on Render 会部署错误,所以有了今天这篇文章, 告诉大家如何把最新的 Django 4.2 部署到 Render 上。

初始化项目

Render 没有使用 pip,而是使用 Poetry 来管理 Django 项目的,因此,你需要使用 Poetry 来完成项目的初始化。

poetry init #初始化 Poetry 的 配置文件
poetry add django gunicorn # 添加依赖 Django 和 gunicorn
poetry run django-admin startproject linuxondjango .
Code language: PHP (php)

初始化项目基本上就是用 Poetry 替代 pip ,这里没有需要针对 Render 特化的部分,就不做过多的介绍。

编写逻辑代码

当你完成了项目的初始化之后,可以编写你自己的业务逻辑代码,这部分不再多讲,可以正常开发使用。

配置项目以支持 Render 的服务端环境。

1. 从环境变量中读取 Secret Key

Django 使用 Secret Key 作为 Session 加密等一些加密场景的 Salt 和 Seed,所以在 Django Admin 创建项目时,会默认生成一个 Session。不过出于安全考虑,最好不要将其放在代码中,而是在服务端生成后,通过环境变量来存储,避免代码泄露后导致的 session 被解密。

你需要在 settings.py 中,添加如下代码,来替代默认的 key。

import os
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = os.environ.get('SECRET_KEY', default='your secret key')
Code language: PHP (php)

2. 在环境变量中读取 Debug 配置

Render 会自动配置一些环境变量,因此,你可以直接通过判断当前环境上下文来确认当前是否是在 Render 的服务端,如果不在,则配置 Debug 为 True,来解决线上不使用 Debug 模式的需求。

DEBUG = 'RENDER' not in os.environ
Code language: JavaScript (javascript)

3. 从环境变量中读取可用域名

Django 是有域名配置的,非配置域名,无法访问当前应用,因此,你需要在 Render 当中读取域名,来确保可以正常访问。当然,如果你自己配置了自己的域名,也可以直接手动写在 ALLOWED_HOSTS 当中。

ALLOWED_HOSTS = []

RENDER_EXTERNAL_HOSTNAME = os.environ.get("RENDER_EXTERNAL_HOSTNAME")
if RENDER_EXTERNAL_HOSTNAME:
    ALLOWED_HOSTS.append(RENDER_EXTERNAL_HOSTNAME)

Code language: JavaScript (javascript)

配置 render.yml 来支持 Render BluePrint

你可以直接复制下面的内容,来作为你的项目的启动配置。其中 build.sh 为构建项目的配置。

build.sh

build.sh 当中最重要的是重新安装 Poetry,因为我使用的是 Python 3.11.4, 和 Render 默认的 Python 3.7 不匹配,所以没办法直接用默认的 Poetry,需要自动手动升级 Poetry。

#!/usr/bin/env bash
# exit on error
set -o errexit

pip install --upgrade pip; pip install poetry;  # 重新安装一下最新的 Poetry,因为默认的 Poetry 的版本比较低。
poetry install

python manage.py collectstatic --no-input
python manage.py migrate
Code language: PHP (php)

render.yml

Render 当中,最重要的是 startCommandPYTHON_VERSION ,startCommand 这里是我使用 gunicorn 来启动 Django 应用,而 PYTHON_VERSION 则是用来设定具体的 Python 版本,这里我根据我自己的需求,选择了 Python 3.11.4。

databases:
  - name: linuxondjango-db
    databaseName: mysite
    user: mysite
    plan: free

services:
  - type: web
    name: linuxondjango
    plan: free
    runtime: python
    buildCommand: "./build.sh"
    startCommand: "gunicorn linuxondjango.wsgi:application"
    envVars:
      - key: DATABASE_URL
        fromDatabase:
          name: linuxondjango-db
          property: connectionString
      - key: SECRET_KEY
        generateValue: true
      - key: WEB_CONCURRENCY
        value: 4
      - key: PYTHON_VERSION # 这里的 python version 是用来指定 Python 版本的,比如这里我用的是 3.11.4。
        value: 3.11.4
Code language: PHP (php)

总结

Render 的教程总体来说没啥大问题,但是在一些小的点上,需要你自己简单 Hack 一下,比如需要自己升级一下 Poetry、设定 Python 版本。如果你也在用高版本的 Django & Render,希望这篇文章 可以帮到你。

如何解决 Kindle 在 M1 系列设备上无法访问的问题

flat screen monitor

问题

在使用 M1 的时候,我遇到一个很麻烦的问题是 M1 无法识别出我的 Kindle系统无法自动加载 M1 设备,这导致习惯于导入标注并使用 Klib 管理的我来说,等于用 Kindle 的功能不齐全了。

使用 macOS 自带的系统工具,也可以看到系统 Kindle 的磁盘,但无法加载。

d2b5ca33bd970f64a6301fa75ae2eb22 29
磁盘工具的展示

如果使用磁盘工具尝试加载,也会报错 com.apple.DiskManagement.disenter错误-119930872

d2b5ca33bd970f64a6301fa75ae2eb22 30
报错的提示

无法使用系统工具加载。

解决方案

在参考了 jakevin 的分享后,我使用如下方式来解决我的 Kindle 挂载问题。

查询外置设备

执行如下命令,可以使用系统自带的 diskutil 查看目前有哪些磁盘。我在这里补充了 grep,来筛选出只有外置磁盘的设备。

diskutil list | grep external -A2
Code language: PHP (php)
d2b5ca33bd970f64a6301fa75ae2eb22 31

手动挂载设备

执行如下命令,来手动挂载 Kindle。

sudo mkdir /Volumes/Kindle # 创建一个新的挂载点,挂载 Kindle
sudo mount -t msdos /dev/disk4 /Volumes/Kindle/ # 使用 mount 命令,挂载 /dev/disk4(你根据需要换成你自己的设备。)
Code language: PHP (php)

一般来说, Kindle 的默认格式化是 fat32 格式,所以用上面的命令就行,但如果你的 Kindle 是 ex-fat 格式,则可以使用如下命令挂载。

sudo /sbin/mount_exfat /dev/disk4 /Volumes/Kindle/ #这里使用的是 mount_exfat。
Code language: PHP (php)

如此操作,便可以让 M1 识别 Kindle 了。

d2b5ca33bd970f64a6301fa75ae2eb22 32

给你的 console.log 添加一些特定的输出

9a1f326b911de6c1629837f3b57551e5 1

在写 Node.js 代码时,常常会使用 console.log 来输出内容,以便于调试。但默认的 console.log 只能标准的输出,在很多需要上下文 debug 的时候,可能信息是不足的。除了使用 debugger 以外,你还可以试着改造 console.log

在你的 index.js 顶部添加如下代码,即可实现在使用 console.log 时自动在前面加上时间信息。当然,你也可以实现自己需要的上下文,比如当前的文件、当前的行数等。

console.log = (function() {
  var console_log = console.log;
  return function() {
    var args = [];
    args.push(`${new Date().toLocaleString()}` + ' -> ');
    for(var i = 0; i < arguments.length; i++) {
      args.push(arguments[i]);
    }
    console_log.apply(console, args);
  };
})();
Code language: JavaScript (javascript)

这个函数的逻辑不复杂,对 console.log 进行了覆盖,写如了新的函数,并通过 arguments 将开发者传入的参数重新打印,以确保不丢失开发者传入的参数。

《哆啦A梦:大雄与天空的理想乡》观后感

d2b5ca33bd970f64a6301fa75ae2eb22 20

我看的动漫不多,哆啦 A 梦、火影、中华小当家。哆啦 A 梦出了大电影,也确实有空,就必然要去看看的。

以下内容包含剧透,如你尚未看此影片且准备去看,建议关掉当前页面,后续看完再回来看本文。

d2b5ca33bd970f64a6301fa75ae2eb22 20

这部电影,如果说让我印象深刻的,大概是以下几点:

回环、价值观

回环

看完整部电影后,我觉得设计最巧妙的便是一开始的蓝色甲虫。在电影的开始,甲虫的出现显得略显无用,似乎也没有在推动剧情的发展。

然而当你看到最后,看到蓝色甲虫竟成了哆啦 A 梦重回人间的锚点,也就不得不感叹这个伏笔有意思,前面蓝色甲虫直奔大雄而去也就有了原因。

挺好。

价值观单一是问题

在普拉多普亚,所有人都是听从三贤人的安排,自然而然,也就要遵循三贤人的价值观。然而,当整个普拉多普亚都是三贤人的价值观的时候,任何违反三贤人的价值观的都成为了错误,甚至要被三贤人的价值观重新洗脑。

如果三贤人真的是贤人,倒也罢了。但三贤人并不是真正意义上的贤人,也不存在绝对意义上的贤人。所以,价值观单一成了问题。

多彩多元的价值观,才能让我们更加开心。

做自己

和上一条接近,如果说,放在自顶向下的角度来看,价值观单一是问题,那么自底向上的便是要做自己,这个自己,是遵从内心的自己,而不是别人告诉你的自己(当然,找到自己的内心是一件很难的事情)。

做自己,才能真正达到完美。如果不是做自己,不过是在和别人眼中的自己做磨合,终究是会磨合的血肉模糊的。

总结

总体来说,可以看,算是合家欢电影,带小朋友去看也没啥问题。不会出现一些奇奇怪怪的事情,影响小朋友的价值观。我这种老朋友,就是去怀念一下自己小时候的哆啦 A 梦罢了。

如何将 Zed 编辑器设置为你的命令行默认编辑器

linux terminal

我最近在使用 Zed 作为我的主要编辑器,在编辑一些命令行文件时,也会使用 Zed 来编辑。但有些时候,一些应用程序的命令会自动调用默认的编辑器,这个时候会默认使用 nano 或者 vim ,而不是 Zed,体验略差。所以我希望将命令行默认的编辑器修改为 Zed 编辑器。

如果需要将 Zed 作为自己的命令行编辑器,首先需要确认 Zed 是否支持等待模式(wait model),在命令行中执行 zed --help,可以看到 Zed 是支持等待模式的。接下来就可以进行后续的步骤来进行测试了。

d2b5ca33bd970f64a6301fa75ae2eb22 3

这里为是在写 Rails 时用到的,因此,我继续使用 rails credentials 来测试。执行如下命令来确认该命令是否可用。

EDITOR="zed --wait" rails credentials:edit
Code language: JavaScript (javascript)

执行后,可以正常唤起,则说明整个链路已经通畅,接下来只需要将其配置在系统的默认环境变量里即可,将如下代码放在 .zshrc 中即可。

export EDITOR="zed --wait"
Code language: JavaScript (javascript)

其他编辑器的命令参考

# Sublime Text
export EDITOR="subl --wait"
# VSCode
export EDITOR="code --wait"
Code language: PHP (php)

天津车检记录

analog watch at 1 00

买车记录里,我说过,我目前开的车是一辆 2017 年的雪铁龙 C3 XR,按照最新的汽车年检的规定,刚好满 6 年,需要进行年检,于是我又快速体验了一次年检。

如何进行年检?

年检有两种方式

  • 一种是前置预约的检查,可以在 12306 上预约(或者使用平安车主的代检服务),这种往往检查的速度比较快,虽然也要排队,但是排队的长度比较短,只有几辆车。
  • 另一种是直接去检测机构检查,就需要根据实际的情况来排队,运气不好的话,排队好几个小时是很正常的。

如果你要预约,直接在 12306 App 上找到【机动车检验预约】,就可以预约车辆的年检了。

d2b5ca33bd970f64a6301fa75ae2eb22 25

在预约时,你需要选择时间和地点,并准备抵达现场进行预约检查。到达预约检测地点的时候,一定要问一下哪里是 12306 预约通道,不要和大量的未预约车辆一起排队!避免你预约了,但走的是常规排队通道,浪费时间。

d2b5ca33bd970f64a6301fa75ae2eb22 26
通道里有个“12306预约检验通道”的标志来提醒

当你进入预约通道以后,会让你进行一个预检查登记,大概像下面这样,

d2b5ca33bd970f64a6301fa75ae2eb22 27

填写完成以后,从后备箱拿出三脚架,放在前挡风玻璃处,开车排队,并将车辆开上检验通道,你的事情就做完了,接下来只需要把钥匙交给工作人员,工作人员会将你的车开上检验通道,进行检查。

d2b5ca33bd970f64a6301fa75ae2eb22 28

此刻你只需要到办事大厅,缴费、拍照、等结果即可。汽车检查的速度很快,基本上我去交完费,等了 5 分钟,就已经完成检验,领钥匙走人了。

一些 Tips

  1. 年检的时候记得带上你的三脚架,检查的时候会用到。当然,更好的方案是把三脚架就放在后备箱里,别拿出来,避免用的时候没有。
  2. 记得提前预约,真的要好很多。
  3. 记得检查你的交强险状态,如果交强险时间较短,有可能会无法入库(但到底多短算短我也不知道),最好是保持2个月以上吧。

总结

汽车年检比我想象的要简单,之前我听别人讲,汽车年检都要耗费一天,甚至是需要找专人代为检查。一方面可能是因为他们的车辆较老,各项基础设施都已经出现故障,有可能因为故障的原因导致无法完成年检。另一方面,也可能是因为习惯了排队,而不是预约,导致车检的耗时比较长,所以也就不愿意自己去年检了。

Feed 订阅调整说明

Read More

本站一直以来,都开放了 Feed 的全文订阅,方便读者阅读,不过由于博客时间较长,文章越来越多,导致 Feed 越来越大,目前已经到达了 1.3 MB

d2b5ca33bd970f64a6301fa75ae2eb22 1

较大的 Feed 文件会导致在进行新读者加载时耗费较多时间,因此,我将 Feed 输出的条目调整为 50 条,内容依旧保持全文开启,以方便使用 Feed 订阅的同学。

d2b5ca33bd970f64a6301fa75ae2eb22 2

调整后,Feed 大小只有 64 KB,加载速度也更快。

如果你希望看到我所有的历史文章,可以直接访问本站的归档页面查看。