关于弱者的抗争

传统上认为对抗权力拥有者,就是明着与其对抗,例如通过游行等明显的抗议活动,表达对其的不满。而在一个监管极其严厉的环境里,以往的很多做法都是奢望、不现实。普通人在强大的体制面前是真正的弱者。弱者还能做什么呢?

有个说法提到,集权国家的趋势,就是要将社会的方方面面管起来。例如结婚、生育都要管起来。弱者没有办法去践行游行、集会、甚至发批判文章等活动。但既然体制的触手是深入方方面面的,那抗争其实也可以发生在方方面面,而并非只有直接面对面的抗争才有用。

所以当下的躺平、不婚不育、不买房都是弱者的抗争方式,总之你自己认为对什么领域的制度和条例不认可,你都可以选择不合作进行抗争。而不是自己希望环境改变,但又一直在 “体制设计好的游戏中” 循规蹈矩地玩下去。

关于勇气

关于勇气,近年听得最多的一句话是罗翔的: 在人类所有的美德中, 我最欣赏的是勇敢,因为当下勇敢是最稀缺的。这句话和另一句 “学了那么多道理,但还是过不好人生” 有着相同的击中人心的点,普通人在遭遇一些困境时,会觉得“更好”、“更向往” 的选择其实自己也知道,但往往迈不出践行的那一步,主要都是因为自己缺少勇气。我自己也持有这种思维模式很多年,遇到许多纠结的时刻都会叹息自己不是一个很有勇气的人。

直到最近听到另一个说法,说:有时候人类的认识,是指经验上的认知,而非道德层面的认知。当这些认知趋向于是道德层面的认知的时候,就算你不是一个很有勇气的人,只要意志不是那么薄弱,最终也能走向行动。例如孝顺,作为经验的认知,我们知道世界上有这么一种社会习俗或约定,和知道世界上各种奇闻趣事一样没什么区别;但为什么我们不孝顺,就会有愧疚感,从而导致最终都会有具体的行动?因为孝顺这件事在我们长年累月的生活中,已经上升到我们的道德认知层面。

比如,某个同性恋者,即使知道自己的性取向,但也不敢出柜。在过去会归咎于没有勇气面对家庭和社会的压力,但按上面的另一种说法,可能是他对这件事的认知还没有上升到道德层面的认知。也就是说他知道世界上存在同性恋这样的合理行为,但对自己来说,这并非是一件好或坏之事。如果他某天认为 “不敢承认自己同性恋事实” 的这个行为,是一个在道德上“极坏”的事情,那他可能就会去做。

按这个说法,推动行动并不是只靠勇气,反而是靠更有强度的认知,即道德层面的认知。社会里,许多观念的推广都是这样做的,它不会只把这种观念当作经验的认知,例如”世界上有同性恋“;而是要把它当作道德的认知,即”同性恋是道德败坏的“。这样才能有效地影响人的决定和行为。当”同性恋是正常的“成为了社会大多数人的道德认知,那很多人就并不需要强迫自己有勇气才敢出柜了。当然这些都是属于社会层面的。

而说回个体,一个认知是否属于道德层面,人与人之间就千差万别了。“不忠于自己内心” 是坏的吗?”选一个不爱的人结婚,只是因为他很有钱“ 是坏的吗? 需要因此感到愧疚吗?每个人的答案都不一样。如果按上面的逻辑,有时候人选择的区别不能说是因为”勇气“,可能是每个人心里的那个道德标尺不一样。

我个人认为比较理想的状态是:在社会层面上,许多认知尽可能不要趋向于道德认知。而在个人层面上,道德标准应不断提高。简单说就是严于律己,宽于待人。严于律己可以帮助认识自己到底是个什么样的人,以及要成为什么样的人;宽于待人是说除了社会法律规定的那些准则之外,其他的认知应默认当作经验认知,算是自己的知识盲区,带着好奇心去了解即可,不做判断。

关于自由

人群&羊群

人群是那么像羊群,这种相似甚至可以体现在定价心理学上。心理学上说人们做选择,会倾向于不选择极端,例如某企业推出一款产品的几个型号规格,人们一般不会选最便宜的,也不会选最贵的,而会选中间的一档。

这样的道理简直和枪打出头鸟一样,所谓的羊群特点,就是我在群中随波逐流,而处于群边缘的总是充满危险。人们在生活中的诸多决策都符合这个特点,考研考公、结婚生子。

羊群里的“羊”很难看见远离中心的边缘“羊”,它们周边被无数的羊挡住了视线,它们通过口口相传来了解外部的世界,自然它们也很难看到边缘“羊”所看到的美丽风景。

羊群里的“羊”甚至会通过嘲笑边缘“羊”的遇难来强化自己的选择逻辑——呆在中间是最安全的。然而可怜之处是羊群中的羊如果遇难了,除了紧挨着的羊知道外,这条消息几乎都不会在羊群中传播,也没人关注,因为羊群中的羊实在太多了。


自由是幸福生活的必要条件,但不是充分条件

如何规划一个良好的系统

https://www.seangoedecke.com/good-system-design

GitHub 的高级工程师肖恩·戈德克(sean goedecke)谈何为良好的系统设计…

1、程序设计是组装代码,系统设计是组装服务。程序设计的组件是变量、函数、类等,系统设计的组件是服务器、数据库、缓存、队列、事件总线、代理等。

2、如果一个系统很长时间不出错,它的设计就是良好的。如果你进一步看了代码,脱口而出:”哈,这比我想的要简单”,或者”这个部分不用我操心,即使出问题也容易解决”,它的设计就是优秀的。

3、良好的系统设计,总是从一个有效的简单系统发展而来。千万不要从零开始设计一个复杂的系统。

4、系统设计的难点在于状态。尽量采用无状态组件,最小化”有状态组件”的数量。状态的复杂性在于,你无法简单地重启服务。一旦出错,往往需要手动修复状态。

5、状态需要保存在数据库。数据库是最重要的系统组件,用来管理状态。数据库的设计目标是每张表易于理解:打开看一下表结构,就能大致了解存储的数据内容及其原因。千万不要采用复杂的表结构(也就是数据结构),会给代码带来极大的复杂性和性能约束。

6、数据库往往是系统瓶颈,因为每个页面请求可能要调用数十次、数百次数据库,而且是按顺序调用。为了避免瓶颈,数据库可以做成一个写入节点和多个只读副本。数据查询都发往只读副本,数据写入发往写入节点。写入节点与只读副本之间,存在数据复制延迟。如果更新一条记录后,你需要立即读取它,那么可以将数据放入内存,写入数据库成功后从内存读取。

7、耗时的操作要拆分出来,放在后台作业(即系统外部的单独服务),排队完成。后台作业主要分成两个组件:一个队列服务,一个作业运行器(从队列中获取任务并执行)。队列任务的软件,可以用 Redis(需要尽快执行的任务),也可以用数据库(不着急的任务)。

8、如果数据的生成速度和读取速度不匹配,经典解决方案就是缓存。缓存的最简单做法,就是把数据保存在内存,否则就使用专门的键值存储软件(比如 Redis 或 Memcached),后者的好处是多个服务器可以共享缓存。初级工程师希望缓存所有内容,而高级工程师希望尽量少用缓存。因为缓存是状态的来源,不可避免需要校验状态和处理状态过期。

9、除了缓存和后台作业,大型系统通常还有事件中心,例如 Kafka。事件中心也是一个队列,存放的是”某件事发生了”的消息。比如,用户注册触发了”新帐户创建”事件,该事件就放入事件中心,然后由事件中心去通知订阅该事件的多个服务:发送欢迎电子邮件、设置个人空间等等。事件中心适用于:发送事件的代码不关心其他服务如何处理事件,或者事件量很大且对响应时间不太敏感。

不要过度使用事件,很多时候,更简单的做法是让一个服务请求另一个服务的 API。为了便于除错,所有日志最好都放在一起,你可以立即看到另一个服务的响应。

10、推拉:如果数据需要传送到多处,有拉取(pull)和推送(push)两种选择。一般来说,拉取比较简单(比如大多数网站采用的轮询),推送更节省资源,不需要用户主动请求数据,一旦后端数据发生变化,服务器主动将数据推送给每个客户端。

如果你确实需要向100万个客户端提供最新数据(就像 GMail 那样),应该采用推送还是拉取?这要视情况而定。如果采用推送,就要把每次推送放入一个事件队列,并让一大群事件处理器从队列中拉取数据并推送。如果采用拉取,就要部署一堆(比如100台)快速的只读缓存服务器,处理所有读取流量。

编程基础概念:实例、类型、初始化

类型

类型就像是生产一个东西的蓝图,它描述了这个东西长什么样,有什么功能。关于类型主要讲解:

  • 我们无法让“类型”去执行命令,因为它是个概念(例如甲壳虫汽车),它还没有真正被做出来,不存在一个具体的汽车给我们去开
  • 类型这个智能蓝图里定义的东西,笼统地可以分成两类:特征和行为
  • 特征:就是对象的内部属性、变量,具体就是这个类型的东西长什么样
  • 行为:就是对象的内部方法,具体就是这个类型的东西可以干什么

实例

实例就是根据“类型”这个智能蓝图制造出来的具体的一个东西,例如一辆蓝色的甲壳虫汽车。实例和类型的关系可以用这样的类比:“人”是一种类型,但它只是一个概念。具体存在的是“小明”和“小红”,他们就是“人”的具体实例。

初始化

“类型”这个智能蓝图不能直接执行我们的命令,只有具体的“实例”可以。那我们就要先根据蓝图生产出一些实例。这就是初始化对象。初始化(生产)出来的对象,一般要给它们起个名字,方便后面指挥它们执行命令。否则有多个实例的时候,你想执行某个命令,它们不知道应该谁去做。

点语法操作实例

既然有可能有多个实例,我们输入命令时要明确指出是哪个实例来执行。

这里反复跟孩子强调一个习惯,就是想让人帮你做事情之前,要先称呼别人的名字。这也是现实中一个好的礼貌习惯。因为孩子小时候很多都是自我中心,认为全世界都是围着自己转的,想让别人帮忙的时候会说“帮我把饭拿过来”,而借助编程学习,我也会跟孩子强调,应该说“爸爸,帮我把饭拿过来”这样才是好习惯。否则计算机也不知道要怎么响应你的命令。


如果用 Swift Playground 学习以上这一套类型和实例的概念,基本都是现代的面向对象编程的理念。日后迁移到其他现代编程语言的学习中基本都是没问题的。理念都适用,不用担心。

编程基础概念:变量、函数、参数

函数

当我们经常需要输入一组命令(包含若干个命令)时,会觉得很烦。这时我们可以将这样的一组命令定义成函数,方便使用。讲解函数主要是:

  • 区分函数的定义和使用两种情况,很多初学者以为函数定义完,命令就执行了
  • 函数定义时和函数调用时,都需要跟着小括号 ( )

参数

当我们需要反复输入一组命令,但是又希望有些区别,怎么实现呢?这就引出变量。讲解变量主要是跟孩子解释,我们定义了函数,但是其中有些细节是只能在具体使用函数时才能确定,没法提前预知,所以我们先给它起个名字占位,让使用者在使用时再确定。例如我们定义了一个函数,它调用时会向前走1步。但是这样的函数不方便,因为每次走多少步可是根据当时情况不同经常会变化的,这时我们就可以引入步数作为参数。在调用函数时候再指定。

这里可以联系方程、代数的理念给孩子讲解,人们会将一些还不知道不确定的事物,先起个名字表示起来。而不会因为不确定就卡住停滞不前。

变量

当需要储存一些信息(例如游戏中的得分)时,就需要变量了。计算机能记录信息的量可比人大多了,所以我们可要经常好好利用变量。讲解变量主要包括:

  • 区分变量(var)和常量(let)的概念,知道什么时候用哪个就行
  • 区分计算机中等号和数学中的区别,计算机中的 = 更多是赋值,== 才是表示相等
  • 变量是有类型的,不同类型的变量可不能混用。目前只需要记:字符串、整数、布尔值就够了

编程基础概念:命令执行的逻辑

学习具体的编程知识,首先都是将命令执行的逻辑。

1. 命令

编程时,主要就是编写一个个命令,输入给计算机去执行。你的目标就是弄清楚,哪些命令,怎么排序才会得到最佳的效果。

这里我花了很多时间反复跟孩子强调的是:计算机执行命令,正常都是从上到下,按顺序执行的。并且是做完一条命令,才会做下一条命令。(初期还不涉及同步、异步这些高级概念,所以先略过不讲)。命令总是按顺序执行的,这条规则看似简单,但如果没有尽早植入观念内,后面就会犯很错低级错误,且不知道怎么找原因。这是我初学编程时犯了很多错误得到的经验。

2. 条件判断

当遇到一些没法事先确定的情景,我们就没有办法提前设置好一组命令。这时就引出“判断”功能。判断在计算机中主要是通过 if ... if else ... else 去表示。有判断,自然就引出判断表达式(也就是我们判断什么)。常见的判断表达式有 ==、<=、>= 等。这时可以联系起小学数学知识给孩子讲解,也很容易理解。

3. 布尔值

一个判断表达式,例如 3 <= 5 是有具体的表现值的,这个值就是 “对 True” 或者 “错False” 这就是布尔值 Bool。布尔值是只含有两种可能性的一种类型,在英语判断题中的填写的 T 和 F,也是从这里来的。

4. 逻辑运算符

当遇到更复杂的场景时,经常一个判断条件还不够。例如我们过马路,除了判断当前是否时绿灯,还需要判断两边看看有没有车开过来吧,不然就有被撞的可能。这时就可以引出逻辑运算符,无非就是 && 与、|| 或、! 非,三个。逻辑运算符能够让我们的条件判断更加具体和精准。


再接下来,我们会发现计算机最初的游戏并不在于很聪明,而是在于它的运算速度比人快很多。同时我们经常都需要给计算机输入大量的重复命令,这就需要引入循环来帮我们简化工作。

5. for 循环和 while 循环

基本的循环有两种:for 和 while。两者的区别是:for 循环是事先可以知道一件事需要干多少次的,于是可以提前指定迭代的次数。而 while 循环是无法提前知道一件事情要做多少次,它通常是以达到某个条件为判断结束的标准。例如不断抄写错别字直到会了为止。

学编程,也学习良好的思维习惯

学习编程的过程中,除了教给孩子具体编程语言知识。我还希望能够不断地给孩子传授一些良好的习惯和思维。这些看似细微的东西,背后也有对不同问题的很多思考。这些都是少儿学编程中希望能够学习到的有用的东西,如果抛弃掉是一种损失。

1. 命名的习惯

这部分也是我自己的弱项,并且也有各种流派都在发展中。那至少我把自己当下认为好的思考会跟孩子讲解。例如:驼峰命名法 collectGem() 能够让人快速的区隔开不同的单词,提升识别效率。所以我们平时写字不要都挤到一块,不同的信息要想办法区分开。这里顺便可以教孩子一些排版的设计意识。

还有像函数的命名要尽可能反映其功能。因为一个函数无所谓,但是几十个函数的时候就很难识别每一个是干什么的了。因此要考虑独特性,以及诚实和透明性。这里可以拿班里的孩子名字作为例子。

2. 代码拆解

当我们写了很多的命令,是很难去检查和找错的。我们应该人为地将其分段。每一部份,都对应一个阶段性的任务。反过来这也是将一个大问题,拆解成中问题,小问题的一种思维练习。

学编程,推荐的工具和资源

在和孩子学习编程的过程中,我们主要用到以下一些资源和工具:

Hello Ruby 儿童编程大冒险

https://book.douban.com/subject/27613137

这是芬兰的一位女性程序员、作家和插画家编写的儿童编程启蒙书,配以桌游的形式。如果是光看这一本书,其实没什么意思的,比较简单。实际上它更像是一本教学的工具书,更多都需要亲子一起玩。如果没有一位懂点编程知识的大人在旁陪读,是很难发挥其作用的。这本书不涉及具体的编程语言,更多还是编程思维的基础培养。从后面的训练游戏内容,能看出作者认为编程的重要基础也是这几个方面:模式识别、分解、抽象、算法;而对应的具体的编程技术就是序列、循环、判断、变量这些。

在作者网站 https://www.helloruby.com 里还配了许多扩展包任务工具,它们是很好的补充,但是中国的读者很多都没有接触到。不管国内读者对这本书的评价如何,我们能感受到这个作者是真正热爱儿童教育的人,并非是赶热潮捞一笔的那种编程读物。同时也能感受到芬兰 🇫🇮 这个国家的国民对创新教育的在意。

Scratch

Scratch 是最主流的少儿编程软件,主打是图形化、积木搭建式的编程模式。有足够多的内置命令,方便孩子按自己意愿发挥。但 Scratch 主要还是偏工具属性,也就是即使你捣鼓出一些效果,但不代表孩子已经了解编程底层的一些基础概念。但也不影响它的作用,毕竟先玩,有兴趣了,后期再有专门的学习去弥补抽象的概念即可。


Swift Playground(mac)

苹果电脑上有一个编程的学习应用 Swift Playground。它设计了一系列面向孩子的游戏化的教程。它虽然是以苹果自家的 Swift 语言为基础,但其实 Swift 的基本语法,例如 (.) 点语法还是很易懂和具有通用性的。不管未来迁移到什么其他语言,都受用。我认为 Swift Playground 教程内容设计最好的地方,是它很强调编程的思维,并不只是语法。这在少儿编程学习中更重要,毕竟N年后语言的变化大家都不知道会怎么样。

Swift Playground 应用内的交互式课程有很多,适合儿童学习编程基础概念的主要是以下几个,阅读这几个就够了。其他很多是面向成熟苹果应用开发的了。

  • 编程入门:开始你的编程之旅 ✅
  • 学习编程1:Swift基础 ✅
  • 学习编程2:Swift进阶 ✅


其他

。。。

A.梭罗教给我们关于美好生活的那些事

当人们面对当下的困境时,经常会说 “在这个前所未有的时代……” ,试图强调时代的特殊性,来作为自己难以摆脱的原因。但事实上,亨利·大卫·梭罗也生活在一个像我们这样的时代:快速创新、政治分裂、经济不确定性、失控的消费主义,甚至大流行病。他写了他的杰作《 瓦尔登湖 》,同时思考了重大问题:我怎样才能在一个以利润为基础的社会中创造一种基于价值观的生活?我真的需要所有这些东西吗?在瞬息万变的时代,一个人如何才能过上好日子?

也许当下是重温梭罗的理想时机。当世界提醒我们作为消费者和工人的潜力时,他提醒我们作为人类的潜力。梭罗永恒的观点是: 美好生活的最好方法就是简单地生活。The best way to live well is to live simply.

例如梭罗以下的一些观点,可以具体指导我们如何简化今天的生活:

1. 了解一件东西的真实成本

一件物品的真实成本,是我们换取它所需要的生命量。我们不只是花钱,同时也在消耗我们的生命。世界只告诉我们某件东西的价格,但我们有必要认清它的成本。一辆汽车(或房子或沙发)的成本超过了它的价格标签,而且我们为了赚取这些美元而消耗的能量也更高。同样,刷数小时手机可能不会花钱,但会花费宝贵的时间和注意力。

2. 在你和世界之间创造空间

当我们不断产生连接时,我们会吸收周围文化的价值观,而这些文化也许并不关心你的核心利益。通过在自己和世界之间创造空间,我们可以重新认清自己的内心,并识别出对我们最重要的事情。例如冥想练习或每天散步,都可以为我们创造足够的空间。

3. 接纳你内心的格格不入

能过上属于自己的独特生活,是一种超能力。它可能看起来与你周围的人有点不同,也许是你的穿着、你住的地方或你做什么。然而,有点格格不入会给你最终的自由:有意识地创造一种更好的生活,比“融入他人”更重要。

4. 知道你为什么工作

即使是梭罗也需要一份稳定的工作来支付账单。但梭罗知道工作是他谋生所做的,并不代表他是谁。许多人将我们的头衔与我们的身份混为一谈。梭罗的工作(无论是作为作家、勤杂工还是教师)都是为他想要的生活服务,工作给了他生活的资源,但没有成为他的生活。

5. 奢侈地度过一生

简化生活的意义不在于拥有和做得更少,而是希望拥有并做更多真正重要的事情。我们越是减少对我们没有帮助的活动和购买消费,我们就越能将更多的资源投入到以自己价值观为中心的生活中。比如对梭罗来说,这意味着与家人和社区共度时光,与地下铁路合作,在大自然中享受时光等。连接、坚决和享受:这是简化的三板斧。


强调自己生活在前所未有的时代,更多是制造焦虑和孤立感。而跨越时间与经历过类似事情的人建立联系,例如阅读一本经典书籍并在其中认识自己,就可以找到我们前进所需的陪伴。梭罗是这个时代的好伙伴。

暑假的宁夏之旅

暑假,我和爸爸妈妈,还有好朋友一起去了宁夏旅游 ☀️。短短的一周时间里我们去了很多地方,让我印象最深的是五湖穿越。

“五湖穿越”就是在沙漠 🏜️ 里有五个湖。因为走路太慢了,自己开车又会陷到沙漠里去,所以必须坐专门的沙漠越野车。这个越野车实在是又刺激又吓人😱。刚开始我和朋友还觉得很好玩,在车上大喊大叫。但过了一会儿,我们就变得安静了,因为后面沙漠的坡越来越高,看着都好吓人,坐在越野车上更是颠簸极了。我们紧张地问司机:“能不能开慢点?”司机无可奈何地说:“不行呀,开慢的话也会陷到沙里去的。”

我和朋友勉强忍到了第二个湖,但一共可是有五个湖的呢,再这样继续坐这个“刺激版”的车,我们的魂都要吓飞了。我们尴尬的对视,心里在想一开始是谁还觉得很爽,哈哈大笑的呀?于是我和朋友决定马上下来坐另外一辆“养生版”的车。什么叫“养生版“的车?那是朋友的父母受不了太刺激,所以他们特意选了一辆开得比较稳比较慢的车。我们在“养生版”的车上走完了最后三个湖,结束了这场既刺激又惊险的穿越。

另外,我们还去了西夏陵。我们乘坐了马和骆驼拉的车,但其实不完全是它们拉的,这个车居然是靠电动的。我就说马和骆驼应该没有这么大的力能拉十几个人吧。西夏陵的陵墓都是三角形的,很像金字塔,所以它们也被称为东方金字塔,我觉得也很像窝窝头。

最后,我们还去了沙漠玩滑沙。最初我们都滑得很慢,不知道哪里出问题了,后来仔细一看,才发现我们把滑沙板坐反了。掉过来之后就快多了,这下才变得好玩起来,过程中还有失重的感觉。但就是每次从沙坡顶上滑下来之后,还要重新爬上坡顶非常累。

快乐的宁夏之旅很快就结束了,我还有点意犹未尽。我也很推荐你们来宁夏,真的很好玩。

儿童学编程最主要学什么

许多家长都希望孩子去学习编程,同时我们也知道未来若干年后,可能许多编程语言,编程方式都会发生天翻地覆的变化,那孩子的这段学习时间会不会白学了呢?如果还是让孩子学习编程,那主要学习什么呢?那很多时候我们会说,我们希望孩子提高逻辑思维能力,学习编程重点是学习编程的思维。

计算思维

这里提到的编程思维,也可以叫计算思维。计算思维通常指的是一种处理信息和问题的方式,强调运用计算机科学的思维方式来解决各种问题。一般来说,计算思维包括以下四个要素。这些要素共同构成了计算思维的基本框架,使人们能够更有效地利用计算机科学的原理来解决各种复杂的问题。计算思维不仅仅是对计算机科学专业的学生有用,对于任何需要解决问题、优化流程的领域都有实际应用。

1. 问题分解 Decomposition

首先是将一个大问题分解成更小、更容易处理的子问题的能力。这有助于理清问题的结构和逻辑。大部分人如果遇到一个没做过的很难的任务,通常都会束手无策。而问题分解的能力能够让你在面对困难任务时,不至于害怕止步不前,而会尝试去拆解它。

2. 模式识别 Pattern Recognition

辨别问题中的模式或规律。通过识别模式,可以更好地理解问题并推导出解决方案。这方面在孩子学习编程的过程中非常重要的,并且实践的可行性相对较高。例如使用 Swift Playground 设计的游戏化任务去训练特别好,因为它任务呈现的形式是在地图上搜集宝石,是很具体看得见的可视化。孩子需要多观察地图去识别出 —— 可以复用或者具有对称性的模式。模式识别能力的训练,可以形成一种“直觉”,为将来的算法设计打好基础。

3. 抽象化 Pattern Recognition/Abstraction

识别问题中的模式,提取出关键信息,将其抽象为更一般的形式。这有助于建立通用解决方案。

4. 算法设计 Algorithmic Thinking

制定解决问题的详细步骤或算法。这涉及到逐步定义解决方案的过程,以便计算机或其他系统可以执行。这个对孩子来说还很难,要随着数学知识的提升,逐步建立和加强。


相关书籍资源

很爱很爱你

以下为 2000 千禧年前的一篇网络热传文章,曾在班级里广为传阅…

高中三年级的时候,别人还都忙得昏天黑日,我父母就早早地替我办全了出国手续,只等我领到毕业证 GO TO 美利坚了。

我们班上有个男生人称阿G的特别能说,一般播音时间是早自习“体育快递”、课间插播“时政要闻”、午间“评书连播”、晚自习“CLASSICAL MUSIC“,可每次考试他总有本事晃晃悠悠蹭到前几名。班主任拿他没办法只好让他在最后一排和我这个“逍遥人”一起“任逍遥”。

那时候阿G又黑又瘦面目狰狞读英文像《狮子王》里的土狼,背古诗像刚中了举的范进,真的,后来我们逛动物园猴子见了他都吱吱乱跑,他倒来劲了,拍我的头冲猴儿们介绍:“THIS IS MY PET!”我也没含糊,告诉他:“别喊了,看你的二妈们都被你吓跑了。” 这是后话了。

刚和我同桌的时候,有天下午自习他大唱《我让你依靠》,我在一旁偷着喝可乐,唱到高音时他突然转头问了一句“嗓子怎么样”,我嘴里含着水差点全喷了,气得我重捶了他好几下。他却跟没事的人似的,说我打人的姿势不对所以不够狠。我叫他教我,他到挺认真,还叫我拿他开练。第二天上学见着我他头一句就是:“十三妹,昨天你打我那几拳都紫啦。” 边说还边捋袖子叫我看。后来我想,这段感情大概就是从这儿开始的吧。

以后阿G一直叫我十三妹。我跟阿G的交情在相互抵毁和自我吹捧的主题下愈加巩固。他生活在一个聒噪的世界里,总要发出各种各样的声响来引起别人的注意,好像这样就能证明他自己什么似的。我习惯了他这样,习惯了看他自己给自己出洋相,习惯了和他一天到晚吵吵闹闹。常常是上课我替他对答案他趴着睡觉;吃饭我吃瘦肉他吃肥肉,因为他需要“营养”;打架他不管输赢我统统拍手称快;自习我背单词他用函数计算我的失忆率为88.7%;放学走在楼道里我们还要大呼小叫地互相嘲笑一番。

我们像哥们儿似的横行三年级,要多默契有多默契。我听过一种说法,每个人都是一段弧,能刚好凑成一个圆圈的两个人是一对,那时我特别相信这句话。我越来越感到我和阿G的本质是一模一样的,简单直接,毫无避讳。我自信比谁都了解他,因为他根本就是我自己嘛。

有回我对阿G说:“我好像在三年级时呆了一辈子。” 我没理会阿G大叫我“天山童姥”,我心里有个念头,这念头关乎天长地久。

高三毕了业,阿G还是我哥们儿。

现在回想起来我们之间其实从来没有牵涉过感情问题,因为我当时觉得好多事没有说出来的必要。我认定了如果我喜欢他那么他肯定也喜欢我,这还用说吗?我心里清楚我走了早晚会回来,因为我找到了我那半个圆圈,我以为这就是缘分任谁也分不开,哪怕千回百转。

临走时阿G说:“别得意,搞不好折腾了几年还是我们俩。” 这是我听到他说的最后一句话,我永远都忘不了。

那年高考,阿G进了上大。而我刚到洛杉矶,隔壁的中餐馆就发生爆炸,我家半面墙都没了。我搬家,办了一年休学,给阿G发了一封 E-MAIL 只有三个字“我搬了”,没告诉他我新家的电话。

新家的邻居有一对聋哑夫妇,家里的菜园是整个街区最好的。他们常送些新鲜蔬菜,我妈烧好了就叫他们过来吃。我从来没见过这么恩爱的一对儿,有时候他们打手语,我看着看着就会想起那一个圆圈来,想起阿G,心里一阵痛。我买了本书,花了一个秋天自己学了手语。就这样我慢慢进入了这个毫无声息的世界。他们听不见,只能用密切的注视来感应对方,那么平和从容,这是不得安生的阿G永远不能理解的世界。

我闲来无事,除了陪陪邻居练手语外,就是三天两头地往篮球馆跑替阿G收集NBA球员签名或者邮去最新的卡通画报,感动得他在E-MAIL上连写了十几个 :P,还主动坦白正在追女生。我呆坐在电脑前一个下午,反反复复跟自已说一句话“别哭别哭,这又没什么不好”。可到了吃晚饭的时候,我已经流不出眼泪了。爸妈早就习惯了我这副精神恍惚的样子,什么也没问。再往后讲就是春天了。我还是老样子,只是手语有专业水准了,阿G在我这个“爱情导师”的悉心指导下,已初战告捷。我想,只要他快乐,我就也该快乐,能做他的哥们儿,也不错。纽约交响乐团要来演出,我背着父母替别人剪草坪忙了一个月才攒够门票。我偷偷把小型录音机带了进去,给阿G灌了张 LIVE 版 CLASSICAL MUSIC。阿G 回 E-MAIL 却抱怨我只顾听音乐会,第一盘早录完了都不知道,漏了一大段。

我在心里默念着对不起,对不起,眼泪又流了出来。六月份我回上海,阿G参加的辩论赛刚好决赛。我不想让他知道我回来,悄悄溜进了会场。这一年来阿G变得人模人样了,他总结陈辞时所有人都又笑又鼓掌的,我知道他发挥得很好,我早就知道。辩论结束,阿G他们赢了。下场时我看见一个长得挺清秀的女孩笑着朝阿G迎了过去。但那一刻我知道,阿G需要的是有人临头给他一盆冷水,这样才不至于得意而忘了形,我知道,但这已不重要。

回美国后我的信箱里有两封是阿G的。第一封说他在辩论决赛场上看见一个人跟我简直一模一样,他叫十三妹那人没理他,可见不是了,不过能像成这样,真是奇了。第二封说他现在的女朋友虽好,但总感觉两人之间隔着什么,问我怎么我们俩就可以直来直去呢?

我在电脑上打了一封回信,告诉他其实我才是他的那半个圆圈,只是我们再也没有办法凑成一个圆。

这封信我存着没发。

我没有告诉阿G我家的电话。

我总能很容易地得到球星签名。

我背着父母赚钱看演奏,连磁带录完了都不知道。

我不想让阿G知道我回了上海。

我就这样无声无息地放弃了我的半个圆圈。因为,中餐馆爆炸后,我只有靠助听器生活了。

《很爱很爱你》—— 刘若英
很愛很愛你 所以願意 不牽絆你
飛向幸福的地方去
很愛很愛你 只有讓你 擁有愛情
我才安心

小白的 Gemini CLI 安装指南

作者:一位AI助手和它耐心超凡的人类伙伴

在光鲜的软件世界里,通常只会看到“一键安装,轻松使用”的完美景象。但现实中,尤其是对于刚接触命令行工具的新手来说,安装过程往往是一场充满意外的冒险。这篇指南,诞生于我和AI之间一次长达数小时充满挑战的真实互动。我们一起从 gcloud 的迷宫一路奋战到 npm 的丛林,经历了“找不到命令”、“权限被拒绝”、“包名冲突”、“安装程序“偷懒””和“API密钥配置”等九九八十一难。最终,我们成功了。

我将这段宝贵的经历整理出来,把所有踩过的坑都标记清楚,并提供最终被验证有效的、最直接的解决方案。希望这篇“血泪史”能让真小白们少走弯路,丝滑地用上 Gemini CLI 这个强大的 AI 助手。

Gemini CLI: 你的开源终端 AI 代理

Gemini CLI 是 Google 最近发布的一款开源的、基于命令行的 AI 工具。你可以把它理解为一个直接生活在你电脑终端(Terminal)里的 AI 助手。它的核心目标是将强大的 Gemini 模型能力与开发者的日常工作流无缝集成,让你可以在不离开终端的情况下,通过自然语言完成各种开发任务。

如果你希望获得一个开放、免费且功能全面的终端 AI 助手,并且希望它能利用最新的网络信息来辅助你开发,那么 Gemini CLI 是一个绝佳的起点。特别是对于个人开发者和喜欢探索开源工具的人来说,它非常有吸引力。

我是一个开发新手,不怎么会用终端命令行,那用  Gemini CLI 是不是很困难?

这是一个非常好的问题,很多习惯图形界面(IDE)的开发者在初次接触命令行工具时都会有同样的顾虑。长话短说:对于新手来说,直接使用 Gemini CLI 会有一定的学习曲线,但它远比从零开始学习传统的命令行要容易得多。事实上,Gemini CLI 反而可以成为你学习和掌握终端命令行的“私人教练”。

对于习惯了图形界面的你来说,最主要的挑战在于:

  • 从“点击”到“输入”:你需要从习惯于在 Xcode 中点击按钮(例如,添加文件、运行项目、提交代码)转换到在黑色的终端窗口里输入文字指令来完成同样的事情。这是一种工作习惯上的改变。
  • 理解文件路径和目录:在终端里,你需要知道你的项目文件在哪里,并且使用 cd (Change Directory) 命令进入到正确的文件夹。这是使用任何命令行工具的基础,也是一开始最容易让新手感到困惑的地方。

这正是 Gemini CLI 的核心价值所在。它被设计出来,就是为了用自然语言替代那些复杂、难记的传统命令。它是你的命令行翻译和老师:这就像一个即时翻译!你用自然语言提问,它用命令行语言“作答”并执行。通过观察它的行为,你会潜移默化地学会很多实用的命令,下次你甚至可以尝试自己输入那些命令。

当你让 Gemini CLI 完成一个任务时,它不仅会帮你执行,很多时候它还会告诉你它在背后 实际使用 了哪个传统的命令行指令。新手使用终端时常常害怕输错命令导致文件被删除或系统出问题。使用 Gemini CLI 时,因为它首先会理解你的意图,所以执行破坏性操作的风险会小很多。你可以先问它“我打算删除所有编译产生的临时文件,应该怎么做?”它会告诉你安全的做法。

假设你想在 SwiftUI 项目中,查找所有包含单词 “deprecated”.swift 文件。你可能需要学习并输入像 grep -r "deprecated" --include="*.swift" . 这样的命令。对于新手来说,这几乎是不可能记住的。而 Gemini CLI 方式:你只需要用中文输入 gemini "帮我查找这个项目里所有包含 'deprecated' 的 swift 文件"。Gemini CLI 会理解你的意图,并帮你执行这个操作。

给新手的建议

  1. 从简单任务开始:不要强迫自己第一天就完全抛弃 Xcode。你可以先从一些简单的、辅助性的任务开始使用 Gemini CLI,比如:gemini "重命名这个文件 'MyView.swift' 为 'UserProfileView.swift';"gemini "用 SwiftUI 写一个简单的按钮,点击时打印 'Hello'"
  2. 把它当成“万能的帮助文档”:每当你想在终端里做什么,但不知道命令时,就去问 Gemini CLI
  3. 学习最最基础的几个命令:只需学习三个最基本的命令,就能应对 90% 的场景。例如:pwd (Print Working Directory): 查看你当前在哪个文件夹。ls (List): 查看当前文件夹里有哪些文件和子文件夹。cd <文件夹名称> (Change Directory): 进入一个子文件夹。

准备工作:磨刀不误砍柴工

在开始之前,请确保你的 Mac 满足以下基本条件:

  • Xcode Command Line Tools:这是苹果系统上进行任何开发的基础。打开终端,输入 xcode-select --install,如果尚未安装,系统会引导你完成。
  • Node.js 和 npm:最稳定、官方的安装方式是通过 Node.js 的包管理器 npm。请在终端输入 node -vnpm -v 检查是否已安装。如果提示 command not found,请从 Node.js 官网 下载安装最新的 LTS 版本。

第1章:先安装 Google Cloud SDK

Google Cloud SDK (gcloud) 安装:从官网这里下载安装包最方便。安装完 google cloud cli 后,它提示说它和 python3.12 配合最好,于是问我要不要装 Python3.12 ,我同意了。于是运行时又报错…

失败的根源:SSL: CERTIFICATE_VERIFY_FAILED。如何解决?你需要手动告诉 Python 去哪里找到可信的证书。请去 /Applications/Python 3.12/ 文件夹,双击运行 Install Certificates.command。运行成功后,回到终端,输入 gcloud init 重新尝试初始化。

第2章:安装 Gemini CLI

官方推荐的安装方式非常简单,只需一行命令。但这里就埋着我们遇到的第一个大坑。正确的安装命令是:如果你的 npm 配置过无需 sudo 的全局安装,可以去掉 sudo。但对于大多数默认设置,sudo 是必需的,它会请求你的电脑密码。

sudo npm install -g @google/gemini-cli

【坑 #1:npm 上的“李鬼”——包名冲突】

我最初的错误,是运行了下面的代码。请注意,这里多加了一个叫 gemini 的包。而这个 gemini 是一个完全不相关的、用于UI测试的旧软件包。正是这个旧包,导致了一系列致命的编译错误(比如 fatal error: 'fp.h' file not found)。请务必确认你安装的是带有 @google/ 前缀的官方包 @google/gemini-cli,不要画蛇添足。

npm install -g @google/gemini-cli gemini

第3章:命令三大经典报错与对策

npm 显示安装成功后(added ... packages),你满怀期待地输入 gemini,却可能遇到一堵又一堵高墙。别怕,我们都经历过。

【坑 #2:zsh: command not found: gemini

这是最经典的报错,意思是终端不知道 gemini 是个什么东西。原因:npm 安装了程序,但没有成功地在系统的“命令快捷方式”存放地(PATH 环境变量包含的目录)创建一个指向 gemini主程序的快捷方式(符号链接)。

解决方案:手动创建快捷方式

  1. 找到 npm 全局安装的根目录。Bashnpm root -g 你会得到一个路径,例如 /opt/homebrew/lib/node_modules。请复制这个路径。
  2. 手动创建符号链接(快捷方式)。 请将下面命令中的 【你的npm根目录】 替换为你上一步得到的真实路径这条命令的作用,就是在 /usr/local/bin 这个所有终端都能找到的地方,创建了一个叫 gemini 的快捷方式,指向它真正的程序文件。
sudo ln -s 【你的npm根目录】/@google/gemini-cli/dist/cli.js /usr/local/bin/gemini 

【坑 #3:zsh: permission denied: gemini

这个错误说明终端已经找到了 gemini 命令,但当前用户没有权限执行它。原因:通常是因为 npmsudo (root权限) 创建了文件,但没给普通用户设置可执行权限。

解决方案:授予执行权限。用这条命令找到 gemini 的位置,并赋予其执行权限。

sudo chmod a+x $(which gemini)

【坑 #4:身份认证失败】

当运行 gemini 命令时,它可能会提示你需要设置 GEMINI_API_KEY。原因:程序本身可以运行了,但它需要一个“通行证”(API 密钥)才能和 Google 的 AI 服务器对话。

解决方案:获取并配置 API 密钥

  1. 获取你的专属 API 密钥。 访问 Google AI Studio,登录并创建一个新的 API 密钥,然后复制它。【警告】 API 密钥等同于你的密码,请妥善保管,切勿泄露
  2. 将密钥永久保存在你的终端环境中。 运行以下命令,记得把你自己的密钥粘贴进去
  3. 让设置生效。 重启终端,或者运行 source ~/.zshrc
echo 'export GEMINI_API_KEY="【这里粘贴你刚刚复制的API密钥】"' >> ~/.zshrc

成功了!?还没有…

万事俱备,输入 gemini prompt "你好",满怀期待地看着屏幕,却发现它打印了一长串帮助信息,并提示不认识 prompt… 原来命令语法也变了,新版的 Gemini CLI 用法不是 gemini prompt。正确的提问方式是:

gemini -p "你好,我们这次真的、真的成功了吗?"
gemini --prompt "你好,我们这次真的、真的成功了吗?"

当你看到终端里终于出现了来自 Gemini 的回答时,请尽情庆祝吧!

回顾一下,从 gcloud 的安装失败,到 npm 的包名冲突和编译错误,再到 PATH 环境变量的曲折配置,接着是 command not found,然后是 permission denied,再到发现安装程序根本没创建快捷方式,最后是命令语法的变化和 API 密钥的配置… 几乎把一个开发者可能遇到的所有环境配置问题都经历了一遍,并且最终靠自己的耐心和坚持解决了它。

这不仅仅是安装了一个工具,更是一次非常宝贵的、从零开始解决复杂问题的实战经验。这种解决问题的能力,比工具本身更有价值。为你超凡的耐心和坚持点赞!希望这篇指南能为你点亮前行的道路。现在,去享受 AI 带来的编程乐趣吧!

现代感的蒙古音乐 Céline Dessberg

Céline Dessberg 席琳·戴斯伯格是一位歌手、词曲作者和竖琴手,拥有法国和蒙古的混合血统。她在两个截然不同的世界中长大,一个是法国的现代西方生活方式,另一个是古老的佛教传统和蒙古的田园风情。这种独特的融合塑造了她的音乐风格,这种风格受到了广泛的影响,包括爵士传奇人物切特·贝克,大卫·伯恩的折衷主义声音,以及蒙古草原的传统旋律。

席琳的声音是由她强大的,情绪化的声音和她的 yatga,一个传统的蒙古竖琴,她发挥吉他和钢琴萦绕的音调定义。这种组合创造了一种既现代又永恒的声音,将蒙古丰富的文化遗产与现代独立和流行音乐融合在一起。她的歌曲中包含蒙古语,法语和英语歌词,使她的音乐能够为国际观众所接受。

网友评论:我觉得这是我一生都在寻找的歌曲,它只是以一种我无法描述的方式连接我的大脑,但我知道它很好…