# 2019
# 2019/07/29
# 01 简单了解 netlify 的一些配置
由于所有的静态资源都打了 hash,为所有静态资源添加了永久缓存。另外配置了自动部署
[[headers]]
for = "/assets/*"
[headers.values]
cache-control = "max-age=31536000"
# 02 一篇关于 exit code 与 node 中异常的文章
https://shanyue.tech/post/exit-code-node-and-docker.html (opens new window)
# 2019/07/30
# 01 一篇关于调试 js 的示例总结
https://shanyue.tech/post/js-debug-examples/ (opens new window)
# 02 关于 kill
的一些信号 (signal)
当起了一个 server
时,
- <Ctrl+C> 使用
SIGINT(2)
来杀死进程 kill
默认使用SIGTERM(15)
杀死进程,进程可以对该信号进行捕捉kill -9
使用SIGKILL(9)
杀死进程,进程无法对信号进行捕捉 (强制杀死)
# 03 对指定进程的 signal 进行监控
strace -e signal -p $pid
# 2019/07/31
# 01 graphql 中 apollo-server 对 cache 的处理
今天对我的脚手架的服务端添加了对缓存的处理,具体改动如下
具体看了下相关插件关于缓存的源码,发现与我想的缓存机制不大一样。graphql 可以说是以 field
为主要关注点,本以为它会根据 field
来进行缓存,就如同客户端的apollo-client
与 relay
一般。结果它还是以整个 query
为单位进行缓存,不过,细想也是有原因的:
- 方便 http response,(GET)
- 返回 field 的数据无法组成 resolver 函数中
Parent
的数据类型
关于如何对一个 query
计算它的缓存时间的源码如下
type Post @cacheControl(maxAge: 240) {
id: Int!
votes: Int @cacheControl(maxAge: 300)
}
type Query {
latestPost: Post @cacheControl(maxAge: 10)
}
# 02 对个人 Next + React + GraphQL 的项目添加了简单的 ts 支持
以下是具体改动,Next 现在对新增 ts 支持的体验真是棒,只需要按着提示走就可以了
# 2019/08/01
每日一诗:荷风送香气,竹露滴清响。
# 01 React Hook 的学习
hook 的出现真是振奋人心,可惜现在才看。最喜欢它的两点:复用逻辑和减少嵌套。
graphql 中再配合 react-apollon-hooks (opens new window) 使用,体验极佳。
PS: 再结合 graphql-code-generator (opens new window) 前端自动生成类型/(及注释文档),不知少了多少前后端的沟通。graphql 后端的接口一出来,前端立即可以
- 使用 graphql-code-generator 自动拉取 type.ts,解决前后端联调最大的问题,及 API 的前后端数据类型一致性,且不用手工维护
- 在 type.ts 中有注释,即文档,不懂的可以再问后端
- 自动补全以及类型校验接口字段
# 02 总结了一份关于 graphql-code-generator (opens new window) 自我感觉良好的配置文件
overwrite: true
schema: "http://localhost:5000/graphql"
documents: "query.gql"
generates:
query.ts:
plugins:
- "typescript"
- "typescript-operations"
config:
scalars:
DateTime: Date
JSON: "{ [key: string]: any }"
namingConvention:
typeNames: change-case#pascalCase
transformUnderscore: true
enumValues: keep
# 2019/08/02
因过竹院逢僧话,又得浮生半日闲。
# 01 看源码 Bluebird.map 中的 concurrency 的实现原理 (doing)
自然自己可以实现一个关于 Promise 的限流,但是能设计好 API 就是另一回事了
function get (i) {
console.log('In ', i)
return new Promise((resolve) => {
setTimeout(() => {
resolve()
console.log('Out', i)
}, i * 1000)
})
}
// 如何使用 get 请求这些数据,并且限流三个
const list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
let count = 0
function run () {
if (count < 3 && list.length) {
count+=1
get(list.shift()).then(() => {
count-=1
run()
})
}
}
run()
run()
run()
# 2019/08/03
叶上初阳干宿雨,水面清圆,一一风荷举。
# 01 看源码 featurist/promise-limit (opens new window) 中的 promise 限流的实现
# 02 接昨日,实现一个 Promise.map
class Limit {
constructor (n) {
this.limit = n
this.count = 0
this.queue = []
}
enqueue (fn) {
return new Promise((resolve, reject) => {
this.queue.push({ fn, resolve, reject })
})
}
dequeue () {
if (this.count < this.limit && this.queue.length) {
const { fn, resolve, reject } = this.queue.shift()
this.run(fn).then(resolve).catch(reject)
}
}
async run (fn) {
this.count++
const value = await fn()
this.count--
this.dequeue()
return value
}
build (fn) {
if (this.count < this.limit) {
return this.run(fn)
} else {
return this.enqueue(fn)
}
}
}
PromiseMap = function (list, fn, { concurrency }) {
const limit = new Limit(concurrency)
return Promise.all(list.map((...args) => {
return limit.build(() => fn(...args))
}))
}
function get (i) {
console.log('In ', i)
return new Promise((resolve) => {
setTimeout(() => {
resolve()
console.log('Out', i)
}, i * 1000)
})
}
PromiseMap(list, i => get(i), { concurrency: 3 })
# 2019/08/04
风吹古木晴天雨,月照平沙夏夜霜。
# 2019/08/05
黑云翻墨未遮山,白雨跳珠乱入船
# 01 总结了两篇关于 promise 的文章
# 2019/08/06
居高声自远,非是藉秋风
# 01 解决 typescript/webpack 环境中 import query.gql 的问题
# 02 看源码 graphql-tag
# 03 了解 node 中的 stream 以及原理
# 2019/08/07
惊鹊栖未定,飞萤捲帘入。
# 01 思考两个问题
- 如何快速熟悉新业务 (opens new window)
- 如何对测试环境添加假数据
# 02 关于 prerender 与 ssr 的取舍思考
# 03 大致了解 musl
# 2019/08/08
睡起秋声无觅处,满阶梧叶月明中。
# 2019/08/09
# 01 看 graphql.js 的源码
# 02 graphql.js 中有一段 Promise.reduce 的实现,用来串行 Promise。比较简单,贴下边
export default function promiseReduce<T, U>(
values: $ReadOnlyArray<T>,
callback: (U, T) => PromiseOrValue<U>,
initialValue: PromiseOrValue<U>,
): PromiseOrValue<U> {
return values.reduce(
(previous, value) =>
isPromise(previous)
? previous.then(resolved => callback(resolved, value))
: callback(previous, value),
initialValue,
);
}
# 2019/08/10
# 01 看 dataloader 源码
关于 Promise 各种功能实现的一个万能的队列...
new Promise((resolve, reject) => {
queue.push({
fn,
resolve,
reject
})
})
# 02 看 CMAKE 用法
# 2019/08/11
月华收,云淡霜天曙。
# 01 体验 taro,使用它做一个小程序
# 02 使用 react-hook 写一个倒计时
恩,这可以考察关于 react hook 的了解与熟悉程度。
刚开始熟悉 react-hook 时,写一个倒计时组件还是比较有点难度的
这一条加入我的候选人面试套餐
# 03 react-hook 中的 useEffect 的执行时机
# 2019/08/12
# 01 htop/ps 中的 time
time
指 cpu user time + cpu system time.
etime
指启动了多久时间
# 2019/08/13
紫薇朱槿花残,残阳却照阑干
# 01 了解数据仓库以及分层
- ODS: Operational Data Store
- DW: data warehouse
- DWD
- DWB
- DWS
- DIM: 维度数据层
就我理解,数据仓库分层,就如同业务代码上线前的若干环境
# 02 了解 postgres 的 Query Plan
添加索引后,要确保是否有效,可以先 explain 一下
# 03 了解 postgres 的 search path
show search_path
恩,还有特殊的 schema:pg_catalog
,自带 search_path...
# 2019/08/15
寒蝉凄切,对长亭晚,骤雨初歇。
# 2019/08/16
陇首云飞,江边日晚,烟波满目凭阑久。
# 01 linux jobs
需要注意的是,jobs
与 tty
相关联。
$ npm run dev
# 放到后台并停止该程序
$ <Ctrl+Z>
# 激活该程序
$ bg
# 放到前台
$ fg
不过一般情况下还是用 tmux
使用多,特殊情况下,如在 vscode
的终端会使用 jobs
# 02 一篇文章 如何为测试环境添加假数据 (opens new window)
# 03 stty size
stty size
输出当前 tty 的高和长。虽然我以前是通过 seq 1 100
来看控制台的高...
# 2019/08/17
登孤垒荒凉,危亭旷望,静临烟渚。
# 01 postgres 把查询结果写到文件中
\o /tmp/query.txt
select * from users limit 100
\o
# 02 What is RSS and VSZ in Linux memory management (opens new window)
一般我理解 RSS 为物理内存,VSZ 理解为虚拟内存,而在监控线上系统时,也是看 RSS。这篇文章说的更细一些
- RSS
- VSZ
- PSS
# 03 统计诗词中的前五百个高频字
select array_to_string(array(select char from char_cloud GROUP BY char ORDER BY sum(count) desc limit 500), '')
# 04 start transaction 与 begin 的区别
好像没啥区别...
# 2019/08/18
欲买桂花同载酒,终不似,少年游。
# 2019/08/19
千里澄江似练,翠峰如簇。
# 01 UTM
关于打点的一些数据,用以了解广告投放的效果。自从转入了 toC 这边,越来越多地接触了运营的东西
- utm_source:标识为您的媒体资源带来流量的广告客户、网站、出版物等,例如:google、newsletter4、billboard。
- utm_medium:广告媒介或营销媒介,例如:每次点击费用、横幅广告和电子邮件简报。
- utm_campaign:产品的具体广告系列名称、标语、促销代码等。
- utm_term:标识付费搜索关键字。如果您采用人工方式标记付费关键字广告系列,那么您还应使用 utm_term 来指定相应关键字。
- utm_content:用于区分相似内容或同一广告内的链接。例如,如果您在同一封电子邮件中使用了两个号召性用语链接,就可以使用 utm_content 并为每个链接设置不同的值,以便判断哪个版本的效果更好。
# 02 补了两篇半年前的旧文
# 2019/08/20
无奈夜长人不寐,数声和月到帘栊。
# 01 SQL 中的隔离级,悲观锁与 MVCC
补一篇文章: 关于统计诗词字云的解决方案 (opens new window)
# 2019/08/21
草色新雨中,松声晚窗里。
# 01 重装 vscode
由于最近 vscode
中的语法高亮坏掉了,特别是在写 css
和 gql
的时候,近乎白色 (solarized light),于是重装。
# 注意以前俩位置要删除掉
$ rm -rf ~/Library/Application\ Support/Code
$ rm -r ~/.vsCode
# 02 升级项目的 react-apollo@3.0.2 可以使用 useQuery
commit: https://github.com/shfshanyue/shici/commit/6a5e87418521dd21352eaf938fc98859561e279f (opens new window) commit 2: https://github.com/shfshanyue/shici/commit/523af69dadf3cc4909c621b6aa8addf777bc3875 (opens new window)
恩,react-hook 对于我最大的好处就是减少了层级嵌套,爽啊
另外,一个 190 行的代码变成了 110 行,大大减少了代码量
# 03 prometheus/grafana
今天使用 postgres 作为 grafana 的数据源做了一个图,感觉还不错
# 2019/08/22
日暮东风怨啼鸟,落花犹似坠楼人
# 01 一点 @apollo/react-ssr 以及 next.js 的源码
关于脱水和注水两个重要的方法
InmemoryCache.prototype.restore()
InmemoryCache.prototype.extract()
<script id="__NEXT_DATA__" type="application/json">
# 02 关于清除前端多余静态资源的方案
# 2019/08/23
# 01 几个关于运营的关键词
- KA (key account)
- 漏斗分析
# 02 漏斗分析
# 2019/08/24
萧萧梧叶送寒声,江上秋风动客情。
# 2019/08/25
浪花有意千里雪,桃花无言一队春。
# 2019/08/26
莫谩愁沽酒,囊中自有钱。
# 01 the-benefits-of-server-side-rendering-over-client-side-rendering
# 02 @apollo/react-ssr 以及 @apollo/react-hooks 的源码
ssr.getDataFromTree
ssr.getMarkFromTree
: 请求数据结束后,生成对应的字符串下发到浏览器hooks.RenderPromises
: 所有的请求hooks.QueryData
在 @apollo/react-ssr
中默认调用 ReactDOMServer.renderToStaticMarkup(element)
,因为它生成更小的字节数据
# 03 React.memo
类似于 PureComponent
# 04 Suspense & React.lazy
主要处理懒加载组件吧,
# 2019/08/27
寒蝉凄切,对长亭晚,骤雨初歇。
# 01 客单价/成单周期
平均每个顾客的支付费用,客单价高一般成单周期长,不过无所谓,toB 挣大钱
# 02 了解一些支付 API 以及微信开发 API
# 03 批量设置 no_proxy
printf -v no_proxy '%s,' 10.1.{1..255}.{1..255};
export no_proxy="${no_proxy%,}";
export no_proxy=0,1,2,3,4,5,6,7,8,9
# 2019/08/28
萧瑟秋风今又是,换了人间
# 01 教育细分行业,如何估计市场规模
# 02 私域流量池
# 03 了解 docker 的 AUFS
# 2019/08/29
无边尽掌露成霜,云随雁字长。
# 01 思考几点 graphql 的意义
- 技术: 性能,缓存
- 沟通: 联调 (文档化,强类型 -> type code autogen,想查啥就查啥)
- 业务: 快速迭代
- 人力: 低
# 02 关于 k8s 的离线镜像包
cat images.txt | xargs -I {} docker pull {}
cat images.txt | xargs docker save -o gcr.tar
# 2019/08/30
# 01 ssh -t github.com
# 02 git submodule 下载所有子模块
git submodule update --remote
# 2019/08/31
# 01 查看 centos 版本号
centos 是一个没有支持的 rhel
$ cat /etc/redhat-release
CentOS Linux release 7.4.1708 (Core)
# 02 现在我们生产环境中的磁盘复制速度多大
# 03 iptables -S
# 2019/09/01
# 01 关于彩票市场规模
每年规模大致4000个亿,其中乐透型大约占 60%
# 02 关于在线教育市场的分类
B2B2C
B2C
# 2019/09/02
# 01 在线教育市场的获客成本
# 02 两个数据获取平台
# 03 解决 k8s 在外网使用 kubelet 进行权限访问时的证书问题
Unable to connect to the server: x509: certificate is valid for 10.96.0.1, 172.17.68.40, not 47.93.26.56
# 2019/09/03
乍暖还清冷,风雨晚来方定。
# 01 网页热力分析 (heatmap)
可以用来分析最高 PV 几个页面的用户点击行为,点击率一般 0.1% 就算比较高了。一些重要内容,如排行榜,搜索可能会有两个百分点
注意网页热力分析时,querystring 不同是否视为不同页面
# 02 访问深度
DV,即 PV / UV,一般超过10就可以认为做的不错了
# 2019/09/04
年年今夜,月华如练,长是人千里
# 01 关于 k8s 中镜像的拉取策略
这里的这个字段叫做 imagePullPolicy
,默认值是 IfNotPresent
,代表如果本地有镜像则从本地拉取镜像,而 Always
表示总是从网络上拉取镜像。
而在 metrics-server
的部署资源: https://github.com/kubernetes-incubator/metrics-server/blob/master/deploy/1.8%2B/metrics-server-deployment.yaml
,其中用的是 always
,害我半天拉不了 k8s
的镜像,报 ImagePullBackOff
的错误。
# 2019/09/06
# 01 降准
准:指法定存款准备金率。一个流程,社会资金 -> 银行 -> 央行,而准备金率指银行必须在央行存的钱与自己库存现金的比例。降准之后,商业银行钱会变多,增加人民币流动性。
# 02 成单周期
# 2019/09/08
一声梧叶一声秋,一点芭蕉一点愁
# 01 马太效应
自由资本市场的贫富两极分化
# 2019/09/09
金风细细,叶叶梧桐坠
# 01 微服务治理
在简书上看到一篇还不错的文章
# 2019/09/11
水风轻,蘋花渐老,月露冷,梧叶飘黄。
# 2019/09/12
# 01 reverse-interview (opens new window)
# 02 knew
在 k8s v1.15 中新出的插件管理工具
# 2019/09/15
惟将终夜长开眼,报答平生未展眉
# 01 表意文字与表音文字
来自知乎的一个问题: 为什么其他国家大多用拼音文字? (opens new window),记录一下
文言二途
语言成为世界语言并不表明某语言本身的优势,而在于语言背后国家及文化的影响力
词库/联想
# 2019/09/16
渐霜风凄紧,关河冷落,残照当楼
# 01 apollo-tooling (opens new window)
# 2019/09/18
潦水尽而寒潭清,烟光凝而暮山紫
# 01 apollo http status (opens new window)
关于 apollo-server 对于 http status 处理的一次提交
# 02 Documentation for new request pipeline life-cycle hooks/plugins. (opens new window)
plugin: 关于 apollo-server 加入 plugin 的一个没有加入文档的特性..
# 2019/09/20
# 01 mysql 中的一个小问题
> select 'a' = 'a '
1
# 2019/09/22
等闲变却故人心,却道故人心易变
# 01 阮朝
越南最后一个封建王朝,内帝外王
# 02 事大
# 03 三国十五州
- 凉州
- 并州
- 幽州
- 兖州
- 冀州
- 青州
- 荆州
- 徐州
- 扬州
- 交州
- 益州
# 2019/09/25
# 01 React Portals
适合写一个 Modal 组件
# 2019/09/27
# 01 babel: 如何定义一个 preset
文档在这里: https://babeljs.io/docs/en/presets
preset
就是一系列 plugin 的集合
# 02 全球饥饿指数
GHI: https://www.globalhungerindex.org/results/
# 03 人类发展指数
HDI: https://en.wikipedia.org/wiki/List_of_countries_by_Human_Development_Index
# 2019/09/28
# 01 卡哈马卡之战
# 2019/10/16
# 01 linux 命令中单引号以及双引号的区别
从以下示例中很可以看出区别,当打印变量时,双引号会当做变量,而单引号原样输出
$ echo $USER
shanyue
$ echo "$USER"
shanyue
$ echo '$USER'
$USER
# 02 韩国近现代史
- 1919 大韩民国临时政府在上海成立,此时为日占时期
- 1945 日本投降,美苏进驻朝鲜半岛,朝韩分裂,三八线为界
- 1948 朝鲜半岛南部大韩民国成立,李承晚首届总统,李承晚亲日亲美
- 1961 朴正熙军事政变,他是朴槿惠父亲,开启了军政府时代。在他掌权的17年出现了 汉江奇迹,财团亲日亲美
- 1979 朴正熙遇刺身亡
- 1980 光州事件,随后全斗焕上台
- 1993 金泳三上台,此时他的党派为民主自由党
- 1997 亚洲金融危机爆发,金泳三向国际货币基金组织贷款 580亿美元
- 2002 卢武铉上台 (辩护人主角原型)
- 2007 卢武铉与金正日朝韩会面
- 2008 李明博上台,政治清算卢武铉,卢武铉自杀
- 2013 朴槿惠上台,闺蜜干政事件(崔顺实事件)被弹劾
- 2017 文在寅上台
- 2007 文在寅与金正恩朝韩会面
# 03 2019.09 CPI
9月份,全国CPI同比上涨3.0%。CPI 指中国居民消费价格,由于猪肉价格上涨极大影响了CPI。
详见 国家统计局九月CPI数据 (opens new window)
# 2019/10/17
# 01 wget 如何像 curl 一样打印到标准输出
$ curl localhost:8080
# -q 指忽略 wget 自身的输出
# -O 指输出文件, - 代表标准输出
$ wget -q -O - localhost:8080
# 02 多服务器 ssh key 的管理
如果只有一台服务器,则可以通过 ssh-copy-id
命令快速免密登录
那如果有100台服务器,如何快速使他们能够互相免密登录
- 拷贝
~/.ssh/config
到每个服务器 - 使用 ansible 的 authorized_key (opens new window) 模块
# 03 github ssh keys
直接访问 github.com/user.keys
可以直接获取用户所设置的 ssh key
$ curl https://github.com/shfshanyue.keys
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC+lWovAJLpk6Jb7NGXQ08IISUNbalT9gpkFOx08cJAPlQDSU8Dqx8F9jK3m4wDj4wGh+rJbTbf6YcGF7kZGwJr+l70mNfAhYc5dU7in5ZdDJUpCzaoUtPceYa6BTnJPbTLSYEUTyvO2KNQNDEIMO95LfCrLaPSALGl3G6sXeE8bGiWR2LdBqxi5ocQsfhw11vX3Nr3L0Sd8cKQPusbMv8MipXizmGDFHMZezcSdQ26na+g6KHfQPqLR1Y80RvNJ47weOuzQ1oMBVIz/OVYajsxoqK+O8L0ZZR1DaTUsl4D9veQPdt+dH89oNZGikzNrGSiqng9w6Ro9Dcy9OIVVrgd
# 04 资讯
- 22日,国家博物馆将开展甲骨文文化展览
- 国台办:大陆全面展开榕马大桥厦金大桥前期研究论证
- 15日, 美国国会众议院通过所谓 "2019年香港人权与民主法案"
# 2019/10/18
# 01 资讯
- 17日,歼-20 与运-20 在长春亮相
# 02 如何查看服务器有多少用户登录
两个命令,一个 who
一个 last
$ who -u
root pts/0 Oct 18 15:04 . 16860 (124.200.184.74)
root pts/2 Oct 18 15:04 . 16902 (124.200.184.74)
$ last -a | head -10
# 2019/10/22
# 01 k8s 中的 Volume
To use a volume, a Pod specifies what volumes to provide for the Pod (the .spec.volumes field) and where to mount those into Containers (the .spec.containers[*].volumeMounts field).
与 docker 中的 volume 最大的不同是,k8s 中的 volume 存在生命周期,而且 k8s 中的volume是分布式的
# 02 k8s 中的 PersistentVolumes 与 PersistentVolumeClaim
PVs are resources in the cluster. PVCs are requests for those resources and also act as claim checks to the resource
PV: 我应该去哪里拿一块空间,nfs 或者哪一个分布式存储的地方? PVC: 我应该去问 PV 要多少空间,并且我要给那个 pod 用
apiVersion: v1
kind: PersistentVolume
metadata:
name: mysql-pv-volume
labels:
type: local
spec:
storageClassName: manual
capacity:
storage: 20Gi
accessModes:
- ReadWriteOnce
hostPath:
path: "/mnt/data"
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mysql-pv-claim
spec:
storageClassName: manual
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 20Gi
# 03 nfs
k8s 的 pv/pvc 依赖于 nfs,毕竟不用于 docker 的 volume,只在单机下。nfs, network file system,顾名思义,所以用它做分布式的文件系统简直再好不过了。
$ yum install rpc-bind nfs-utils
$ systemctl enable nfs
$ systemctl start nfs
# 创建挂载目录
$ mkdir /data
$ cat >> /etc/exports <<EOF
> /data/ 172.17.68.0/24(rw,sync,no_root_squash,no_all_squash)
> EOF
# 重启 nfs 服务
$ systemctl restart nfs
# showmount - show mount information for an NFS server
$ showmount -e localhost
Export list for localhost:
/data/ 172.17.68.0/24
# 2019-10-23
# 01 postgres 不设置密码
修改文件 pg_hba.conf
,可以对特定网络的用户不设置密码
host all postgres 127.0.0.1/32 trust
具体参考文档 The pg_hba.conf File (opens new window)
# 02 在k8s 中使用 pgcli 连接 postgres
$ kubectl run pgcli --rm --tty -i --restart='Never' --image docker.io/pygmy/pgcli --command -- pgcli --host pg-postgresql -U postgres -p 5432 -d todos