博客折腾记

记录博客修修补补的故事

210123: 博客进入 beta 0.3 时代 我也想学习微信不写更新日志

beta 0.3

beta 0.2

长达 9 个月闲置之后,终于迎来一轮对博客的更新。

  • 本着闭环的原则,将评论系统从 Disqus 替换为基于 Github Issues 的 Gitalk。不过,依旧没有多少留言量。
  • 博客主题从 Next 切换到 fi3ework/hexo-theme-archer: 🏹 A smart and modern theme for Hexo.
  • 添加一个新的固定栏目 「每月分享」,目前正在持续探索具体形式中。
  • 除继续使用百度统计之外,加上 Google Analytics 进行数据分析。

beta 0.1

beta 0

早期对博客进行的相关修改有:

博客专栏

  • 【每周分享】:每周六更新,记录过去一周,我看到值得分享的内容
  • 【月读】:每月更新,推荐本月我阅读的一本书
  • 【数字生活】:我的数字生活实践
  • 【博客公告】:分享与这个博客维护相关的内容

博客记录

  • 本博客采用hexo搭建,使用Even主题
  • 托管:Coding Pages
  • 域名:腾讯云
  • 评论:Disqus
  • 统计:百度统计
  • 图床:七牛
  • 20151006:恢复订阅功能
  • 20160303:开启分类和请我喝一杯咖啡
  • 20160623:重新开启评论和百度统计,与自己和解
  • 20160624:更换主题大道至简Maupassant,增加favicon和apple-touch-icon
  • 20170104:放弃github+hexo,投入vps+wordpress怀抱,依旧使用maupassant主题
  • 20170722:主机系统升级失败,从备份中恢复博客,并采用 Twenty Twelve 主题
  • 20171005:重新投入hexo怀抱,并托管于Coding Pages
  • 20180101:开启功德箱
  • 20180501:PV: 657 | UV: 242
  • 20180528:使用 Travis CI 自动部署

除虫记录

Error: Cannot find module ‘node-sass-magic-importer’

ERROR in Cannot find module ‘node-sass’(已解决) - line - CSDN博客

1
cnpm install node-sass@latest

博客折腾记:hexo-leancloud-counter-security 与标题中的引号冲突

昨天按照 hexo-theme-next/LEANCLOUD-COUNTER-SECURITY.md at master · theme-next/hexo-theme-next 这个文档配置博客阅读次数时,遇到 hexo-leancloud-counter-security 插件的一个冲突。

完成配置使用 hexo -d 时,终端中出现下面的错误提示:

1
2
3
4
5
6
7
8
9
10
11
12
13
 ATAL Something's wrong. Maybe you can find the solution here: http://hexo.io/docs/troubleshooting.html
SyntaxError: Unexpected token h in JSON at position 30
at JSON.parse (<anonymous>)
at /Users/didi/Documents/personal/xiang578.github.io/node_modules/hexo-leancloud-counter-security/index.js:92:42
at arrayEach (/Users/didi/Documents/personal/xiang578.github.io/node_modules/_lodash@4.17.11@lodash/lodash.js:516:11)
at Function.forEach (/Users/didi/Documents/personal/xiang578.github.io/node_modules/_lodash@4.17.11@lodash/lodash.js:9344:14)
at Hexo._callee$ (/Users/didi/Documents/personal/xiang578.github.io/node_modules/hexo-leancloud-counter-security/index.js:83:27)
at tryCatch (/Users/didi/Documents/personal/xiang578.github.io/node_modules/_regenerator-runtime@0.11.1@regenerator-runtime/runtime.js:62:40)
at Generator.invoke [as _invoke] (/Users/didi/Documents/personal/xiang578.github.io/node_modules/_regenerator-runtime@0.11.1@regenerator-runtime/runtime.js:296:22)
at Generator.prototype.(anonymous function) [as next] (/Users/didi/Documents/personal/xiang578.github.io/node_modules/_regenerator-runtime@0.11.1@regenerator-runtime/runtime.js:114:21)
at step (/Users/didi/Documents/personal/xiang578.github.io/node_modules/_babel-runtime@6.26.0@babel-runtime/helpers/asyncToGenerator.js:17:30)
at /Users/didi/Documents/personal/xiang578.github.io/node_modules/_babel-runtime@6.26.0@babel-runtime/helpers/asyncToGenerator.js:28:13
at process._tickCallback (internal/process/next_tick.js:68:7)

看提示貌似是利用 Json 解析字符串的时候出现问题。打开 node_modules/hexo-leancloud-counter-security/index.js:92,对应出现一个解析 JSON的:

1
y = JSON.parse(memoData[memoIdx].substring(0, memoData[memoIdx].length - 1));

js 没有怎么接触过,不知道能不能单步调试之类的,只好祭出输出调试大法,加上两个输出:

1
2
3
console.log(memoIdx)
console.log(memoData[memoIdx])
y = JSON.parse(memoData[memoIdx].substring(0,memoData[memoIdx].length - 1));

然后再执行 hexo -d 命令,命令行输出为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
28
{"title":"System.out.println("hello world!");","url":"/post/hello-world.html"},
FATAL Something's wrong. Maybe you can find the solution here: http://hexo.io/docs/troubleshooting.html
SyntaxError: Unexpected token h in JSON at position 30
at JSON.parse (<anonymous>)
at /Users/didi/Documents/personal/xiang578.github.io/node_modules/hexo-leancloud-counter-security/index.js:92:42
at arrayEach (/Users/didi/Documents/personal/xiang578.github.io/node_modules/_lodash@4.17.11@lodash/lodash.js:516:11)
at Function.forEach (/Users/didi/Documents/personal/xiang578.github.io/node_modules/_lodash@4.17.11@lodash/lodash.js:9344:14)
at Hexo._callee$ (/Users/didi/Documents/personal/xiang578.github.io/node_modules/hexo-leancloud-counter-security/index.js:83:27)
at tryCatch (/Users/didi/Documents/personal/xiang578.github.io/node_modules/_regenerator-runtime@0.11.1@regenerator-runtime/runtime.js:62:40)
at Generator.invoke [as _invoke] (/Users/didi/Documents/personal/xiang578.github.io/node_modules/_regenerator-runtime@0.11.1@regenerator-runtime/runtime.js:296:22)
at Generator.prototype.(anonymous function) [as next] (/Users/didi/Documents/personal/xiang578.github.io/node_modules/_regenerator-runtime@0.11.1@regenerator-runtime/runtime.js:114:21)
at step (/Users/didi/Documents/personal/xiang578.github.io/node_modules/_babel-runtime@6.26.0@babel-runtime/helpers/asyncToGenerator.js:17:30)
at /Users/didi/Documents/personal/xiang578.github.io/node_modules/_babel-runtime@6.26.0@babel-runtime/helpers/asyncToGenerator.js:28:13
at process._tickCallback (internal/process/next_tick.js:68:7)

JSON 在解析字符串{"title":"System.out.println("hello world!");","url":"/post/hello-world.html"} 时出现错误。对应的正是之前写的一篇名为 System.out.println("hello world!"); 的文章,由于 JSON 格式中字符串是需要用"" 修饰,导致JSON 中出现了一个 "title":"System.out.println("hello world!");" key-value 组合。然而实际上 JSON 只会将 "System.out.println("h 解析成 value,之后出现的 h 被当成非法字符报错。

定位问题之后,暂时修改文章的标题为 hello world! | 算法花园,绕过部署失败。


博客折腾记:主题更新、迁移博客到腾讯云COS以及解决百度收录

本周有空对博客进行新一轮折腾,现在将这些尝试记下来和大家分享。

1. 主题更新

我在 博客折腾记:使用 Travis CI 自动部署 中提到将主题以 modules 的形式加入主仓库。而且现在使用的主题 git 仓库是我自己 fork 的,也有一些修改。几个天之前,hexo-theme-even 的 master 接受 feat: add LaTeX support by JieJiSS · Pull Request #236 ,完成对 LaTeX 公式的支持。所以,我需要将使用的代码和最新的代码合并。

这里使用的是 github Pull request 功能。在你自己 fork 的仓库的网页上点击 new pull request,然后按照下图修改。就会生成一个新的 Pull request 。
-w1009

而且,如果你没有修改过原来的代码,PR 能自动合并。不过由于我对代码做了一些修改,会产生一些冲突,需要手动解决冲突(这里推荐使用 VS code)。出现下图的情况即成功合并两个库。
-w1046

完成 PR 后,进入你站点下面的对应主题目录,使用 git checkout master 切换到主题的 master 分支,使用 git pull origin master 拉取最新的代码。回退到站点目录下,利用 git add 更新。

2. 迁移博客到腾讯云COS

利用腾讯云存储博客的静态文件,并配合使用 CDN 可以加快国内的访问速度。参考 Hexo博客迁移之旅(Coding到腾讯云COS)+ Travis CI持续集成 - 个人文章 - SegmentFault 思否 以及 如何在腾讯云COS部署HEXO博客 - 云+社区 - 腾讯云

记录两个我遇到的坑。

新的域名解析

完成 COS 配置后,需要将博客域名解析到腾讯提供CDN节点上的地址。

添加持续集成自动发布到COS(Travis CI)

为了发布到 COS,站点的 _config.yml 会添加下面的代码。

1
2
3
4
5
6
7
 deploy:
- type: cos
secretId: XXX_ID
secretKey: XXX_KEY
appId: 1252086360
bucket: blog-1252086360
region: ap-shanghai

其中出现的 secretId 以及 secretKey 是私钥,不要在公开仓库展示。通过Travis-ci 中添加 Environment Variables 解决。

很多教程里,他们的 _config.yml 不会出现 secretId 和 secretKey 这两行,取而代之的是让你在 .travis.yml 添加几行。

1
2
3
4
5
6
script 
- hexo d
env:
global:
- secretId: ${secretId} # Environment Variables 中配置
- secretKey: ${secretKey} # Environment Variables 中配置

按照这样设置,build 时,出现错误提示如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
{ error:
{ Code: 'InvalidAccessKeyId',
Message: 'The access key Id format you provided is invalid.',
Resource:
'blog-1252086360.cos.ap-shanghai.myqcloud.com/2012/01/23/2011/index.html',
RequestId: 'NWNlMDU3NzlfNWI5ZDA4MDlfNWVlMF81ZWUzNTg=',
TraceId:
'OGVmYzZiMmQzYjA2OWNhODk0NTRkMTBiOWVmMDAxODc0OWRkZjk0ZDM1NmI1M2E2MTRlY2MzZDhmNmI5MWI1OTQyYWVlY2QwZTk2MDVmZDQ3MmI2Y2I4ZmI5ZmM4ODFjMDU3YThkNThjZmQ1NWVkMGY2ZDBiNGM1YTEyNGIzMGM=' },
statusCode: 403,
headers:
{ 'content-type': 'application/xml',
'content-length': '513',
connection: 'keep-alive',
date: 'Sat, 18 May 2019 19:05:29 GMT',
server: 'tencent-cos',
'x-cos-request-id': 'NWNlMDU3NzlfNWI5ZDA4MDlfNWVlMF81ZWUzNTg=',
'x-cos-trace-id':
'OGVmYzZiMmQzYjA2OWNhODk0NTRkMTBiOWVmMDAxODc0OWRkZjk0ZDM1NmI1M2E2MTRlY2MzZDhmNmI5MWI1OTQyYWVlY2QwZTk2MDVmZDQ3MmI2Y2I4ZmI5ZmM4ODFjMDU3YThkNThjZmQ1NWVkMGY2ZDBiNGM1YTEyNGIzMGM=' } }
FATAL Something's wrong. Maybe you can find the solution here: http://hexo.io/docs/troubleshooting.html
TypeError: Cannot read property 'statusCode' of undefined
at uploadFileToCOS.catch.then.data (/home/travis/build/xiang578/xiang578.github.io/node_modules/hexo-deployer-cos/lib/deployer.js:42:16)
at process._tickCallback (internal/process/next_tick.js:68:7)

出现这个问题是 hexo -d 时,_config.yml 无法获得环境变量 secretId 和 secretKey 的。会导致没有秘钥。

参考 使用 Travis CI 部署你的 Hexo 博客 - 知乎 ,在 .trvis.yml 文件的 hexo d 命令前,加入下面两行即可解决。

1
2
- sed -i "s~XXX_ID~${secretId}~" _config.yml
- sed -i "s~XXX_KEY~${secretKey}~" _config.yml

之后build 时,会自动利用环境变量中 secretId 和 secretKey 的值替换 _config.yml 文件缺省的值。

最后提供我的两份配置文件给大家参考:_config.yml.travis.yml

3. 百度收录

之前,我一直将博客的静态文件存储在 github 的项目中,也使用插件生成 baidusitemap 文件。但是由于一些不为人知的秘密,百度的爬虫实际上无法爬取 github 上的资源,导致博客最新的文章没有被收录到百度中。

而且从百度提供的抓取诊断上来看,配置腾讯云 COS 后,百度的爬虫依然访问的是 github 上的仓库。

-w558

一顿搜索之后,找到一个主动提交 hexo 博客链接至百度的插件 huiwang/hexo-baidu-url-submit

参考 Hexo插件之百度主动提交链接 | 王辉的博客 以及 Hexo百度主动提交链接 - 简书 完成配置。

  • 安装插件 cnpm install hexo-baidu-url-submit --save
  • 修改根目录下面的 config.yml 文件,配置 baidu_url_submit 和 deploy。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
baidu_url_submit:
count: 100 ## 比如3,代表提交最新的三个链接
host: xiang578.com ## 在百度站长平台中注册的域名
token: your_token ## 请注意这是您的秘钥, 请不要发布在公众仓库里!
path: baidu_urls.txt ## 文本文档的地址, 新链接会保存在此文本文档里

deploy:
- type: cos
secretId: XXX_ID
secretKey: XXX_KEY
appId: 1252086360
bucket: blog-1252086360
region: ap-shanghai
- type: baidu_url_submitter

上面的代码中出现一个 token,由于这是一个私有的,不能出现在 github 公开的仓库中。所以也需要 Travis-ci 中添加 Environment Variables 解决。和前文提到相同,在 .travis.yml 中添加 - sed -i "s~your_token~${BD_TOKEN}~" _config.yml 解决私钥问题。

最终在 travis-ci 中发现下面的日志即配置成功。另外一点,百度的站长平台的数据不能及时展示我们提交后的结果,需要耐心等待。

-w866


ImageNet Classification with Deep Convolutional Neural Networks(AlexNet)

作者以及相关性

  • Alex Krizhevsky
  • Ilya Sutskever
  • Geoffrey E. Hinton
  • 本文被认为是这一轮深度学习浪潮的开端

主题

  • 将 CNN 技术最先应用到图像识别领域,利用 CNN 参数共享的特性,减少网络的规模
  • 解决深度网络难训练(速度慢)以及容易过拟合问题(更多数据或者网络技巧)

数据集与指标

  • ImageNet LSVRC-2010 contest: 图片 1000 分类
  • top-1 和 top-5 错误率为指标

模型/实验/结论

模型

  • 由于当时的 GPU 显存限制,无法将所有的数据加载到单独 GPU 中,作者使用两个 GPU 并行训练。

  • 整个模型如下图所示,由 5 个卷积层以及 3 个全连接层组成。其中在 CONV3、FC1、FC2、FC3 层进行两个 GPU 的数据交互。

    • [227, 227, 3] INPUT: 原始论文中 224 为笔误。
    • [55, 55, 96] CONV1: (11*11*3,96) filters, Stride 4, pad 0
    • [27, 27, 96] MAX POOL1: (3*3) filters, Stride 2
    • [27, 27, 96] NORM1: Normalization layer
    • [27, 27, 256] CONV2: (5*5,256) filters, Stride 1, pad 2
    • [13, 13, 256] MAX POOL2: (3*3) filters, Stride 2
    • [13, 13, 256] NORM2: Normalization layer
    • [13, 13, 384] CONV3: (3*3,384) filters, Stride 1, pad 1
    • [13, 13, 384] CONV4: (3*3,384) filters, Stride 1, pad 1
    • [13, 13, 384] CONV5: (3*3,256) filters, Stride 1, pad 1
    • [6, 6, 256] MAX POOL3: (3*3) filters, Stride 2
    • [4096] FC1: 两个 GPU 中的 CONV 层结果进行全连接
    • [4096] FC2: FC1 进行全连接
    • [1000] FC3: FC2 进行全连接,最后输出分类结果
  • 参数数量 60 million

  • 使用 ReLU 作为激活函数:比 tanh 计算开销小,以及收敛速度快。根据问题的特点选择激活函数(大模型、大数据集)
  • Local Response Normalization(Norm Layers):局部响应归一化层,后来很少使用。
    在经过 ReLU 作用之后,对相同空间位置上(bx,y{b_{x,y}})的相邻深度(bj{b^j} )的卷积结果做归一化。n 指定相邻卷积核数目,N 为该层所有卷积的数目。k,n,α,β{k, n, \alpha, \beta} 都是超参数。本文使用 k=2,n=5,α=104,β=0.75{k=2, n=5, \alpha=10^{-4}, \beta = 0.75}, 分别降低 top-1 和 top-5 错误 1.4% 和 1.2%

bx,yi=ax,yi/(k+αj=max(0,in/2)min(N1,i+n/2)(ax,yj)2)βb_{x, y}^{i}=a_{x, y}^{i} /\left(k+\alpha \sum_{j=\max (0, i-n / 2)}^{\min (N-1, i+n / 2)}\left(a_{x, y}^{j}\right)^{2}\right)^{\beta}

  • Pooling:s=2 < z=3,有部分重叠,作者通过实验发现这种方法可以更好地避免过拟合。
  • data augmentation:
    • 对图像进行裁剪以及翻转,扩大数据。这种策略对测试带来影响,测试时裁剪出图片四个角落以及中间部分,得到 5 张图片,另外翻转得到 5 张图片,最后分类结果又这 10 图片的平均得分确定。
    • 利用 PCA 改变 RGB 通道的强度。
  • Dropout:每次训练的时候,从模型中 sample 出一个小的模型,减少过拟合。

实验

  • 参数:dropout 0.5,batch size 128, SGD Momentum 0.9, Learning rate 1e-2 reduce by 10,L2 weight decay 5e-4

  • 测试集上结果

  • 取出 CONV1 相关的 filters卷积侧重点不同,GPU1 颜色无关,GPU2 颜色相关。多次实验发现都存在这种现象,说明使用多个 GPU 训练是必要的,模型可以捕捉更多信息。

  • 取所有最后一个隐层向量,找到与测试图片欧拉距离最小的训练图片(下图中第一列为测试图片,之后几列是欧拉距离最小的训练集中图片)。肉眼可以发现,同一分类的图片有很大关联性。证明模型能学习图片之间的关系。

结论

  • 通过移除 AlexNet 网络中的某几层发现错误率均有提高,这个网络时必要以及有效的。
  • 文章中作者通过大量的实验确定模型的细节问题,值得我们学习。
  • 当时的 GPU 限制作者的想象力……

2018 探索

全文混乱。拖了 4 个月之后,强行完结。

毕业

2018 最大的一件是自己终于艰难地从学校毕业。本来在学校属于 easy 模式,原本以为毕业很轻松。不过出于一些原因,比其他人多待一个月才拿到毕业证书,给我不太美好的大学生涯又多添几份痛苦。本来还准备写篇文章来总结一下大学生涯,拖到现在毕业都快一周年,也只能当成是毕业一周年的回忆文章。

工作

毕业之后,用我外婆说的一句话“一个人拉着两个行李箱就去工作了”。误打误撞和机器学习挂上一些关系。每天属于虽然工作很开心,但是好像没有干什么事情的状态。更多地吐槽也准备写在工作一周年的文章中。

自我管理

这个概念是年初感觉自己太混乱时提出来的,如果成为更好的自己。一年来有过很多想法和实践,但是现在还探索出来完整的系统。有机会再写。

年度阅读

说来惭愧,今年没有读多少本书,而且绝大部分都是在没有毕业时候读的。工作之后,完整看完地也只有一本《九败一胜》。这本书讲的是王兴的创业故事,总的感受是创业维艰。感觉王兴是为了创业而生的人,有知识基础,又有经济基础。在多次创业之后,培养了商业上的灵敏,管理上的艺术。最终能在千团大战中走出来,成就今天的美团帝国。可惜这个冬天,美团有些艰难,脉脉上给予他裁团(裁员,特别是应届生)、C团(绩效打 C,逼你走)的名声。比起王兴的故事,我更感兴趣的是程维创立滴滴的故事,不知道什么时候可以读到。

说回来在读过的书中,最推荐 软技能,之前也写过简单的介绍。用时髦的话来说,这本书教你成为一个斜杠青年。在基础的工资外,还有通过其他渠道有第二职业的收入,最后是睡后收入(表名上说的是睡觉时候获得的收入,第二层含义是一次生产,可以多次贩卖)。后来想想,自己可以二次出售什么?无法是什么时间管理、知识管理、理财、读书、写作之类的烂大街的东西。所以,自己还是需要加强抗击职业风险的能力,尽快找到自己的第二职业收入。

另外,自己也进行了一些主题阅读。年初的时候,对时间管理和知识管理感兴趣。读过Evernote 100个做笔记的好方法Evernote超效率数字笔记术印象笔记留给你的空间有道云笔记:记录,成为更好的自己你的知识需要管理,看完这些书多少有些收获,但也没有完全解答我的疑问,说回来,也不太推荐你们去看。不过,时间管理方面的两本书,小强升职记搞定Ⅰ,却是五星推荐,看一看,多少能提高一些工作效率。

年度观影

今年看过的电影倒是比书多一些。不过,其中好多都是漫威的超级英雄片。自己感觉漫威伟大的地方在于创造了一个包括神话、物理、外星文明的电影宇宙,这个宇宙也许会成为我们这一代人的回忆。

说回来,今年看过的片子中,最推荐的是无问西东。这部片子讲述了不同时期 4 个不同年代清华学子关于选择的故事,也许是因为没有他们这样的大学经历才会嫉妒。看完片子后,还抄录一些台词,大概能更加清晰的表达电影对我的影响。

吴岭澜(文科很好,理科很差)面对梅校长时候询问为什么不去读文科时的回答。

因为最好的学生都读实科
我只知道,不管我将来做什么
在这个年纪,读书,学习都是对的
我何用管我学什么?
每天把自己交给书本,就有种踏实

吴岭澜重新找到自己的目标之后,成为了清华大学的一名教授。在西南联大给学生上课时回忆自己的大学时光:

当我在你们这个年纪,有段时间,我远离人群,独自思索,我的人生到底应该怎样度过?某日,我偶然去图书馆,听到泰戈尔的演讲,而陪同在泰戈尔身边的人,是当时最卓越的一群人,这些人站在那里,自信而笃定,那种从容让我十分羡慕。而泰戈尔,正在讲“对自己的真实”有多么重要,那一刻,我从思索生命意义的羞耻感中,释放出来。原来这些卓越的人物,也认为花时间思考这些,谈论这些,是重要的。今天,我把泰戈尔的诗介绍给你们,希望你们在今后的岁月里,不要放弃对生命的思索,对自己的真实。

对吴岭澜的总结:

梅校长说:“人把自己置身于忙碌当中,有一种麻木的踏实,但丧失了真实,你的青春也不过只有这些日子。”
什么是真实?
你看到什么,听到什么,做什么,和谁在一起
有一种,从心灵深处,满溢出来的不懊悔,也不羞耻的平和与喜悦

后来吴岭澜领悟到了:
看到和听到的,经常令你们沮丧,世俗是这样强大,强大到生不出改变它们的念头。可是如果有机会提前了解了你们的人生,知道青春也不过只有这些日子,不知你们是否还会在意的,那些世俗让你们在意的事情,比如占有多少,才更荣耀,拥有什么,才能被爱。 等你们长大,你们因绿芽冒出土地而喜悦,会对出生的朝阳欢呼雀跃,也会给别人善意和温暖,但是却会在赞美别的生命的同时,常常,甚至永远忘了自己的珍贵。愿你在被打击的时,记起你的珍贵,抵抗恶意;愿你在迷茫时,坚信你的珍贵,爱你所爱,行你所行,听从你心,无问西东。

富家子弟沈光耀放弃学业,决定参加飞行队时,母亲不远万里来联大劝他。

“当初你离家千里,来到这个地方读书,你父亲和我都没有反对过,因为,是我们想你,能享受到人生的乐趣,比如读万卷书行万里路,比如同你喜欢的女孩子结婚生子。注意不是给我增添子孙,而是你自己,能够享受为人父母的乐趣,你一生所要追求的功名利禄,没有什么是你的祖上没经历过的,那些只不过是人生的幻光。我怕,你还没想好怎么过这一生,你的命就没了啊!”

同学在他牺牲后,去看望沈母时,屏幕上展现出一幅对联:三代五将护国定疆青史留正气,六韬三略擅用筹边御旨赞英豪。

这部电影的彩蛋标题是致敬时代的风骨,快速回顾在电影中出现过的时代名人。可惜自己没有认出多少个,真是悲哀。

后记

这篇文章写的有点杂,我只是看着 MWeb 中的存稿有点多,趁着这次机会消灭一些,来年有机会写些新的东西。

于北京回龙观

其他文章:


每周分享第 11 期

这里记录过去一周,我看到的值得分享的东西,每周六不定时更新。

观点

  • 美团和滴滴为什么要互相开展对方的业务:
    1. 我记得罗振宇在某一年时间的朋友中提到一个观点:O2O 领域会出现一个超级公司,业务横跨所有场景。
    2. 从技术角度分析,外卖中比较难的点在于分单、时间估计以及路径规划。这也是出行服务中的技术难点。不过各有侧重,外卖中路径规划相当于最多不超过 20 个点(10 个商家处取餐,10 个顾客中送餐)的 TSP 问题。出行服务最关键的是如何有效的获取道路信息。(我有一个观点,人是有主观能动性的,会抄各种小道)
    3. 这两个服务都严重依赖地推服务,所以双方本身都有一支庞大的城市地推人员。我想开展不同业务的切换难度应该会小一些。

读书《刻意练习》

听这个名字很容易认为是一本鸡汤书,英文小标题中提到 New science of Experitse。本书打破的是之前很流行的 1 万小时天才理论,这个理论认为很多天才之所以是天才是他们的技能经过长时间的训练,有量变引起质变。新的研究发现,学习的本质是在大脑中建立心理表征,它是一种长时记忆单元,也是我们习得技能的结果。刻意练习就是如何高效地获得这个心理表征。鉴于这是一本脑科学的书,方法是否正确还应该是自己亲身体验才能知道。

文章

  • 经过一年的思考,我重新梳理了我的印象笔记使用方法 - 少数派:不知道为什么,我对这类文章特别地喜欢。这篇文章带来的新意是对知识的六种分类,之前我自己没有考虑过。不要过度沉溺于研究工具,而忘记学习的初心。
  • 教授说没有写过一千行代码就别想上大公司,这种说法对吗? - 知乎:之前看到这个问题就想直接喷,写一千行代码怎么去大公司。看完其他人的回答,才发现又一次陷入到了思维定势。从数学角度来说,写一千行代码去大公司是一个必要不充分条件,去大公司确实需要写代码,一千行是被包括的,但可能远远不够。
  • iPhone X 发布会乔布斯录音的中译(或当代汉语现状) – 一天世界:一段英文白话翻译以及文言翻译对比,又一次体会到古典之美。
    • There’s lots of ways to be as a person, and some people express their deep appreciation in different ways. But one of the ways that I believe people express their appreciation to the rest of humanity is to make something wonderful and put it out there. You never meet the people, you never shake their hands, you never hear their stories or tell yours. But somehow in the act of making something with a great deal of care and love, something’s transmitted there. And it’s a way of expressing to the rest of our species our deep appreciation. So we need to be true to who we are and remember what’s really important to us. That’s what’s gonna keep Apple, Apple, is if we keep us, us.
    • 「李如一」译文:人生而有别,感恩之心亦可谓十人十色。创造神奇,示之于人,此为对人性感恩之一种也。彼二人或未曾握手相见,对各自生平事故复无相闻,惟细巧体贴之创造即足以千里传音。此即吾等人类传递感恩之心之法门也。故人必诚于其本色,忠于其所信。林檎之为林檎,端赖吾辈不忘初心也。愿与诸君共勉。
    • 「@东莞大唐和尚」译文:人与人的生活方式千差万别,表达感恩的方式也是多种多样。但我认为,做出一件绝妙的东西,才是向这个世界表达感恩的最最深刻的方式。你没见过那些人,没跟他们握过手,你没听过他们的故事,也没跟他们讲过自己的经历,但就是通过你倾注心血做出的这样一件东西,你传达给了他们一些东西。这是向其他人表达我们感激的最深刻的方式。我们需要真诚地面对自我,永远记住对自己最重要的东西是什么。苹果之所以是苹果,我们之所以是我们,正在于此。

视频

后记

这半年自己写的东西有点少,从第 10 期到这一次拖了好久。最初,是在阮一峰的鼓舞下开始这种形式的分享。不过后来由于种种原因,又展现出自己的本质。有些事情还是要坚持的,所以将这些存货发布出来。


2018 年消费指南

去年在总结中提到了一些知识付费的内容,今年将内容扩展,和大家分享我在这一年购买的实物以及虚拟产品。

实体购物

工作之后,感觉自己每个月留不下多少钱,很大一部分用来购买一些号称提高工作效率有关的物件。现在毕竟钱都花出去了,至少要装模作样地总结它们给我带来的提升。

键鼠

入职之后,地主只给我提供了一把锄头(Macbook Pro 13 with touchbar),长时间在蝴蝶键盘上敲击不是很愉悦的感觉。所以自己产生了购买键盘和鼠标的念头。

众所周知,机械键盘是码农的标配,用手指在键盘上噼里啪啦快速敲击,想想就有画面感。之前在上学的时候,我拥有一把 IKBC G87 的青轴键盘。IKBC 的优点在于价格便宜,不过和同学的 Filco 圣手对比,手感不是那么的清脆。而且本着一步到位的想法,这次准备购买的键盘可以贵一些。再加上一些其他的条件,将自己的选择限定在了 Filco 和 HHKB 上。众所周知,HHKB 的价格差不多可以买两个 Filco。最后是遇到了少数派的优惠活动,才痛下决心买了一个 HHKB Professional BT(其实是多送了少数派的贴纸而已)。

HHKB

评价 HHKB 最好的方式是引用其创始人和田英一下面这一段话:

美国西部的牛仔们,会将死去的马儿留在原地,但是仍然会扛着马鞍长途跋涉,穿越一望无垠的沙漠。因为马儿是消耗品,而马鞍却是与人体融合在一起的“知己”。我们要有这样的观念:现在,电脑是消耗品,键盘却是传递情感,陪伴我们一生的“挚友”。

HHKB 给人最大的感觉就是与众不同,一共只有 60 个按键。整个键盘长度和一张 A4 纸相当。看下面的布局图不难发现:

  1. 没有 F1-F12 功能按键
  2. 没有方向键
  3. Caps 键的位置上是 Control 键

HHKB_Pro2_Layout

咋一看,很难满足一般的工作需求。但是经过对工作方式的一些调整,可以很好的完成日程任务,而且键盘的手感不错(从 v2 上看到的形容是少女酥胸的手感,具体是不是我也没有体验过),长时间敲击没有疲劳感。我的编程主要在服务器上用 vim 完成,所以 hjkl 才是我的方向键,而且我也在 Jetbrain 的编辑器中安装了 vim 插件。对于其他情况下,使用 Karabiner Elements 对键盘进行一些改造(按住 Control 开启 vi 模式,hjkl 变成方向键),最后还可以用 Mac 系统自带的一些文本编辑相关的快就键。

Karabiner_Elements

有了键盘之后,不能没有鼠标。其实这里面也有两个选择:罗技 的 MX Master 2 和苹果的触摸板。不得不说, mnp 自带的触摸板用起来非常的爽快,但是单独购买触摸板价格也很感人,提前退出了购买范围。趁着双十一,在京东买下了 MX Master 2。

MX Master 2

看上面的图片可以知道,这是一款人体工程学的鼠标,而且有一些按键可以编程(配合软件)。支持蓝牙以及接受器连接,可以记忆三个设备。据说,还实现了在一台电脑上复制,再另外一台电脑上粘贴。总体用下来也是中规中矩,除了中间的滚轮阻尼感有点差之外(侧边的滚轮手感很好,但是不能修改成上下滚动的效果),也没有太多缺点。

Bose QC 35 二代

购买降噪耳机多少是出于无奈,离开学校的图书馆之后,很少能找到一个安静的地方,让自己静下心来干一些事情。特别是在开放的办公室中,不仅有其他同事的讨论声,还有空调的噪音。带上降噪耳机,在放上一曲喜欢的音乐,就感觉来到了另外一个世界。之前在知乎上看到的一个评价正好能形容这种感觉:

有多安静我来描述一下,孩子数学成绩不好,你在银行做经理,维护客户关系,不上不下,有房贷和车贷,每月按揭五千。你老婆在市人民医院做护士,她妈有尿毒症透析多年,她不爱你。你年轻的时候觉得能成一番事业,但现在也就这样,朋友们混的都比你好,你下班在车库停稳车,关掉引擎,呜一声安静了下来。太安静了,你生命中少有这么安静的时刻,你打算发十分钟呆再上楼吃饭。
以上就是 BOSE QC 35 的降噪效果测评。

所以充分证明,现在的耳机评测多么注重编故事的能力。说回来,带上耳机之后,空调之类的噪音基本上会被隔绝,其他人声只是轻微的减弱,就像他们在远处处聊天。总体来说,这副耳机达到了我的预期,也算是一笔合理消费。

米家宇宙

用这里来调侃一下,小米出的那么多智能家电。自己入手了米家台灯和小饭煲,搭配米家的 APP ,可以实现晚上当你拖着身体回来时有一盏灯为你亮起,清晨又有一锅粥等你去品尝。最近,米家 APP 通过捷径配合 Siri 使用,大大扩展了便利程度。未来真的快要来了。

mijia

年度虚拟产品

与上面提到的实体产品相反的,就是虚拟产品,比如软件、文章、教程、视频等。用虚拟产品更好的总结这些消费的特点。其实很多人会觉得这些东西不值得花钱,网上找盗版的即可。但自己赞同一个观点,给优秀的内容付费,才能激励作者分享更多的知识。

订阅服务

在这一年中持续付费的产品有滴答清单、印象笔记、SetApp。滴答清单是最早购买的 GTD 软件,对于初学者来说,这是一个大而全的软件,从清单、日历到番茄时间应有尽有。不过,我没有打算继续在新的一年为它付费,我对 GTD 软件的要求是有强大的过滤功能,而不是那一些花里胡哨的噱头功能。印象笔记是自己选择的主力笔记软件,之前使用为知笔记,但是他在 Mac 上的功能很少,也很久没有大的更新了,而印象笔记特别是在中国区独立之后,有很多大的动静。

Setapp 是一个软件集中订阅服务,简单来说,你订阅了这个服务,可以使用很多需要购买的 Mac App。自己目前常用的有 Moneywiz(记账软件,mac 和 ios 都可以使用)、Timing(自动记录 Mac 上软件使用时间,可以看成是一个统计工作效率的软件)、Bartender(隐藏状态栏,看起来更加清爽)、iStat Menus(在状态栏显示网速、cpu使用率等系统状态)、MarginNote(比较强大的 PDF 阅读软件)、Ulysses(Markdown 写作软件)。除此之外,SetApp 还提供了 100 多款软件,总的来说是超值的服务。

-w1252

买断服务

相比起付费服务,直接买断的软件就显得有点少。其中的原因有很多,最重要的是很多国外软件一次性买断价格是参考国外的物价,也许对于他们来说是一顿饭的价格,对应到国内就是好几百。

MacOS 上购买了 MWeb 3,也就是现在使用的 Markdown 软件。从二代开始入手使用,用来写一些文章的草稿。另外一点,用来管理博客文档也比较方便,可以一键将文章中出现的本地图片上传到图床。不过,上面提到 SetApp 中提供了更强的 Ulysses,也许明年的总结我会用 Ulysses 完成。

iOS 中,主要购买的是一些工具。Cloud Speed,测试不同国外云服务商的不同机房的速度,买了之后没有想象中的那么好。Taskmator,搭配 Mac 上的 Taskpaper 使用,之前想用他来做任务管理,不过后来放弃了。MoneyWiz 2,超值的记账软件,帮我养成了记账的习惯。之前用过网易有钱,无法忍受他的理财社区而卸载了。无相,一款神奇的浏览器,你可以指定一些其他网站的 CSS 样式(软件中有一个商店可以下载 CSS 文件),从而提升阅读体验,间接实现去除页面上的广告……

知识付费

罗振宇在 2016 年提出知识付费元年,可从我的角度来说,2018 才是我的知识付费元年。今年主要在两大平台进行内容消费,闲鱼以及少数派。

对的,你没有看错,闲鱼是我上半年的一个主要消费场所。有一句话,评价一个知识付费好不好,看它在闲鱼上有没有买就可以了。闲鱼上有很多倒卖的人,很可能是 N 道贩子,主要是通过百度云进行交易。比起原生的,体验是非常差的(得到的文章是长图片形式),胜在价格便宜(一两块到十几块不等)。可以用来简单判断一下内容,再决定是否需要去原网站购买。回过头来看,自己购买的绝大部分课程内容还静静地躺在百度云中……但也发现了一个精品课程,小能熊——陈华伟的《知识管理训练营》,这里面讲了很多老师自己使用 Mac 和 iPhone 进行知识管理的方法和体会。对于不是高阶的用户很是值得一看,原价是 99 元非常值得(可以在印象笔记公众号中找到)。我也做了一些笔记,一直比较忙,没有时间整理分享。搜索了一个其他人的笔记,大家可以看一下了解 21天知识管理训练营总结【笔记版1.0】 - 简书

课程大纲

至于在少数派中,就花了很多钱够买其中的专栏。少数派是我看了好几年的一个数字资讯网站,他们的口号是「少数派致力于更好地运用数字产品或科学方法,帮助用户提升工作效率和生活品质」。自己购买了他们的会员通讯 Power+ 1.0 以及还在持续更新中的 Power+ 2.0,具体的内容介绍可以查看这两个网页。如果你也是那种喜欢折腾软件的人,这个东西非常超值。任务管理系列(用 OmniFocus 3 搭建任务管理系统用更现代的方式做任务管理TaskPaper 使用指南),其实购买这三个完全是没有必要,你喜欢哪一个软件做 GTD,直接购买对应的教程就好了。最后也很推荐的是 从零开始做好个人记账,教你使用 Moneywiz 记一手明白账(原理通用,也可以使用其他软件。)

sspai


博客折腾记:修复七牛云测试域名失效问题

毕业之后开始工作快要 5 个月了,然后也快有 3 个月没有更新博客。其实文本编辑器中还有很多的草稿,但是一直没有力量驱动自己完结他们,并且分享出来。另外,这一段时间也不是完全没有分享。在这个页面的上方有一个 Tech 的标签,可以连接到我新搭的博客。受限于当前使用的 hexo 主题无法配置 latex 数学公式,所幸新开博客分享算法学习的笔记。大家感兴趣的可以访问一下,不过也没有太多的内容。

这次在博客公告中要告诉大家的确是另外一件事情。屋漏偏风连夜雨,不知道从什么时候开始,七牛云开始图片使用测试域名,毫无疑问这个博客的图片都挂了。自己也一直没有动力修复,让这一段时间访问我博客的小伙伴受累了。

今天研究了一下如何修复这个图床问题。官方有一个帮助页面如何配置域名的 CNAME - 七牛开发者中心,大概就是你的存储空间之前有一个测试域名(比如我的是 7xkpe5.com1.z0.glb.clouddn.com),现在不允许通过测试域名访问图片,需要绑定一个备案过的域名才可以。所以我们需要两个步骤完成改造:首先,给空间绑定一个域名(比如现在使用的是 media.xiang578.com );最后,在域名解析平台添加一个 CNAME,将你指定的域名转发到七牛的记录上。

完成上一步后,图片还是不能正常显示。因为之前的文章中,图片的链接都是以测试域名开头的,比如7xkpe5.com1.z0.glb.clouddn.com/15283589946007.jpg ,现在我们要将它改成 下面的形式 media.xiang578.com/15283589946007.jpg。简单的方法是打开文本编辑软件,然后使用查找替换功能,一个一个文件处理。显然这很无聊,而且进入 source/_posts 目录下利用 grep 7xkpe5 *.md | wc 统计了一个,我大概需要修改的有 142 处。

需要替换的字符串

幸运地是 linux 系统下有两大文本处理利器 sedawk。我们使用 sed 可以将一个字符串转换为另外一个字符串。网上搜索了一下用法,很快写了出来

1
sed -i -r "s/7xkpe5\.com1\.z0\.glb\.clouddn\.com/media\.xiang578\.com/g" *.md

这条命令中原始形态可以表示为 sed 's/原字符串/替换字符串/g'。其中参数 -i 代表替换文件中的所有匹配项,-r 代表批量替换支持扩展表达式。在原字符串和替换字符串中都出现了 \.,应为 .sed 命令中代表匹配任意单个字符,加上转移字符后可以代表它本身。最后 *md 代表对目录下的 md 文件进行处理。

运行完成之后,我们在统计一下测试域名和正式域名的数量,可以发现完美的解决了这个问题,图片又能正常显示。

修改后

所以,写下今天这一篇博客一切都是因为贫穷。如果有钱直接在主机上放置图片,有带宽提供出来访问,也就不会依赖七牛云了……


2019.11.09

为了减少博客依赖服务,参考 图床从七牛云迁移到腾讯COS折腾笔记 | 思想就是武器 将所有的图片全部从七牛上下载,利用 COS 存储。


字体的重要性

字体的重要性

最近开始工作,基本上都和终端打交道,碰到几个误认字符的尴尬场面,记录一下。

第一个遇到的问题发生在输入账户密码时,公司发的小册子上写的密码大概形式如xxxxxi|6xxx。由于打印密码的字体是黑体,难免产生疑问 | 到底是 I 还是 l?观察到的细节是 | 这个字符下面比其他的字符长,不过由于之前很少在密码中使用过这个字符,所以以为这个细节是区分Il 的。在密码错误 n 次后,眼光扫到键盘才发现回车键上面的 | 键。

第二个遇到的问题是在终端中,公司的堡垒机登陆比较复杂,一般都会写脚本来快速登陆。写完之后,运行指令的格式为

jump ip 'auth'

其中的 'auth' 部分为调用另外一个脚本生成一个二次验证的并作为 jump 命令的参数。其中这个 ' 符号被我认为是引号,后来查阅相关的 shell 命令(相关文章参考linux下命令执行结果作为其他命令输入参数 - CSDN博客),才明白为反引号(一般位于ESC 的下方)。

说完这两个问题,回到主题,每天和字母打交到,选着一款合适的字体是非常重要的。推荐一款我在几年前就使用的编程字体——Hack: A typeface designed for source code

Hack 字体示意

上图就是这款字体的示意,最喜欢的点是 0 中间有一个小竖点,非常的传神。 以至于现在 IDE 中的 0 不是想上面这样处理,我都感觉不会编程了。


博客折腾记:使用 Travis CI 自动部署博客

已切换到 Github Action

之前一周在封闭接受公司培训,最重要的任务是熟悉「项目开发全流程」。其中有一点:服务的稳定性。不知道为什么,前几天自己的博客崩溃了,输入域名只能看到 404 页面。当时以为是 Travis CI 的原因,所以进行了全面的一次排查:

  • 问题出现在 Github Pages 的 Custom domain 设置中。
  • 具体表现:通过 Travis CI 推送博客静态文件到仓库中的 master 后,下图框中的域名就会变成空的,导致无法访问。
  • 解决方法:在源文件的 source 目录下创建一个 CNAME 文件,写上你自己的域名。

Travis CI

其实看一眼就应该知道,我的博客是基于 hexo 搭建的,文件托管在 github 仓库中。不过,按照之前的设想博客应该在 Coding 中也有一份备份。后来由于一些原因,在利用 hexo 生成静态文件之后,自动推送到 Coding 上的命令不起作用。自己也没有时间去排查问题,所以最近访问速度有点慢。

传统的 hexo 博客更新过程是:在完成写作之后,利用命令行调用 hexo g && hexo d 来生成静态博客文件以及并推送到远端的仓库中。这种方法会产生三个痛点:

  1. 每一次修改源文件后都需要重新生成一边静态文件,当大量修改时,步骤就变得繁琐且无趣。
  2. 生成静态文件依赖电脑中的 hexo 和 node.js 环境,不方便在外出时临时写或修改博客。
  3. 博客源文件没有自动的备份功能,不符合安全原则。

Travis CI 是一种持续集成开发所使用的工具,在写作过程中引入他可以解决上面我提到的痛点。Travis CI 具体的含义也不是很清楚,直接介绍我是怎么使用的。

博客依赖 3 个 git 仓库:

和大部分人一样,这个博客的静态文件保存在 github 的 xiang578.github.io 仓库 master 分支中。但是,我还创建了一个新的分支 hexo,用来保存博客源文件。每一次修改博客源文件之后,我不在本地生成静态文件,而是利用 git 命令,将所有的修改内容推送到仓库中的 hexo 分支。Travis CI 服务监听到新的 push 时,会根据你的配置将 git 仓库拉倒他的服务器上,编译源文件成为静态文件,并推送生成的文件到指定仓库的指定分支中。而且,如果编译静态文件失败,他也会通过邮件通知你结果。

编译成功截图

流程

  1. 将 github 上存放静态博客源文件的仓库拉下来,利用 git checkout -b hexo 创建并进入新的分支,删除分支内所有的文件。
  2. 将博客源文件复制到第一步中的文件夹中。
  3. 添加一个 .travis.yml 文件,文件内容可以参考下一节 Travis-ci 配置文件。
  4. https://travis-ci.org/ 提供免费的持续集成服务,可以通过 github 登入,直接选择需要管理相关的项目。
  5. 第一次将源文件上传到 github 时,可能会遇到问题。主题 themes/xxx 是通过 git clone 下载的,无法直接 push 包含嵌套关系的 git 库。删除 themes/xxx/.git 正确的姿势是,最开始就使用 git modules 引用依赖库。所幸还能编辑 .git/config,添加下面几行代码解决:
  6. 打开 themes 对应的 github 网页,你会看到主题链接到其他仓库(其中 @commitid 控制对应的版本)
  7. 完成这样的设置,修改主题文件后,需要先将修改 push 到主题的仓库,然后在博客文件夹下 push 修改到远端仓库(修改依赖的 commitid)。最终,才能再网页上看到修改效果。

Travis-ci 配置文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
language: node_js
node_js:
- 9.11.1
cache:
directories:
- node_modules
before_install:
- export TZ='Asia/Shanghai'
- npm install hexo-cli -g
install:
- npm install
script:
- hexo clean
- hexo generate
after_script:
- git clone https://${GH_REF} .deploy_git # GH_REF是最下面配置的仓库地址
- cd .deploy_git
- git checkout master
- cd ../
- mv .deploy_git/.git/ ./public/
- cd ./public
- git config user.name "xiang578"
- git config user.email "xiang578@foxmail.com"
- git add .
# - git commit -m "Deploy at $(date +"%Y-%m-%d %T")"
- git commit -m "Travis CI Auto Builder at `date +"%Y-%m-%d %H:%M"`"
# Github Pages
- git push --force --quiet "https://${CI_TOKEN}@${GH_REF}" master:master
# Coding Pages
# - git push --force --quiet "https://xiang578:${Coding_TOKEN}@${CO_REF}" master:master

branches:
only:
- hexo

env:
global:
# Github Pages
- GH_REF: github.com/xiang578/xiang578.github.io
# Coding Pages
# - CO_REF: git.coding.net/xiang578/xiang578.git

hexo 两个错误

在这一次的过程中,又遇到两个本地编译 hexo 的错误,一同记录一下。错误表现如下:

1
2
3
4
5
6
7
8
9
ERROR Plugin load failed: hexo-renderer-sass
Error: Cannot find module 'node-sass'
at Function.Module._resolveFilename (internal/modules/cjs/loader.js:581:15)
...
ERROR Plugin load failed: hexo-renderer-scss
Error: Node Sass does not yet support your current environment: OS X 64-bit with Unsupported runtime (64)
For more information on which environments are supported please see:
https://github.com/sass/node-sass/releases/tag/v4.8.3
...

网上的建议是修改 npm 的源地址为淘宝的镜像,并且重新下载这两个包。

1
2
3
sudo npm config set registry https://registry.npm.taobao.org
npm install hexo-renderer-sass --save
npm install hexo-renderer-scss --save

Reference

ChangeLog

  • 180904:完成初稿