# 3

1. CDN工作原理及其在淘宝图片业务中的应用

   <https://www.tuicool.com/wx/faq2Uvm>

   没想到图片业务能如此复杂，需要动态生成，控制缓存..
2. 快餐文分享:

   Defensive BASH Programming

   <https://kfirlavi.herokuapp.com/blog/2012/11/14/defensive-bash-programming/> 摘要: Here is my Katas for creating BASH programs that work. Nothing is new here, but from my experience pepole like to abuse BASH, forget computer science and create a [Big ball of mud](http://en.wikipedia.org/wiki/Big_ball_of_mud) from their programs. Here I provide methods to defend your programs from braking, and keep the code tidy and clean.

   由于 Shell 的糟糕设计, 作者提出了 防御性编程规范...
3. 每日一句分享:

   我们的计算机的知识就像一座金字塔，底层是数学，上面是数字电路，然后是汇编，再往上是操作系统、网络，数据库、高级编程语言、框架等等......

   我们每个人不可能精通这个金子塔的每一层， 但是要掌握、理解构成这个金字塔的核心概念。
4. ![image-20201203135444934](/files/-MPZDc3o-LYn2g3-KdGZ)
5. 计算机科学的先驱 Alan Perlis 给低层语言（low-level languages）下的定义是：

   > “A programming language is low level when its programs require attention to the irrelevant.” \[5]

   如果用一门语言编写的程序**需要处理不相关的东西**，那这就是一门低层语言。
6. 快餐文分享:

   Go-通道用例大全

   <https://gfw.go101.org/article/channel-use-cases.html>

   摘要: 文章详细地解释了通道类型和通道值，以及各种通道操作的规则细节。本文的目的是展示尽量多的通道用例。但是，我们应该知道通道并不是Go支持的唯一同步技术，并且通道并不是在任何情况下都是最佳的同步技术。

   这篇文章 我之前已经读过很多遍了，每次读完都有不同的感受，通过 channel 去模拟并发原语，并天然在语法层面上支持 coruntine，这就是 Golang 的设计魅力所在。
7. 分享一篇刚刚在 V社刷到的帖子：

   突然有点迷茫，关于学历的问题

   <https://v2ex.com/t/731679>

   我看了下这老哥的 Github，star 有 28k 多，可以说技术水平非常强了，并且有6年的工作经验，最近跳槽大厂时 还是因为 学历被卡了。哎，这也太难了。
8. 快餐文分享：

   ECMAScript 双月报告：TC39 11月会议提案进度汇总

   <https://mp.weixin.qq.com/s?__biz=MzI5NjM5NDQxMg==&mid=2247488302&idx=1&sn=6dd21d69db461379c0be9a50929b5b63>

   摘要：这次 TC39 会议是 2020 年度最后一次全员会议。这次会议中没有任何提案争取到从 Stage 2 进入 Stage 3 的共识，也没有提案从 Stage 3 进入 Stage 4。

   我喜欢 proposal-extensions 这个提案，现在的语言早就应该支持 Pointfree 特性了，就像管道似的\~
9. 分享一道面试题：

   ```typescript
   interface Logger {
     time: number;
     asyncLog:(msg: string) => Promise<string>;
     syncLog:(msg: string) => number;
   }

   type Translate<T> = /** 你需要实现的部分 **/;

   // 要求 Translate
   //  1. 提取出为函数类型的属性，丢弃掉其它类型的属性
   //  2. 将函数返回类型调整为形参类型(假定有且只有一个参数)

   // 实现效果如下:
   type T0 = Translate<Logger>;

   // 等价于
   type T0 = {
       // 其它属性被丢弃
       asyncLog: (arg: string) => string; 
       // return 类型被调整为跟 arg 保持一致
       syncLog: (arg: string) => string; 
       // return 类型被调整为跟 arg 保持一致
   }

   const result: T0 = {
       asyncLog(msg: string) { return msg }
   };
   ```

   1. 先实现一个类型可以提取出指定类型，用来筛选出所有为函数类型的属性

   ```typescript
   type FilterTypes<T, U> = {
       [Key in keyof T]: T[Key] extends U ? Key : never
   };

   // 看看阶段性成果
   type T = FilterTypes<Logger, Function>;
   // type T = {
   //     time: never;
   //     syncLog: "syncLog";
   //     asyncLog: "asyncLog";
   // }
   ```

   1. 在 1 的基础上剔除 `never`，取出所有 key

   ```typescript
   type FilterKeys<T, U> = FilterTypes<T, U>[keyof T];

   // 看看阶段性成果
   type T = FilterKeys<Logger, Function>;
   // type T = "syncLog" | "asyncLog"
   ```

   1. 在 2 的基础上我们可以使用 `Pick` 提取出子类型

   ```typescript
   type SubType<T, U> = Pick<T, FilterKeys<T, U>>;

   // 看看阶段性成果，此时我们已经成功提取出了所有类型为函数的属性，满足要求
   type T = SubType<Logger, Function>;
   // type T = {
   //     syncLog: (msg: string) => number;
   //     asyncLog: (msg: string) => Promise<string>;
   // }
   ```

   1. 在 3 的基础上我们再使用 `infer` 将函数的返回类型改为形参类型

   ```typescript
   // 将参数类型作为返回类型
   type ArgAsReturn<T> = {
       [K in keyof T]: T[K] extends ((arg: infer U) => any) ? ((arg: U) => U): never;
   }

   // 我们最终得到了 Translate
   type Translate = ArgAsReturn<SubType<Logger, Function>>;

   // 看看最后效果，满足要求
   type T = Translate<Logger>;

   // type T0 = {
   //     asyncLog: (arg: string) => string;
   //     syncLog: (arg: string) => string;
   // }
   ```

   文中部分示例来自[TypeScript 官网 - 高级类型](https://www.typescriptlang.org/docs/handbook/advanced-types.html)，面试题灵感来自[中国 LeetCode](https://github.com/LeetCode-OpenSource/hire/blob/master/typescript_zh.md?rgh-link-date=2020-04-13T15%3A04%3A56Z)，原题太绕且有 Redux 倾向，因此做了简单改造，基本思路一致甚至更全面。
10. 分享一个代码优化技巧：

    如何将优化双分支的代码？ ![image-20201203162454394](/files/-MPZDc3xg55onZRXDZiz)

    `condition ? A : B` 在大多数弱类型语言中可转换为 `[A, B][condition]`

​


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://thinking.simonaking.com/archives/2020/12/3.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
