软件架构设计必备概念

背诵版。

软件架构风格

描述特定软件系统组织方式的惯用模式,组织方式描述了系统的组成构件和这些构件的组织方式,惯用模式则反映众多系统共有的结构和语义。

架构风险

架构设计中潜在的、存在问题的架构决策所带来的隐患。

风险点与非风险点

风险点:可能引起风险的因素。

某个做法如果有隐患,有可能导致一些问题,则为风险点。

非风险点:如果某件事是可行的可接受的,则为非风险点。

敏感点

为实现某种特定的质量属性,一个或多个构件所具有的特性。

权衡点

影响多个质量属性的特性,是多个质量属性的敏感点。

Kubernetes helm 部署 prometheus stack

Pometheus-Oerator 已经准备弃用,采用社区维护的 prometheus stack 部署。

helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm repo update

# install
helm install prometheus-stack prometheus-community/kube-prometheus-stack -n monitoring --create-namespace

# upgrade
helm upgrade prometheus-stack prometheus-community/kube-prometheus-stack

# uninstall
helm uninstall prometheus-stack

References

kompose 转换 docker compose 应用为 k8s 资源清单

Compose是Docker Compose到容器编排(如Kubernetes或OpenShift)的转换工具。

官方Kubernetes项目,仓库位于github.com/kubernetes/kompose。

安装

# Linux
curl -L https://github.com/kubernetes/kompose/releases/download/v1.34.0/kompose-linux-amd64 -o kompose

# Linux ARM64
curl -L https://github.com/kubernetes/kompose/releases/download/v1.34.0/kompose-linux-arm64 -o kompose

# macOS
curl -L https://github.com/kubernetes/kompose/releases/download/v1.34.0/kompose-darwin-amd64 -o kompose

# macOS ARM64
curl -L https://github.com/kubernetes/kompose/releases/download/v1.34.0/kompose-darwin-arm64 -o kompose

chmod +x kompose
sudo mv ./kompose /usr/local/bin/kompose

使用

$ kompose convert -f compose.yaml

$ kubectl apply -f .

$ kubectl get po
NAME                            READY     STATUS              RESTARTS   AGE
frontend-591253677-5t038        1/1       Running             0          10s
redis-leader-2410703502-9hshf   1/1       Running             0          10s
redis-replica-4049176185-hr1lr  1/1       Running             0          10s

也可以修改控制器,比如指定使用 Statefulset 就这样:

$ kompose convert -f compose.yaml --controller statefulset

作者 使用这个工具快速成功部署了 logto 和 lobechat。

更多详情查询官网。

References

kubernetes 部署 cert-manager 快速实现自动 ssl

简单记录,使用 cloudflare dns 自动完成域名 ssl 证书申请并配置到 ingress 的关键步骤。

安装

使用 helm 安装方法如下:

helm repo add jetstack https://charts.jetstack.io --force-update
helm install \
  cert-manager jetstack/cert-manager \
  --namespace cert-manager \
  --create-namespace \
  --version v1.16.1 \
  --set crds.enabled=true

配置

使用 cloudflare 密钥自动认证

apiVersion: v1
kind: Secret
metadata:
  name: cloudflare-api-token-secret
  namespace: cert-manager
type: Opaque
stringData:
  api-token: xxxxxxxxxx

定义 issuer

apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: issuer01
spec:
  acme:
    email: XXXXXX
      # 配置证书目录,演练环境使用Staging环境,正式环境使用另一个
    #server: https://acme-staging-v02.api.letsencrypt.org/directory
    server: https://acme-v02.api.letsencrypt.org/directory
    privateKeySecretRef:
      # Secret resource that will be used to store the account's private key.
      name: issuer-account-key
    solvers:
    - dns01:
        cloudflare:
          apiTokenSecretRef:
            name: cloudflare-api-token-secret
            key: api-token

示例程序

apiVersion: apps/v1
kind: Deployment
metadata:
  name: whoami-deploy
spec:
  replicas: 1
  selector:
    matchLabels:
      app: whoami
      release: canary
  template:
    metadata:
      labels:
        app: whoami
        release: canary
    spec:
      containers:
      - name: whoami
        image: traefik/whoami:v1.10
        ports:
        - name: http
          containerPort: 80

---
apiVersion: v1
kind: Service
metadata:
  name: whoami
spec:
  selector:
    app: whoami
    release: canary
  ports:
  - name: http
    port: 80
    targetPort: 80 # pod port

---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingress-whoami
  annotations:
    cert-manager.io/cluster-issuer: issuer01
  #  kubernetes.io/tls-acme: "true"
spec:
  ingressClassName: nginx
  rules:
  - host: whoami.hzc1.skybyte.me
    http:
      paths:
      - backend:
          service:
            name: whoami
            port:
              number: 80
        path: /
        pathType: Prefix
  tls:
  - hosts:
    - whoami.hzc1.skybyte.me
    secretName: whoami-hzc1-skybyte-me-tls # Name of secret automatically generated.

References

临时解决 vagrant 不支持 virtualbox7.1

介绍一种临时解决 Recent version of Virtualbox 7.1.0 is not supported by vagrant 2.4.1 的方法:

解决方案

方案一

$ sudo viVirtualBoxVM|virtualboxvm)
     VBoxManage|vboxmanage)
-        exec "$INSTALL_DIR/VBoxManage" "$@"
+   if [[ $@ == "--version" ]]; then
+     echo "7.0.0r164728"
+   else
+          exec "$INSTALL_DIR/VBoxManage" "$@"
+   fi
         ;;
     VBoxSDL|vboxsdl)
         exec "$INSTALL_DIR/VBoxSDL" "$@"

方案二

$ sudo vim /opt/vagrant/embedded/gems/gems/vagrant-2.4.1/plugins/providers/virtualbox/driver
$ diff -u meta.rb.orig meta.rb
--- meta.rb.orig        2024-09-16 11:37:37.017440100 +0100
+++ meta.rb     2024-09-16 11:33:51.312254400 +0100
@@ -69,6 +69,7 @@
             "6.0" => Version_6_0,
             "6.1" => Version_6_1,
             "7.0" => Version_7_0,
+            "7.1" => Version_7_0,
           }

           if @@version.start_with?("4.2.14")

References

查看 linux 安装时间

想要评估一下自己当前使用的 linux 工作环境已经持续多久,询问 claude3.5 得到了几个方法:

ai 的答案

要查看您的 Arch Linux 安装时间,您可以尝试以下几种方法:

  1. 查看根文件系统的创建时间: 打开终端,输入以下命令:

    stat /

    在输出中查找”Birth”或”创建时间”这一行,它通常表示系统的安装时间。

  2. 检查最早的日志文件: 使用以下命令查看最早的系统日志文件的时间戳:

    ls -lct /var/log | tail -1
  3. 查看安装包数据库的修改时间: 运行以下命令:

    stat /var/lib/pacman/local

    查看”Modify”或”修改时间”这一行,它可能接近您的系统安装时间。

  4. 如果您使用systemd,可以尝试:

    sudo journalctl --list-boots

    这会显示系统启动的历史记录,最早的记录可能接近安装时间。

请注意,这些方法可能不会给出精确的安装时间,但通常可以提供一个相当接近的估计。如果您在安装后立即更改了系统时间,这些方法的准确性可能会受到影响。

实际使用

实测有两个方法看起来比较靠谱,原理是查看根文件系统的创建时间,我后续虽然改动过其他分区,但是根一直没动过,应该比较准确:

➜  PentaCortex git:(test) cd
➜  ~ stat /                    
  文件:/
  大小:4096            块:8          IO 块大小:4096   目录
设备:259,2     Inode: 2           硬链接:20
权限:(0755/drwxr-xr-x)  Uid: (    0/    root)   Gid: (    0/    root)
访问时间:2024-10-12 14:32:19.003665547 +0800
修改时间:2024-09-05 16:06:53.850059764 +0800
变更时间:2024-09-05 16:06:53.850059764 +0800
创建时间:2024-02-16 11:43:29.000000000 +0800
➜  ~ stat /var/lib/pacman/local
  文件:/var/lib/pacman/local
  大小:131072          块:264        IO 块大小:4096   目录
设备:259,2     Inode: 559536      硬链接:2119
权限:(0755/drwxr-xr-x)  Uid: (    0/    root)   Gid: (    0/    root)
访问时间:2024-10-14 10:23:22.640397815 +0800
修改时间:2024-10-14 10:23:19.712278043 +0800
变更时间:2024-10-14 10:23:19.712278043 +0800
创建时间:2024-02-16 12:06:46.299561805 +0800
➜  ~ neofetch
                   -`                    songtianlun@srd-songtianlun-archlinux 
                  .o+`                   ------------------------------------- 
                 `ooo/                   OS: Arch Linux x86_64 
                `+oooo:                  Host: ASUS Zenbook 14 UX3405MA_UX3405MA 1.0 
               `+oooooo:                 Kernel: 6.11.2-zen1-1-zen 
               -+oooooo+:                Uptime: 2 days, 18 hours, 14 mins 
             `/:-:++oooo+:               Packages: 2118 (pacman), 9 (flatpak) 
            `/++++/+++++++:              Shell: zsh 5.9 
           `/++++++++++++++:             Resolution: 1920x1080 
          `/+++ooooooooooooo/`           DE: Plasma 6.2.0 
         ./ooosssso++osssssso+`          WM: kwin 
        .oossssso-````/ossssss+`         Theme: Breeze [GTK2/3] 
       -osssssso.      :ssssssso.        Icons: breeze [GTK2/3] 
      :osssssss/        osssso+++.       Terminal: konsole 
     /ossssssss/        +ssssooo/-       Terminal Font: SauceCodePro Nerd Font Mono 12 
   `/ossssso+/:-        -:/+osssso+-     CPU: Intel Ultra 7 155H (22) @ 4.500GHz 
  `+sso+:-`                 `.-/+oso:    GPU: Intel Arc Graphics] 
 `++:.                           `-/+/   Memory: 19381MiB / 31455MiB 
 .`                                 `/

安装时间大概是今年二月份,当前已经完全在日常工作环境使用八个月,目前感觉良好。

《解密》

解密

《解密(陈思诚导演,刘昊然主演电影同步上映中)》

麦家 66个笔记

02

◆ 牛顿数学桥是剑桥大学城里的一大景观,全桥由7177根大小不一的木头衔接而成,有10299个接口,如果以一个接口用一枚铁钉来计算,那么至少需要10299枚铁钉。但牛顿把所有铁钉都倒进了河里,整座桥没用一枚铁钉,这就是数学的奇妙。

◆ 由著名数学家佩德罗·爱默博士担任主席的牛顿数学桥评审委员会为此作出承诺,谁只要在此基数上再减少铁钉数量,哪怕只少一枚,就能直接荣获剑桥大学数学博士学位。表妹后来就是这样得到剑桥数学博士学位的,因为她设计的数学桥只用了388枚铁钉

◆ 容算盘·黎黎即为表妹的洋名字,在容家族谱上,她的名字叫容幼英,系容家第八代后人。而那两位把她从剑桥大学请走的人,就是人类飞机史上的第一人:莱特兄弟。

◆ 一九四三年十月的一天,日本鬼子把战火烧进N大学校园,佩德罗·爱默博士赠送的稀世之宝——牛顿数学桥250∶1模型,毁于一场野蛮又愚蠢的大火中,而桥的设计主人早在二十九年前,也就是佩德罗·爱默博士访问N大学的次年,便已辞别人世,终年不到四十岁

01

◆ 在面临弃与不弃的重要关头,是小东西和他祖母的那点宿命的挂相保救了他,把他留在了容家深宅里。

02

◆ 小黎黎合起书看了看封面,居然是一册英文版的《大不列颠百科全书》。

◆ 你老是不开口,难道真是哑巴?”小黎黎说,声音里带点儿指责的意思,“如果是的就跟我再点个头,如果不是就对我开口说话。”为了怕他听不懂国语,小黎黎还用英语重复了这段话。

04

◆ 马是把世界变小的,船是把世界变大的,汽车则把世界变成了魔术

◆ 男人女相,连鬼都怕。意思是男人生女相,既阳又阴,阴阳相济,刚中带柔,极易造就一个男人变龙成虎,做人上人。因此,民间派生出各式各样指望阴阳相济的方式方法,包括取名字,有些望子成龙的父亲刻意给儿子取女人名,以期造就一个大男人。

◆ 因为只有一只手,程在当老师期间就被人叫做一把手,如今当了校长,可谓是名副其实的一把手了

05

◆ 小黎黎说:“据我所知,精确地计算,地球围绕太阳转一圈的时间应该是365天零5小时48分46秒,为什么要有闰年?就因为这个原因

◆ 一般上几万的数字,计算允许的误差标准是千分之一,超过了千分之一,可以确定你是算错了,否则就该属于合理的误差

◆ 在此基础上,他又无师自通地摸索出等差数列求和的演算公式,即:X=[(第1项数值+最后一项数值)×项数]/2[1]换句话说,等于是他发明了这个公

◆ 小黎黎认为,像他这样对未知世界有强烈探索精神的人,更需要一步步深入地学,通晓知识,免得日后把才华荒唐地浪费在已知领域里。

06

◆ N大学的数学系一向是好名在外的,曾经有数学家摇篮之称。据说,十五年前,C市文艺界的一位大红人在沿海受到某些地域上的奚落时,曾语出惊人,说:“我们C市再落魄嘛,起码还有一所了不起的N大学,即使N大学也落魄了,起码还有一个数学系,那是世界顶尖级的,难道你们也奚落得了?”

◆ 突然,希伊斯惊叫道:“嗬——!我看出来了,你是大楼前那尊塑像的后代,那个女黎黎的后代,容算盘·黎黎的后代!告诉我,你是她的后代吗?是儿子还是孙子?”

07

◆ 原来希伊斯这次回欧洲,为自己这些年学术上的碌碌无为深感失落,受了刺激,也受了启发,带回来了一个宏大的科研计划,决定要研究人的大脑内部结构。现在我们讲人工智能似乎一点也不新奇,都知道,但当时人类第一台计算机才诞生不久[插图],他就敏感这一点,应该说意识是相当超前的。与他宏大的科研计划相比,他带的书又似乎是少了,恕不外借也就不难理解了

◆ 不解实情的人就说洋教授是想利用珍弟的才智为自己搞研究。你知道,这种说法是最容易在校园里盛传开来的,因为是揭人的短嘛,说的人痛快,听的人过瘾,就是这样的。我听了,还曾为此专门问过珍弟,他矢口否认。后来我父亲又问他,他也说是没有的事。

08

◆ 有原子弹之父之称的美国科学家兼实业家罗伯特·奥本海默曾说过:在所有科学中,时间是真正的难题;在一个无限的时间内,所有的人将发现世上所有的秘密

09

◆ 我尚有的半辈子来赌一赌解破人脑奥秘科学,殊不知,赌局刚摆开就不得不放弃。为什么放弃这是我的秘密,总的说我不是由于困难和害怕放弃的,而是出于族人(犹太人)的殷切愿望

◆ 不用说,这些年我一直在为我的同胞干着一件非常紧要又秘密的事情,他们的困难和愿望感动了我,让我放弃了理想。如果您对此有尝试的兴趣,这就是我说这么多的目的了

10

◆ 原来珍弟确定的论文选题内容是建立在世界著名数学家格·伟纳科的数字双向理论基础上的,从选题学术性上讲,可以说是对数字双向理论的模拟证明。而伟纳科当时是科学界出名的反共分子,据说他门前贴有一张纸条,上面写着:亲随共产主义者不得入内

◆ 较好地阐述了关于研制人造大脑的症结——人大脑拥有的模糊意识。模糊就是不清晰,就是无法全知,也就是无法再造。所以,他提出,在现有程式下,人脑难有彻底再造的乐观前程,只能是尽量接近而已。

◆ 对付魔鬼的最好办法,是让我们挑战魔鬼,让魔鬼看到我们的力量。伟纳科是科学圣殿中的魔鬼,长期以来作威作福,贻害甚深,亟待我们来清算他。这是一篇清算伟纳科谬论的檄文,声音虽然模糊了些,但可抛砖引玉。

◆ 这在当时可以说是给论文画了一个化险的符,也等于给它签发了一本问世的通行证。

◆ 三项决定是:一 同意父亲辞去校长职务;二 国家将拨专项资金,在N大学数学系设立电子计算机研究课题组;三 课题组筹建工作由父亲负责。

◆ 从学术开始,以仕途结束,这是中国知识分子的毛病之一,现在老人突然想治治自己的毛病呢,是悲是喜,看来只有让时间回答

◆ 毕竟搞人造电脑不像生个人脑,人类似乎只要让某个男人和某个女人恰到好处地睡上一觉,某个人脑就会像树一样长出来

03

◆ 在老夫人心里,送行饭起码要达到如下四项特殊要求:1.主食必须是一碗面食,取的是长寿平安的意思。2.面又必须是荞麦面;荞麦面比一般面要柔韧,意思是一个人在外要能屈能伸。3.调味时必须要加酸醋、辣椒和桃仁;桃仁是苦的,意思是酸甜苦辣味,其中酸、苦、辣三味都留在了家里,出去就只有甜了。4.数量上宁少毋多,因为到时必须金珍吃得滴水不剩的,以象征圆圆满满。

◆ 这是一九五六年六月十一日凌晨五点多钟,就是从这一刻起,几乎像一棵树又像一个传说一样在N大学校园里既沉静又喧嚣地度过十余年的数学天才金珍,即将踏上神秘的不归路

◆ 以后,人们只知道他待在某一个地方,这地方的通信地址是——本市三十六号信箱。仿佛很近,就在身边。可实际上无人知晓这究竟是个什么地方——

◆ 曾问过几个在邮局工作的学生,本市三十六号信箱是个什么单位、在哪里,得到的答复都是不知道,好像这是地球以外的一个地址。开始我们都以为这地方就在本市,但当我们收到珍弟第一封来信时,信在路上走的时间告诉我们,这不过是个掩人耳目的东西。他去的地方可能很远,甚至可能在很远的地方的地底下

◆ 他第一封信是走后第三天写的,我们是在第十二天收到的

◆ 是珍弟走的当年冬天,十二月份,有天晚上,外面刮着大风,天气骤然降温,吃饭的时候,父亲突然觉得有点头痛,都以为是着凉引起的,所以他吃了几片阿司匹林后,便早早上楼去休息了。没几个小时,等母亲上床去休息时,发现父亲身上还是热乎的,但人已没了气息。父亲就这样去世了,好像睡前吃的几片药是毒药,好像父亲知道没有珍弟他的课题研究注定要流产,所以就干净利索地结束了自己。当然,事实不是这样的,是脑溢血夺走了父亲的生命。

◆ 珍弟走后第三天,一个曾多次代表珍弟单位来我家表示节日慰问的人,给我们送来一份由当时省军区和省革委会联合下发的大红头文件,内容是说:容金珍是受党中央、国务院、中央军委表彰的革命英雄,其家庭是革命之家、光荣之家,任何单位、组织和个人不得擅自入内,更不能以任何名义对英雄亲人采取错误的革命行为等。上面还有一手批示——违者一律以反革命处置!是当时省军区司令员亲笔签署的。这不啻是一把尚方宝剑,正是靠着它,我们家后来再没有遇到任何麻烦,包括我哥,先是靠它调回到N大学,后来他决定出国,也是靠它才出去成的。我哥是搞超导研究的,当时在国内哪有条件?只好出去,可你想想,那个时候要出国有多难。从某种意义上说,在那个特殊的年代,是珍弟给我们提供并创造了正常甚至是理想的生活和工作环境

04

◆ 跟容先生一样,郑瘸子是我完成这个故事的一个重要人物,我在采访容先生之前就曾采访过他,并与他建立了十分友好的关系。那时候,他已经六十多岁,皮肉上的疏松已经不可避免地渗透到骨头里,所以跛足也不可避免地变得更跛,再不可能凭借一两个鞋后跟来解决问题,只好拄起了拐杖。正如有人说的,他拄拐杖的样子显得很威严,不过我想,威严也许不是来自拐杖,而是来自他的头衔。我结识他时,他是特别单位701的头号人物,一局之长。人到这份上,瘸子自然是没人敢喊了,即使他要你喊你都不敢,再说人到这份上,有官衔,又有年纪,可以称呼的称呼也多了。

◆ 我看不见得!难道你觉得靠一颗原子弹可以打赢一场战争吗?而靠容金珍我们几乎可以打赢每一场战争。原子弹是象征我们国力的,是插上鲜花给人看的,而容金珍干的事是看别人,是从风中听人的心跳声,看人家深藏的秘密。只有知彼知己,方能百战不殆,所以,依我看,从军事的角度说,容金珍干的事比造原子弹还要有实际意义。”容金珍干的事是破译密码——

◆ 破译事业是一位天才努力揣摩另一位天才的心的事业,是男子汉的最最高级的厮杀和搏斗。这桩神秘又阴暗的勾当,把人类众多的精英纠集在一起,为的不是什么,而只是为了猜想由几个简单的阿拉伯数字演绎的秘密。这听来似乎很好玩,像出游戏,然而人类众多精英却被这场游戏折磨得死去活来。

◆ 破密家的悲哀也在于此!在人类历史上,葬送于破译界的天才无疑是最多的。换句话说,能够把一个个甚至一代代天才埋葬掉的,世上大概也只有该死的密码了,它把人类大批精英圈在一起似乎不是要使用他们的天才,而只是想叫他们活活憋死,悄悄埋葬。所以,难怪人们都说破译事业是人类最残酷的事业

07

◆ 密码的本质是反科学、反文明的,是人类毒杀科学和科学家的阴谋和陷阱。这里面需要智慧,但却是魔鬼的智慧,只会使人类变得更加奸诈、邪恶;这里面充满挑战,但却是无聊的挑战,对人类进步一无是处。

◆ 如果实在无法回头,那么金珍,我亲爱的金珍,请无论如何记着我说的,在你们试图破译的多部密码中,你可以选择任何一部,但决不能选择X国的紫密

◆ 紫密是当时701面临的一种最为高级的密码,有种未经证实的说法,说紫密是某宗教团体用重金加上黑社会的手段,引诱加威胁地强迫一位科学家研制的,但研制成功后,由于它设置的机关太多,难度太大,密中有密,错综复杂,深不见底,以致主人根本无力使用,最后才转卖给X国,成了X国军方目前使用的顶级密码,也是701当前最渴望破译的一部密码。

◆ 事实上,棋疯子正是因为破译紫密而被逼疯的,换句话说,棋疯子就是被制造紫密的那位未名科学家逼疯的。而没逼疯的也不是因为他们的精神有多强大,而是因为胆怯、聪明,连碰都不去碰它——紫密!聪明让他们预先知道碰它的结果,所以不碰它显然再次证明他们是聪明的。这是一个陷阱、黑洞,聪明的人躲开了它,勇敢的人疯了,疯了的人让人们更加敬畏它,回避它,躲开它。这就是701破译紫密的现状,令人心急如焚,却又百般无奈。

◆ 现在——事实证明,这只大头大脑的癞蛤蟆不但具有天才的才能,还有天才的运气。星辰之外的运气。祖坟青烟直冒的运气。

08

◆ 通过每张图表简洁的中文注解,我马上明白,这些图表其实是《世界密码史》的重写,然而要没有这些注解,我是怎么也看不出究竟的。《世界密码史》是一套洋洋三百万字的巨书,他能够如此简洁地提拎出来,而且是采用这种特殊的数列方式,这首先强烈地震惊了我。好像一具人体,能够剔除皮肉以其骨架的形式传真已是一个天才的作为,而他根本不要骨架,只掰了一截手指骨。你想想,以一截手指骨就将一个人体活脱脱地展现出来,这是一种什么样的能力!

◆ 说真的,容金珍确实是个天才,他身上有很多我们不能想象的东西,他可以几个月甚至一年时间不跟任何人说一句话,把沉默当做饭一样吃,而当他开口时,一句话又很可能把你一辈子的话都说尽了

◆ 他说,我相信世上密码与一具生命是一样的,活着的,一代密码与另一代密码丝丝相联,同一时代的各部密码又幽幽呼应,我们要解破今天的哪本密码,谜底很可能就藏在前人的某本密码中。

◆ 听了他的两条线之理论后,我没有理所应当地去驳斥他,而是默默地生出了几分敬佩,且隐隐嫉恨,因为他显然站到我前面去了

◆ 完全可以这么说,在众多史林中密码史无疑是最沉默、最冷清的,那里面无人问津,那里面无人敢问津!破译家的悲哀正是因此而生,他们失去了历史这面镜子,失去了从同仁成果中吸取养料的天律。他们的事业是那么艰难深奥,而他们的心灵又是那么孤独无伴,前辈之身躯难以成为他们高站的台阶,却常常变成一道紧闭的门,吃人的陷阱,迫使他们绕道而行,另辟蹊径。依我看,世上没有哪项事业需要像密码一样割裂历史,反叛历史。历史成了后来者的包袱和困难,这是多么残酷,多么无情。所以,葬送于密码界的天才往往是科学界最多的,葬送率之高令人扼腕悲号啊!

01

◆ 荣誉和职业已使他变得如玻璃似的透明、易碎,这是没有办法的,而他自己又把这种感觉无限地扩大、细致,那就更没法了

02

◆ 什么叫不虚此行?有了这些东西就叫不虚此行

04

◆ 直接投入破案人员有3700多人,其中包括容金珍和瓦西里。直接被查询人员有2141位乘客、43名列车工作人员和B市600多名着军便装的小伙子。火车因此延误时间5小时30分钟。B市秘密管制时间484小时,即20天零4小时。人们说,这是G省历史上从未有过的一个巨大而神秘的案子,几万人为之惊动,几个城市为之颤抖,其规模和深度实为前所未有!

03

◆ 前面说过,密码界不允许出现两个相似的心灵,相似的心灵是一堆垃圾。因此,密码界还有一条不成文的规定,简直是铁律:一个人只能制造或破译一本密码!因为制造或破译了一本密码的人,他的心灵已被他自己的过去吸住,那么这心灵也等于被抛弃了。由此,从原则上说,容金珍后来是不应该再去承担破译黑密的任务的,因为他的心灵已属于紫密,若要再破黑密,除非他将心灵粉碎了重新再铸。

04

◆ 4.这问题[插图]你自己去想,我回答不了。总的说,希(伊斯)是个科学家,政治上很幼稚,所以很容易被伤害,也很容易被利用。而你刚才说的有些东西(指希伊斯激烈的反共行为)是子虚乌有的,我敢说没这样的事!

05

◆ “所有从事破译工作的人,命运中和棋类游戏都有着一种天然的联系,尤其是那些平庸之辈,最后无一例外地都会迷恋于棋术,就好比有些海盗、毒枭,晚年会亲近于慈善事业一样。”

06

◆ 还有一个怪异,我不知你能否理解,就是:黑密作为一本高级密码,当时启用三年我们却逮不到它一丝差错,就像一个正常人模仿一个疯人讲疯话,三年滴水不漏,不显真迹,这种现象在密码史上极为少见。对此容金珍很早就曾同我们探讨过,认为这很不正常,再三提出质疑,甚至怀疑黑密就是过去某部密码的抄袭。因为只有经过使用,也就是经过修改的密码,才可能如此完美,否则除非造密者是个天神,是个我们不能想象的大天才。

◆ 你可以想象,这样下去,我顶多成为一个走出九十九步的容金珍,那最后一步将永远埋在黑暗里。时间也许可以让容金珍走出最后一步,而我却不能,因为我刚才说过,我只是趴在他身上的一个孩童,现在他倒下了,我自然也跟着倒下了。这时候,我才发现,容金珍留给我笔记本,其实是给了我一个悲哀,它让我站到胜利的前沿,胜利的光辉依稀可见,却永远无法触摸、抓到。这是多么可悲可怜!我对自己当时的处境充满恐慌和无奈。

◆ 说真的,谁想得到,就是这样一位天才人物,一个如此强大而可怕的人(笔记本使我深感容金珍的强大和可怕),一个有着如此高度和深度的人,人类的精英,破译界的英雄,最后竟然被一个街头小偷无意间地轻轻一击,就击得粉碎。这使我感到神秘的荒唐,而且这种荒唐非常震惊我

◆ 最后,老人还告诉我:对方所以制造黑密这部没有密锁的密码,是因为他们从紫密被破译的悲惨命运中已看到了自己所处的绝境。他们知道,一次交锋已使他们深悉容金珍的天才和神奇,若是一味追求正面交锋,肯定必死无疑,于是便冒天下之大不韪,疯狂地使出了这生僻、怪诞的毒招。

◆ :容金珍通过自己的灾难——这种神奇又神奇的方式,向他的同仁显示黑密怪诞的奥秘,这是人类破译史上绝无仅有的一笔!

03

◆ 洋先生的死亡是从喉咙开始的,也许是对他一生热衷于圆梦事业的报复吧,总的说,他的一生得益于巧舌如簧的嘴巴,也祸害于这张游说于阴阳间的乌鸦嘴。在给小黎黎酝酿遗书之前,他基本上已经失声无语,这也使他预感到死期的来临,所以才张罗起大头虫的前程后事

◆ 因为只有一只眼,腿脚又不灵便,每天在枯坐静坐中度过,渐渐地他不可避免地有了便秘的忧患,严重时令他徒有生不如死的感觉。那年入冬,便秘的毛病又发作了,他沿用往常的办法,早晨醒来后猛灌一大碗生冷的凉开水,然后又接连地灌,企盼迎来一场必要的肠绞腹痛。但这次便秘似乎有些顽固,几天过去,凉开水下去一杯又一杯,肚子里却迟迟不见反应,静若止水的,令他深感痛苦和绝望。这天晚上,他从镇上拣草药回来,趁着黑就把出门前备好的一碗凉水一饮而尽。因为喝得快,到最后他才觉出这水的味道有些异怪,同时还有一大把烂东西随水一道冲入胃肚里,叫他顿生蹊跷。点了油灯看,才发现碗里堆满被水泡活的干梨花,不知是风吹落进去的,还是耗子捣的乱。之前,他还没听说这干梨花是可以饮用的,他忐忑不安地等待着由此可能引发的种种下场,甚至连死的准备也作好了。但是不等他把第一道草药水熬出来,他就感到小腹隐隐地生痛,继而是一种他梦寐以求的绞痛。他知道,好事情来了,在一阵激烈的连环响屁后,他去了茅房,出来时人已备感轻松。

◆ 以往,轻松之时也是肠炎的开始之刻,便秘通畅后,往往要闹上一两天的腹泻,有点物极必反的意思。而这次却神秘地走出了怪圈,通了就通了,没有派生任何不适或不正常的症状,神秘之余,梨花水的形象在他心中亲热地凸现出

◆ 不用说,他表明的神秘的·法演算式实际就是乘法,只不过他不知道而

◆ 然后还有一页草稿纸,上面的演算很乱,但老爷一看就明白他这是在推敲、总结乘法规律。规律最后被清清楚楚地列在这页纸的下端,老爷看着,嘴里不禁跟着念出声来——一一得一

第四篇 再转

◆ 从某种意义上说,一个人的智力范围越是局限,那么他在某一方面的智力就越容易接近无限。换言之,天才之所以成为天才,是因为他们一方面将自己无限地拉长,拉得细长细长,游丝一般,呈透明之状,经不起磕碰。所以,大凡天才都是娇气的,如世上所有珍宝一样。

— 来自微信读书

《Helm学习指南:Kubernetes上的应用程序管理》

阅读感悟

暂略

阅读摘录

《Helm学习指南:Kubernetes上的应用程序管理》

马特·布彻 马特·法里纳 乔什·多利茨基 32个笔记

1.1 云原生生态系统

◆ 有一项关键的技术提供了移动容器镜像的能力,即镜像登记站(image registry),这是一种专门的块存储技术,它容纳容器,使其可供主机使用。主机可以将容器镜像推送(push)到登记站,该动作会将各层传输到登记站。然后另一台主机可以将镜像从登记站拉取(pull)到该主机的环境中,如此一来该主机就可以执行此容器了。

◆ 。组合这些的标准格式是name:tag@digest,其中只有name是必需的。

◆ 2015年,时机已经成熟:Docker容器正在向企业进军。显然,此时需要一种工具来管理跨主机的容器调度和资源管理。多种技术相继登场:Mesos引入了Marathon;Docker创建了Swarm;Hashicorp发布了Nomad;Google创建了其内部Borg平台的开源兄弟,并将这项技术命名为Kubernetes(希腊语中的船长一词)。

◆ 每一个调度器都有其优点和缺点。但是Kubernetes引入了两个概念,使它与众不同:声明性基础设施(declarative infrastructure)和协调循环(reconciliation loop)。

◆ 在Kubernetes上安装一个容器更像是在说,“我希望这个容器在这个端口上运行,使用一定量的CPU并在文件系统的这个位置上安装一些存储”。Kubernetes在后台工作,根据我们对所需内容的声明来连接所有内容。

◆ 在协调循环中,调度程序说:“这是用户所需的状态。以下是当前状态。它们不一样,所以我将采取步骤来协调它们。”用户希望为容器提供存储空间。当前没有附加存储。因此Kubernetes创建了一个存储单元并将其附加到容器中。容器需要公共网络地址。现在也不存在。所以一个新的地址被附加到容器上。Kubernetes中的不同子系统开展工作以实现用户对所需状态的整体声明的各个部分。最终,Kubernetes要么成功地创建了用户想要的环境,要么得出了无法实现用户需求的结论。同时,用户只能被动地观察Kubernetes集群并等待它成功完成或将安装标记为失败。

◆ 一般一个pod只有一个容器。但有时有一些用于为主容器做预配置并在主容器联机之前退出的容器,这些被称为初始化容器(init container)。另外有一些与主容器同时运行并提供辅助服务的容器,这些被称为边车容器(sidecar container)。这些都被认为是同一个pod的一部分。

◆ 在前面的代码中,我们编写了Kubernetes Pod资源的定义。当用YAML或JSON表示时,这些定义称为清单(manifest)

◆ Secret在结构上类似于ConfigMap,只是data部分中的值必须是Base64编码的。

◆ Deployment由一些顶级配置数据以及构建副本pod的模板组成。

◆ Service是一种持久的网络资源(有点像静态IP),即使连接到它的一个或多个pod消失,它也会持久存在。这样,Kubernetes Pod可以来去自如,而网络层可以继续将流量路由到同一Service端点。

◆ 虽然Service是一个抽象的Kubernetes概念,但在幕后它可以实现为从路由规则到外部负载均衡器的任何东西

1.2 Helm的目标

◆ YAML。Helm的核心思想是,所有这些对象都可以打包在一起进行安装、更新和删除

◆ Kubernetes就像一个操作系统。在它的基础上,操作系统提供了执行程序的环境。它提供了存储、执行和监视程序生命周期所需的工具

◆ 它不执行程序,而是执行容器。但与操作系统类似,它提供了存储、执行和监视这些容器所需的工具

◆ 当我们将Kubernetes设想为一个操作系统时,很快就看到了对Kubernetes软件包管理器的需求

◆ 我们最初借鉴Homebrew(macOS的软件包管理器)和Apt(Debian的软件包管理器)对Helm进行设计。但随着Helm的成熟,我们已经尽可能多地借鉴不同的软件包管理器。

◆ 典型的操作系统和Kubernetes之间有一些区别。其中之一是Kubernetes支持运行同一应用程序的多个实例。

◆ 另一个在典型操作系统中很少见的概念是命名空间(namespace),但它是Kubernetes的核心。

◆ 这些只是Kubernetes与传统操作系统不同的几个方面。这些差异和其他差异对Helm的设计提出了挑战。我们不得不构建Helm来充分利用这些差异,但同时又不放弃关于我们的软件包管理比喻。

◆ 例如,Helm安装命令不仅需要软件包的名称,还需要用户提供的名称,通过用户提供的该名称可以引用该软件包的已安装版本

3.1 模板和试运行

◆ 换句话说,–set值覆盖传入的值文件中的设置,而传入的值文件又覆盖chart的默认values.yaml文件中的任何内容。

◆ helm install和helm upgrade等命令提供了一个名为–dry-run的标志。当在命令行中添加此标志时,将导致Helm逐步完成前四个阶段(加载chart、确定值、渲染模板、格式化为YAML)。但是当第四阶段结束时,Helm会将大量信息转储到标准输出,包括所有渲染的模板。然后它将退出,而不将对象发送给Kubernetes,也不创建任何发布记录。

◆ –dry-run标志的主要目的是让人们有机会在将输出发送到Kubernetes之前检查和调试输出

◆ 但在它被引入后不久,Helm维护人员就注意到了用户中的一种趋势:人们希望使用–dry-run将Helm用作模板引擎,然后使用其他工具(如kubectl)将渲染的输出发送到Kubernetes。但是编写–dry-run时没有考虑到这个用例,这导致了一些问题:1.–dry-run将非YAML信息与渲染的模板混合。这意味着在将数据发送到kubectl等工具之前,必须对其进行清理。2.–dry-run在升级时可能会产生与其安装时不同的YAML输出,这可能会让人困惑。3.它会联系Kubernetes API服务器进行验证,这意味着Helm必须拥有Kubernetes凭据,即使它只是用来试运行一个发行版本。4.它还将特定于集群的信息插入模板引擎。因此,某些渲染过程的输出可能是特定于集群的。为了解决这些问题,Helm维护人员引入了一个完全独立的命令:helm template。

◆ 虽然–dry-run是为调试而设计的,但helm template是为了将Helm的模板渲染过程与安装或升级逻辑隔离开来。

◆ 之前,我们研究了Helm安装或升级的5个阶段。template命令执行前4个阶段(加载chart、解析值、渲染模板、格式化为YAML)。

◆ ·在helm template执行期间,Helm从不联系远程Kubernetes服务器。·template命令的作用始终类似于安装。·通常需要联系Kubernetes服务器的模板函数和指令将只返回默认数据。·chart只能访问默认的Kubernetes类型。

3.2 了解发布版本信息

◆ 的5个Helm安装阶段:1.加载chart。2.解析值。3.执行模板。4.渲染YAML。5.把它发送到Kubernetes。

◆ 在最后一个阶段,Helm将数据发送给Kubernetes。然后二者“来回沟通”,直到发布版本被接受或拒绝。

3.3 历史记录和回滚

◆ 看到helm uninstall命令有一个名为–keep history的标志。通常,删除事件将销毁与该安装相关联的所有发布记录。但是当指定–keep history时,即使删除了安装,你也可以看到它的历史记录

3.4 深入了解安装和升级

◆ 使用–generate name标志,我们不再需要提供名称作为helm install的第一个参数。Helm根据chart名称和时间戳的组合生成名称

— 来自微信读书

《大话设计模式》

阅读感悟

暂略

摘录笔记

《大话设计模式》

 程杰

 225个笔记

 前言

  • [插图]本书希望能给渴望了解OO世界的初学者、困惑于僵硬、脆弱、无法复用的代码编程体验者、一直打着OO编程的旗号,做着过程式开发的基于对象的编程实践者一些好的建议和提示。

 本书起因

  • 技术课的教学同样如此,除非学生是抱着极大的学习动机来参与其中,否则照本宣科的教学、枯燥乏味的讲解,学生一定会被庞杂的概念和复杂的逻辑搅晕了头脑,致使效果大打折扣。

 本书读者

  • GoF的《设计模式》好比是世界顶级足球射门集锦,《重构》、《敏捷软件开发》、《设计模式解析》好比是一场场最精彩的足球比赛。
  • 可是我并不只是想做一个球迷(软件使用者),而是更希望自己能成为一个足球运动员(软件设计编程者),能够亲自上场比赛,并且最终能成为球星(软件架构师)
  • 本书显然不是培养足球明星(软件架构师)的俱乐部,而是训练足球基本功的学校,培训的是初学足球的小球员(面向对象的程序员),本书希望的是读者阅读后可以打好面向对象的基础,从而更加容易并深入的去理解和感受GoF的《设计模式》以及其他大师作品的魅力。

 本书研读方法

 关于本书学习的疑问解答

  • 设计模式有四境界:1.没学前是一点不懂,根本想不到用设计模式,设计的代码很糟糕;2.学了几个模式后,很开心,于是到处想着要用自己学过的模式,于是时常造成误用模式而不自知;3.学完全部模式时,感觉诸多模式极其相似,无法分清模式之间的差异,有困惑,但深知误用之害,应用之时有所犹豫;4.灵活应用模式,甚至不应用具体的某种模式也能设计出非常优秀的代码,以达到无剑胜有剑的境界。

 不是一个人在战斗

  • 本书起源于本人在“博客园”网站的博客http://cj723.cnblogs.com/中的一个连载文章《小菜编程成长记》。
  • 写作过程中,本人还参考了http://www.dofactory.com/关于23个设计模式的讲解,并引用了他们的结构图和基本代码

 1.5 活字印刷,面向对象

  • “第一,要改,只需更改要改之字,此为可维护;第二,这些字并非用完这次就无用,完全可以在后来的印刷中重复使用,此乃可复用;第三,此诗若要加字,只需另刻字加入即可,这是可扩展;第四,字的排列其实可能是竖排可能是横排,此时只需将活字移动就可做到满足排列需求,此是灵活性好。”

 1.6 面向对象的好处

  • 是呀是呀,你说得没错,中国古代的四大发明,另三种应该都是科技的进步,伟大的创造或发现。而唯有活字印刷,实在是思想的成功,面向对象的胜利。

 1.11 UML类图

  • 类图分三层,第一层显示类的名称,如果是抽象类,则就用斜体显示。第二层是类的特性,通常就是字段和属性。第三层是类的操作,通常是方法或行为。注意前面的符号,‘+’表示public,‘-’表示private,‘#’表示protected。”
  • 它表示一个接口图,与类图的区别主要是顶端有\<\>显示。第一行是接口名称,第二行是接口方法
  • 接口还有另一种表示方法,俗称棒棒糖表示法
  • 继承关系用空心三角形+实线来表示。”
  • 实现接口用空心三角形+虚线来表示
  • 当一个类‘知道’另一个类时,可以用关联(association)。
  • 聚合表示一种弱的‘拥有’关系,体现的是A对象可以包含B对象,但B对象不是A对象的一部分[DPE](DPE表示此句摘自《设计模式》(第2版)
  • 聚合关系用空心的菱形+实线箭头来表示
  • 合成(Composition,也有翻译成‘组合’的)是一种强的‘拥有’关系,体现了严格的部分和整体的关系,部分和整体的生命周期一样[DPE]。
  • 合成关系用实心的菱形+实线箭头来表示
  • 依赖关系(Dependency),用虚线箭头来表示。”

 2.3 简单工厂实现

  • 面向对象的编程,并不是类越多越好,类的划分是为了封装,但分类的基础是抽象,具有相同属性和功能的对象的抽象集合才是类

 2.4 策略模式

  • 策略模式定义了算法家族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化,不会影响到使用算法的客户
  • 封装变化点是我们面向对象的一种很重要的思维方式

 2.6 策略与简单工厂结合

  • 你的意思是说,简单工厂模式我需要让客户端认识两个类, CashSuper和CashFactory,而策略模式与简单工厂结合的用法,客户端就只需要认识一个类CashContext就可以了。耦合更加降低。”

 2.7 策略模式解析

  • 策略模式是一种定义一系列算法的方法,从概念上来看,所有这些算法完成的都是相同的工作,只是实现不同,它可以以相同的方式调用所有的算法,减少了各种算法类与使用算法类之间的耦合[DPE]
  • “当然。这个办法就是用到了反射技术,不是常有人讲,‘反射反射,程序员的快乐’,不过今天就不讲了,以后会再提它的。”
  • (注:在抽象工厂模式章节有对反射的讲解)

 3.4 单一职责原则

  • 就一个类而言,应该仅有一个引起它变化的原因[ASD]

 3.5 方块游戏的设计

  • 如果一个类承担的职责过多,就等于把这些职责耦合在一起,一个职责的变化可能会削弱或者抑制这个类完成其他职责的能力。这种耦合会导致脆弱的设计,当变化发生时,设计会遭受到意想不到的破坏[ASD]
  • 软件设计真正要做的许多内容,就是发现职责并把那些职责相互分离[ASD]
  • 如果你能够想到多于一个的动机去改变一个类,那么这个类就具有多于一个的职责[ASD],就应该考虑类的职责分离。”

 4.2 开放-封闭原则

  • 开放-封闭原则,是说软件实体(类、模块、函数等等)应该可以扩展,但是不可修改

 4.3 何时应对变化

  • 开放-封闭原则的意思就是说,你设计的时候,时刻要考虑,尽量让这个类是足够好,写好了就不要去修改了,如果新需求来,我们增加一些类就完事了,原来的代码能不动则不动。
  • “在我们最初编写代码时,假设变化不会发生。当变化发生时,我们就创建抽象来隔离以后发生的同类变化[ASD]
  • 我们希望的是在开发工作展开不久就知道可能发生的变化。查明可能发生的变化所等待的时间越长,要创建正确的抽象就越困难[ASD]。
  • 开放-封闭原则是面向对象设计的核心所在。遵循这个原则可以带来面向对象技术所声称的巨大好处,也就是可维护、可扩展、可复用、灵活性好。开发人员应该仅对程序中呈现出频繁变化的那些部分做出抽象,然而,对于应用程序中的每个部分都刻意地进行抽象同样不是一个好主意。拒绝不成熟的抽象和抽象本身一样重要[ASD]。

 5.3 依赖倒转原则

  • 因为CPU的对外都是针脚式或触点式等标准的接口。啊,我明白了,这就是接口的最大好处。CPU只需要把接口定义好,内部再复杂我也不让外界知道,而主板只需要预留与CPU针脚的插槽就可以了。
  • 依赖倒转原则,原话解释是抽象不应该依赖细节,细节应该依赖于抽象,这话绕口,说白了,就是要针对接口编程,不要对实现编程
  • 高层模块不应该依赖低层模块。两个都应该依赖抽象
  • 抽象不应该依赖细节。细节应该依赖抽象
  • 比如我们做的项目大多要访问数据库,所以我们就把访问数据库的代码写成了函数,每次做新项目时就去调用这些函数。这也就叫做高层模块依赖低层模块。

 5.4 里氏代换原则

  • “里氏代换原则是Barbara Liskov女士在1988年发表的[ASD],具体的数学定义比较复杂,你可以查相关资料,它的白话翻译就是一个软件实体如果使用的是一个父类的话,那么一定适用于其子类,而且它察觉不出父类对象和子类对象的区别。也就是说,在软件里面,把父类都替换成它的子类,程序的行为没有变化,简单地说,子类型必须能够替换掉它们的父类型[ASD]。”
  • 里氏代换原则(LSP):子类型必须能够替换掉它们的父类型。[ASD]
  • 只有当子类可以替换掉父类,软件单位的功能不受到影响时,父类才能真正被复用,而子类也能够在父类的基础上增加新的行为。

[转译] 深思熟虑的编程练习

马尔科姆·格拉德威尔曾著名地宣称,掌握一门技艺需要 10,000 小时的深思熟虑的练习,彼得·诺维格在他的文章 Teach Yourself Programming In Ten Years 中引用了这一发现。程序员在工作 5.2 年,每天 8 小时,每年 48 周后将获得 10,000 小时的办公室时间。这并不意味着程序员在 5 或 6 年后就会成为专家,因为这 10,000 小时的办公室时间并不全是深思熟虑的练习。

深思熟虑的练习包括阅读书籍、学习新语言、参加 Udacity 课程或解决挑战性的问题,锻炼你的思维。花 3 小时在谷歌上搜索如何操作 Ruby Gem 的 DSL 并不算入你的 10,000 小时中。一些深思熟虑的练习发生在工作中,但大多数发生在深夜和周末。

如果一份工作的 40% 被视为深思熟虑的练习(这个估计对于大多数工作来说可能偏高),那么一个每天工作 8 小时、每年工作 48 周的程序员每年只会获得 768 小时的深思熟虑的练习,达到 10,000 小时的练习将需要 13 年。如果只有 20% 的工作被视为深思熟虑的练习(由于重复任务、会议等),那么将需要 26 年才能达到精通。

Hacker News 的评论者也迅速指出,有些人拥有 1 年的经验 10 次。第一年的工作是一个陡峭的学习曲线,几乎全是深思熟虑的练习,但随后的几年是重复的,因此没有额外的深思熟虑的练习。这些程序员从未达到精通,且 是无法编程的程序员。

深思熟虑的练习是从事一些超出你当前技能水平的工作(例如,如果你不理解递归,弄清楚如何递归地解决阶乘问题)。随着你当前技能水平的提高,你需要不断地从事更难的项目并挑战自己。那些有纪律、从事困难问题并花费大量时间编码的人,才会在这门技艺上达到精通。

我想象 20 年前的网页程序员会通过弄清楚如何做事情来获得 10,000 小时的深思熟虑的练习。如今的网页开发者可以访问强大的库,很多深思熟虑的练习都用于弄清楚现有解决方案的工作原理。以下是网页程序员在授权方面可能的进展:创建一个带有 CanCan 的 Rails 应用,从 RailsCast 学习如何从零开始进行授权,在 Rails 中创建自己的授权解决方案,将授权添加到你创建的网页开发框架中。这些网页开发者将不断深入,了解编程的本质(例如,Ruby 代码生成了什么 HTML,发出了什么 HTTP 请求,HTTP 是如何工作的……)。

我直到 27 岁才开始认真编程,28 岁时才找到编程工作,因此在成为专家程序员之前还有很多工作要做。我几乎每天都待到晚上 10 点,并试图在每个周末至少进行 8 小时的编程,以补充我在工作中获得的深思熟虑的练习。希望对这门技艺的专注能让我快速成为专家。

来源:Deliberate Programming Practice 作者: intelligentinvestingplan