2022 Week 43

也可以在竹白上订阅更新

Web Programming

Next.js 13

Next.js 13 的发布应该是近日的大新闻了,比较大的改动是 Make Server Component Default,也就是默认为 Server Component。在之前有两种方式来实现 Server Component 的效果:SSGSSR,前者会在编译期获取动态数据,然后再 Pack 成一个 Component,后者则是在 Runtime 阶段去动态请求数据,然后再返回给前端一个完整的带数据的页面。前者可以被 Deploy 到 CDN 上,后者则要牺牲一点访问速度。

Next.js 13 统一了这二者,不用再声明 getServerPropsgetStaticProps,直接 fetch 即可,如果 fetch 的参数没有 revalidatecache: no-store 则表现为 getStaticProps,有设置 cache: no-store 则表现为 getServerProps,详见文档

同时 Routing 也更换成了新的设计,抛弃了原先的那一套,更加强大。

PS: TurboPack 看上去很快很强大,不过对于中小型 App 区别应该不会很大(相比于 Vite)。

PPS: 新的文档页面很漂亮。

A comprehensive guide to creating intuitive context menus

这篇文章讲了构建一个菜单需要考虑哪些因素,比如动画(二级菜单是否要有动画?),快捷键,点按反馈,显示位置等等。还有很重要的一点是二级菜单的选择体验,因为用户在滑向二级菜单的过程中,有可能会滑过其他一级菜单,此时如果响应了该行为,就有可能与用户的预期不符。文章里提到了苹果的解决方案。

An Interactive Guide to Keyframe Animations

这篇文章通过可交互的 demo 基本把 css 的 @keyframes 的使用姿势讲透彻了。@keyframes 用来定义不同的关键帧对应的 css 属性(如果有用过 Macromedia Flash IDE 应该对此不会陌生),然后结合 css 的 animation* 系列属性,就能实现复杂的动画效果。

<style>
  @keyframes grow-and-shrink {
    0% {
      transform: scale(1);
    }
    50% {
      transform: scale(1.5);
    }
    100% {
      transform: scale(1);
    }
  }

  .box {
    animation: grow-and-shrink 4000ms;
    animation-iteration-count: infinite;
    animation-timing-function: ease-in-out;
  }
</style>

<div class="box"></div>

这个 demo 里定义了一个放大/缩小的关键节点(grow-and-shrink),中间的动画(补间动画)CSS 会自己 figure out。animation 属性表示,当该 element 出现时,不要愣愣地直接出现,而要自带出场效果。其他的 animation-* 就像是 animation function 的参数。

还有很重要的一点是,animation 只是用来实现出场效果,动画做完之后,并不会 keep 最后的状态,而是回到该 element 原先定义好的 style。文中作者举了一个 alpha 变化的例子很好地体现了这点。如果要停留在动画结束时的各个属性,可以设置 animation-fill-mode: forwards

When the animation ends, animation-fill-mode: forwards will copy/paste the declarations in the final block, persisting them forwards in time.

Building an interactive WebGL experience in Next.js

这篇文章讲了 Vercel 的 Ticket 效果是怎么做出来的,主要用到了 react-three-fiberdrei

其中的三棱镜反射效果还有点复杂,用到了一种叫 raymarching 的技术。

The Wrong Abstraction

duplication is far cheaper than the wrong abstraction.

这篇文章的核心观点就是上面那句话:重复好过错误的抽象。文中他推演了需求的演变过程,相信我们多少都会有共鸣。大概过程就是随着需求的迭代,原先的抽象已无法满足需求,然后就会在原先的抽象基础上,不断加新的参数(打补丁),直到最后谁都看不懂这个抽象到底要做啥。

解决方法是,当发现抽象失效时,就放弃这个抽象,根据需求再抽象出一个更小的子集,剩下的代码独立存在于需要的地方(有部分重复)。

CRDT 简介

CRDT (conflict-free replicated data type) 无冲突复制数据类型,是一种可以在网络中的多台计算机上复制的数据结构,副本可以独立和并行地更新,不需要在副本之间进行协调,并保证不会有冲突发生。

CRDT 常被用在协作软件上,例如多个用户需要共同编辑/读取共享的文档、数据库或状态的场景。在数据库软件,文本编辑软件,聊天软件等都可以用到它。

"conflict-free" 听起来很神奇,用过 Git 就知道,conflict 有多容易。那 CRDT 如何实现无冲突的呢?其中有几个要点:

  • 可以被独立并发地更新,而不需要副本之间进行协调(加锁)
  • 多个更新之间不可能发生冲突
  • 总是可以保证最终一致性

「不可能发生冲突」,可以通过强最终一致性来解决,比如都对同一个字做了修改,但其中一个修改发生在离线状态,那么就以最后(时间更靠后)的修改为准。

「可以被独立并发地更新」,可以保存用户的每一个操作(Operation),这些操作就像一条条汇编指令一样,本地软件只要执行这些指令就行了。「协作」就是把其他人的指令也加进来(比如按时间排序)一起执行。

「最终一致性」,只要最后大家同步到了所有的 Operation,就能保证每个人的表现都是一致的。

这篇文章 对该算法在 Rich Text 场景下的使用做了比较详细的描述。Rich Text 处理起来会更加复杂,比如 A 对 The fox jumped. 的前两个字进行了加粗,变成了 **The fox** jumped.,B 对后两个字进行了加粗,变成了 The **fox jumped.**,简单地 Merge 的话,就变成了 **The **fox** jumped.**,结果 for 没有被加粗。文中的处理方法是将操作语意化,比如加粗动作可以描述为:

{
  action: "addMark",
  opId: "[email protected]",
  start: { type: "before", opId: "[email protected]" },
  end:   { type: "before", opId: "[email protected]" },
  markType: "bold"
}

这里的 opId 格式为 [email protected]nodeId 就是一台设备/进程,对应每一个操作者。

代码写得不好,不要总觉得是自己抽象得不好

复杂度的来源是需求,如果需求不合理,就很难得到合理的抽象和代码,那么就要和产品经理谈判。我在想有没有什么模型既可以正确反应当前代码的架构、依赖情况和 Workflow,又能让产品经理看得比较明白,同时又不会随着代码的更新而过期?

How does UTF-8 turn “😂” into “F09F9882”?

这篇文章描述了😂这个表情是如何被计算机描述为 F09F9882 的。

大概可以分两步,首先 UTF-8 是变长的,有一些字符占据的空间多一些(比如 emoji),有一些字符占据的空间少一些(比如英文字符),这样的话,当遇到一个 UTF-8 字符时,系统就要知道该读多长,这个信息会放到 header 里,也就是不同的 header 对应不同的长度,比如系统看到 header 是 1110 就知道这个要往后取 16 个比特。

然后再把 "😂" 对应的编码,按照 utf-8 的格式「压缩」一下,就变成了 F09F9882

52 Cards Win a Dollar

很有意思的一道题:

You have 52 playing cards (26 red, 26 black). You draw cards one by one. A red card pays you a dollar. A black one fines you a dollar. You can stop any time you want. Cards are not returned to the deck after being drawn. What is the optimal stopping rule in terms of maximizing expected payoff?

你有 52 张扑克牌(26 张红的,26 张黑的)。你一张一张地出牌,如果是红的赢一块钱,如果是黑的则输一块钱。可以随时选择终止游戏。扑克牌一旦出来就不会再被收回(比如出了 10 张牌,则手里就只有 42 张牌了)。问,玩这个游戏有什么最佳策略么?

这个看起来很随机的游戏,确实有「最佳策略」。52 张太多的话,可以把扑克牌减少一些,比如 6 张。

Cool Stuff

Startertab

可以自定义开始页的各个内容,有点像以前的 iGoogle(现在变成了 igoogleportal),可以把自己关心的信息集中起来,这里有一个演示视频

类似的 app 还有 start.me

Pokemon Cards Animation

鼠标移到卡片上,卡片会有 z 轴方向的反馈,给人一种 3D 的感觉,点击后也是用一种 3D 旋转的方式出来,还是挺酷的,用到了 CSS 的 3d transforms, filters, blend mode,CSS 的可玩性还是挺强的。

相关的 CSS 代码在这里

Worth Mention

Do things, tell people.

做一个很酷的能够向朋友炫耀的产品,即使没什么大用,即使还没有 Ready。找到合适的圈子去和其他人谈论它,慢慢就会与更多人建立连接,获取更多信息,这个产品成功的可能性也会更高。

Make something that you can talk about. Make something cool. Something interesting. Spend time on it. Go crazy. Even if it's the least useful thing you've ever made, if you can talk about it, make it.

Next, find events where the people you want to work with are. Then get a drink into you (or don't) and talk to them about it. Relax. It's probably interesting to them too. Even if it's not, because you've made it, you sound like you know what the hell you're talking about. That's the important part.

How To Learn Stuff Quickly

作者结合自己学东西的过程,总结了一套他认为比较有效的方法。

  • 心态:只要用心学,就一定有所成。大脑是可塑的。
  • 记忆:通过间隔记忆来提高记忆效率。
  • 激励:被某个效果所吸引,一定要做出来的决心。
  • 方法:每天都抽一小块时间用来学习,晚上可以再回顾一下,这样比周末学一天的效果要好。
  • 过程:
    1. 从教程开始,先对概念有个大概的理解。
    2. 重写一遍教程里的相关代码,这个过程一定会出现跟理论不符的状况,搞定它们。
    3. 拓展教程,如果要在教程的基础上添加某个 Feature 应该怎么办?
    4. 构建相关的 Projects,进一步夯实学到的知识点。

四只鸭子同半圆,概率有多大?

一道挺有趣的数学题:四只鸭子在一个圆形水池里,每只鸭子的位置随机,它们位于同一个半圆里的概率有多大?李永乐老师带来了他对这道题的思考和解答。

Why is it so hard to cure the common cold?

为什么没有普通感冒(common cold)的特效药?既然天花病毒可以通过疫苗被完全扼杀,那为什么普通感冒就不能通过注射疫苗来达到同样的效果呢?这个视频带我们快速(5分钟)地了解下背后的原因,主要是:1) 变异快,可以在很短时间内进化出适应疫苗或药物的病毒。2)变种基数大,一个鼻病毒就有很多的变种,很难针对性地去杀死它们并且不对人体产生副作用。

起床和睡觉

起床和睡觉是两个重要的节点,尽量固定这两个节点的时间。

  • 每天在同一时间起床,并在您刚开始感到困倦时入睡。
  • 早上第一件事就是晒 10-30 分钟太阳,就像在固定的时间醒来一样,这是另一种固定你身体机制的方法。
  • 至少在起床后 90 分钟之内不要喝带有咖啡因的饮料或食物。

知道事物的顺序是非常重要的

  • 对于大多数人来说,睡的越早质量越好,所以晚上看 Netflix 和早上看影响是不同的,晚上的损害更大一点。
  • 把早上的时间拿来读深度的东西,而不是去读碎片的社交资讯或者博文,这也许是另一种塑造更好的深度工作时间。
  • 下午锻炼似乎要比早上精力充沛(做创造性事情)或者晚上精神疲惫时收益更高,因此你可以更好的利用这些时间从而获得更多的锻炼和更有效的利用时间。
  • 在销售产品之前建立一个网友群可能更有效。

如果要养成读书的习惯,可以在早上醒来后给自己留半小时读 20 页的书:

20页足够小,不会让人感到阅读的恐惧。大多数人可以在30分钟内阅读完20页。如果在早晨做了这件事,那么一天的忙碌也不会受到影响。即便你一天过的很丧气,想到你早上读完的20页书,心里也会有一点安慰。

工程化你的习惯

好习惯带来复利,坏习惯带来负利,这两者之间的差异在时间的加成下会越来越大。作者列举了 3 个人的习惯,每个人的统计维度和 Routine 都不一样。有的会践行美德每日回顾(富兰克林),有的会建立表格跟踪习惯,并打分,还有的通过 8 + 1 的方式来跟踪:

把生活的各方面分成 8 个盒子。每周抽出时间对这8方面做一个回顾,看看生活的8个方面,确保事情是平衡的,每个盒子里面都有填入。这就是8 + 1系统中的 + 1。

如果你还没有自己的习惯系统,或许可以从中找到启发。

PERMA 模型

积极心理学之父 Seligman 提出了一个更全面的幸福模型:PERMA模型,每个字母代表的含义如下:

同一件事,我们可以消极地看,也可以正面地想,这是一种能力,越是困难的环境,对这个能力的要求越高。

我们应该都有过沉迷游戏的经历,这段时间可以非常忘我(E, Engagement),进入 Flow 状态。但当看到一天就这么过去了时,还是会有些小小的愧疚感,因为缺少了 M (Meaning) 的支持。

哈佛大学的一个历时 75 年的研究,跟踪了 700 多个人的工作、家庭、健康状况,得到了明确的结论:良好的人际关系能让人更加快乐和健康。

PERMA 将这些要素进行了融合,指向了一种创造的幸福,一种把我们自身与他人、社会福祉相联系的幸福,持久的幸福。这样的幸福,才配得上成为我们终身的目标。

Daily

这篇短文中,作者探讨了一个现象:为什么像 BeReal / Wordle / Nouns 这样的应用都使用了 Daily 模式,也就是每天触发一个 Activity。因为:

Daily Creates Habits. One of the best ways to develop a habit is to perform the smallest unit of the activity but do it every day.

作者本身也在实践这一方法,他已经写了 515 篇 Daily 短文,或许我们也可以找一个小的 Activity,然后 Do it Daily。

What's your single best piece of career advice

作者从 1300 多个职业建议中提炼的 12 个他认为的 Best Advices,可以参考下。

  • Reduce uncertainty for others as much as you can. You can kill your boss' uncertainty.
  • Take your assignment, however small or "unimportant", and do it really well.
  • If I can't trust you, it doesn't matter how smart you are.
  • Either learn or earn.
  • You’re the only person who is on your career journey.
    • Not the company you work for.
    • Not a manager you report to.
    • Not a team you’re on or work with.

创业要从「笨」事情做起

Paul Graham 的 Do Things that Don't Scale 的中文翻译,经典的文章就应该多读几遍。

我们鼓励每个创业公司将周增长率作为衡量自身进步的尺度。如果已拥有100名用户,那么需要在下周多招揽10名用户以实现每周10%的增长率。尽管110看起来比100强不了多少,但如果能将每周10%的增长率保持下去,累积起来的数字将会非常令人吃惊:一年后会达到14000,两年后会突破2000000。

交易平台型创业公司很难启动,因此创业者应该在初创期采取一些特别的举措。以 Airbnb 为例,他们最开始就是挨家挨户地寻访纽约的用户,招揽新用户,并引导现有用户更好地使用他们的产品来改进出租清单。在我的印象里,Airbnb 的创始人们常常带着他们的旅行袋出现在周二的晚餐时间,因为他们一定是刚从什么地方赶回来。

怎样才能用「笨方法」吸引用户呢?如果创业者仅仅想解决自己的问题,那么就找到和自己类似的人就好了,这通常不那么难。否则的话,创业者要努力地找出最合适的用户群体。通常的办法是,把产品投放给一批没经过特意选择的用户,随后观察哪些用户对产品更感兴趣,并找出与他们类似的用户群。

创业者不仅应该采取一些超常的举措去吸引用户,更要取悦用户。在线表单公司 Wufoo 就曾每一名新用户寄去一封手写的感谢函(并且出乎意料地坚持了很长时间)。这样一来,第一批用户就会觉得注册他们的产品是自己人生做过的最好决定。于是你也应该绞尽脑汁想出新点子让用户高兴。

我曾经一直在想可以用一个什么样的极端的词汇来形容创业者应该对用户的关心程度呢?然后我发现乔布斯已经找到了:疯狂的好 (insanely great)。他并不是用「疯狂」作为「非常」的一个近义词,而是真的从字面意思来解释——创业者对用户关照的程度应该放在日常生活里会被人觉得有病。

Wenbin Fang's Podcast Playlist

Listen Notes的 CEO,听了很多 Podcasts,这是他从众多 Podcasts 中选出来的单集列表,可以用 RSS 订阅。关于他为什么做这个 App,可以看这篇文章

张潇雨:我的人生信念

张潇雨自己总结的一些人生信条,有一些我觉得还挺不错的。

财富的累积不仅在于你做对了多少次决策,更在于决策正确的时候你的下注有多高

下注高低在于自己的信心如何。信心来自于你对一个事情的真正了解

财富的积累来自于不可替代性。学着让自己很难被替代,就像公司要建立自己的护城河

很多时候最好的竞争优势就是「别人觉得麻烦而你不觉得」

当两件事看起来有些矛盾的时候,几乎总有一个更高层面的东西把它们统一起来。不断寻找这样的东西,你就可以找到游戏的元规则

管理风险的另一个重要方法是不要玩你无法承担最坏结果的游戏,无论那个最坏结果发生的概率有多低

吃得健康、持续锻炼、保证睡眠,几乎可以带人走出任何困境

在解决生存问题之后,人的幸福感主要由身边关系的质量决定

学会对不带评判地自我觉察,这是一切改变的起点

印度Vipassana十日禅修冥想

Vipassana 也就是内观,在了解这个概念的过程中发现了这篇文章,作者描述了他从国企辞职后去印度参加十天内观禅修的感受,还是挺神奇的,几乎每一天都会有新的体验。对内观禅修感兴趣的可以看一下。

有必要说明这十天课程里面的戒律。

1.禁语,不能说话。

2.吃素,戒烟戒酒。

3.男女分开,不得交流。

4.完全断绝和外界的联系。

晚上到达瓦拉纳西,Venus说我看起来整个人不一样了,我说哪里不一样。她说:

“你眼睛里有光,那种可以穿越黑暗到达最后的光明的那种坚强的光。”

在坏年景中营造好的小天地|56件感恩小事

这是富于理性的不二同学对感恩练习(每天晚上睡觉前,写下你生命中值得感恩的五件事)的一些反馈,她的感受是:

在我的所有习惯中,没有哪个比「感恩练习」更让我感受到自己的富足;如果功利一点,用「投资回报率」来衡量,也没有哪个习惯能与「感恩练习」匹敌。

文中她还罗列了一些她的感恩事项,很细节,很美好,我也想尝试下,甚至想做一个应用。

  • 谢谢早上的风、在湖边练习瑜伽的畅快。
  • 晚上骑车回家,谢谢风钻进袖口、灌满T恤的那一刻。
  • 秋天的梭子蟹太好吃啦!

感恩练习与闪光点

也是围绕「感恩练习」的一篇文章,讲得更加细致,引用了相关的文章,对如何实践「感恩练习」会有不少帮助。

  • 不要只是走过场。第一步是要从内心希望变得更快乐、更有感恩之心,这个动机很重要。
  • 追求深度而不是广度。详细描述一件让你心存感激的事情,比肤浅罗列一个清单更好。
  • 多写写你感激的人,比只是写你感激的事更有效。
  • 尝试做减法,而不仅是做加法。激发感恩之情的有效方法是想象没有现在的生活会怎么样,而不仅仅是计算生活中的好事。
  • 品味惊喜。尝试记录出人意料或者让你惊喜的事情,因为这些事情往往能激发更强烈的感激之情。
  • 不必过度。偶尔记一记(每周一到两次),比每天写更好。

每天都有几个时刻会产生巨大的影响,我把这些小选择称为决定性时刻。你决定叫外卖或者在家自己做饭的那一刻,你决定开车或者骑自行车的那一刻,你决定开始写作业或者拿起游戏手柄的那一刻,这些选择就是生活之路上的岔路口。

神奇的苹果醋

根据 webmd 的研究,苹果醋对减肥,降血糖/血压,降胆固醇都有不错的效果。

  • may help with weight loss.
  • may lower blood sugar.
  • may lower cholesterol.
  • Lower blood pressure.

It's safe and tasty to use ACV to add some excitement to your meals. Use it to liven up sauces and stews as well as traditional salad dressings and marinades.

Tim Ferris 也在用它来提升睡眠效果,想买一箱感受下。

👍