不敢开车的老司机

不敢开车的老司机

常说车开多了胆子会越来越小,写代码也是。其实不是老司机胆子小了,而是新手无知无畏罢了。

最近一个很简单的功能,我做了2-3天,要是在我刚毕业的是时候把这个任务交给我,啪啪啪,不是我吹牛,2-3小时我就搞定了!

直接看产出的结果可能没觉得怎么样,甚至还会觉得这么做不对,但我觉得其中的思考过程还是非常有价值的,所以想在这记录下来。

RingBuffer 在 Puma 中的应用

什么是 RingBuffer

环形缓冲区:https://zh.wikipedia.org/wiki/環形緩衝區

维基百科的解释是:它是一种用于表示一个固定尺寸、头尾相连的缓冲区的数据结构,适合缓存数据流。

底层数据结构非常简单,一个固定长度的数组加一个写指针和一个读指针。

RingBuffer

只要像这张图一样,把这个数组辦弯,它就成了一个 RingBuffer。

那它到底有什么精妙的地方呢?

我最近做的项目正好要用到类似的设计思路,所以翻出了以前在点评写的 Puma 系统,看了看以前自己写的代码。顺便写个文章总结一下。

知乎用户屏蔽插件

脑子是个好东西,希望人人都能拥有它

知乎是个很有意思的地方,而人与人之间有不同的观点是很正常的事情。

但有的人就很奇怪,一言不和就开始人身攻击了。

这两天就遇到一个奇葩的人。

Python 中的 MySQL 数据库连接池

从 Java 到 Python

本文为我和同事的共同研究成果

当跨语言的时候,有些东西在一门语言中很常见,但到了另一门语言中可能会很少见。

例如 C# 中,经常会关注拆箱装箱,但到了 Java 中却发现,根本没人关注这个。

后来才知道,原来是因为 Java 中没有真泛型,就算放到泛型集合中,一样会装箱。既然不可避免,那也就没人去关注这块的性能影响了。

而 C# 中要是写出这样的代码,那你明天不用来上班了。

 

同样的场景发生在了学习 Python 的过程中。

什么?数据库连接竟然没有连接池!?

完全不可理解啊,Java 中不用连接池对性能影响挺大的。

Python 程序员是因为 Python 本来就慢,然后就自暴自弃了吗?

 

突然想到一个笑话

问:为什么 Python 程序员很少谈论内存泄漏?

答:因为 Python 重启很快。

😂 说多了都是泪,我之前排查 Java 内存泄漏的问题,超高并发的程序跑了1-2个月后就崩溃。我排查了好久,Java GC 参数也研究了很多,最后还是通过控制变量法找到了原因。

如果在 Python 中,多简单的事啊,写一个定时重启脚本,解决…

偏光太阳镜的那些事

探索精神

我这人对待事物有一个习惯,一个东西只有把原理搞明白了,才会去相信它,才会去用它。

反之就会对它嗤之以鼻。因为国内无良商家实在太多,不去刨根问底,就容易交智商税。

 

例如朋友圈的微商,本质就是类似传销的金字塔模式,那些三无产品真的有人买?朋友圈见一个屏蔽一个。

 

还有之前流行的“大麦若叶”,功效被吹得那么神,还是来自于日本的正规品牌。

它还真让我困惑了很久,因为理论上,在日本、美国等地方相关法律健全,不太会有这种“神奇”的产品出现。

后来知乎上的解答让我豁然开朗,简单地说一下结论:

这东西的确有一定功效,而日本农产品不发达,所以产生了这个东西。

但是在中国不一样啊,蔬菜这么便宜,你为什么要花大价钱买这个呢?而且还这么难喝。

而且它的很多所谓的功效都是到了国内被吹出来的。

 

然后,偏光太阳镜也是一个传说中很神奇的东西,带上它开车就可以抗反光,让视野更清晰。嗯,一般价格至少100以上。

这不是逗我玩吗?电影院那种3D偏振眼镜5元就可以买一副了,不都是偏振吗?还能有什么区别?

于是,我就这样带着家里的3D偏振眼镜开了一年多的车…

我之前也一直以为那些偏光太阳镜是无良商家的虚假宣传,为了揭露他们的邪恶本质,我当然要去研究一下!

于是,就有了去年我在知乎提的一个问题:为什么偏光太阳镜可以抗反光?

工程师的情商

一件小事

有这么一件小事,总是觉得不值得一写,却又总是念念不忘,恐怕不写下来我就会一直惦记着这件事。

为 zsh 实现 fish shell 的效果

fish shell

很久以前就见过fish shell,很多人见到这两张图就会想去试一下:

Fish Shell Auto Suggestion Fish Shell Colors

fish shell炫酷在哪?

主要就是这两张图中的两个功能:智能提示 和 语法高亮。

 

为此我也试用过多次fish shell,但是每次都败了,因为还是有很多地方不习惯:

  • 无插件系统,功能上还是比oh-my-zsh少了很多
  • 不兼容bash语法,导致我之前的很多脚本无法运行

 

oh-my-zsh才是我的真爱!

那么问题来了,oh-my-zsh中有没有插件可以实现类似的功能?

答案是肯定的!

将群晖 NAS 安全地暴露到公网中

群晖 NAS

家里的群晖 NAS 已经用了一年了,好话就不多说了,谁用谁知道。一年内成功安利了三位朋友买了群晖。(群晖是不是要给我点推广费?)

去年开始运营商网络挟持很猖狂,各种嵌入广告,国内互联网公司也都纷纷上了 HTTPS。

我一个个人 NAS 也不太可能被盯上,但是在这种网络情况下,只要有人针对你,那么挟持你的相关信息是分分钟的。

所以我也开始在自家的 NAS 上折腾 HTTPS 了。

除了这块的教程,我也顺便也把 NAS 如何暴露到公网相关的教程都写一下,包含了很多个部分:光线猫破解,光纤猫改桥接,端口转发设置,DDNS 设置,NAS 设置等。

暴露到公网后用起来就很方便了,再配合 HTTPS,基本不用担心安全问题了。

API Blueprint Docker

API Blueprint

上次介绍的 API Blueprint 解决方案 虽然不错,但是有一些问题:

  1. 部署麻烦,需要装不少东西
  2. 文档更新后不支持自动部署
  3. 没有权限控制

以至于我们团队最后没有用这个方案,所以我想了下解决方案。

  1. 通过 Docker 镜像,解决部署问题
  2. 通过 Docker 镜像中的脚本,配合 Github Webhook 来实现自动化部署
  3. 还未实现

正好顺便学习一下 Docker,Docker 的书看过几本了,之前同事也做过分享,但还是那句话:实践出真知。

之前虽然了解各种概念,但是自己捣鼓后,才算是真正的理解。

2015年的那些事

迟到的年终总结

那天一位老友问我怎么还没写2015年总结?

为什么要等我的总结?

他说他也准备写,想先看看我的…

我突然想到了学生时代的一句话:喂,你作业做好了借我抄一下。

 

其实,今年写这么晚主要是在等一个时间点,因为一些事只能在这个时候才方便说。

现在时间点已过,我就随便说说吧。不像往年,我今年就不列自己看了多少书学了多少东西了,那样太俗。

(๑•́ ₃ •̀๑) 啊。。。别揭穿我,其实真相是,我今年真的没看几本书…

API Blueprint

对 API 文档的幻想

你对 API 文档有哪些需求?写起来方便看起来舒服?

这两个应该是文档最基本的需求了。

其实,前后端配合开发的时候,还常常会有这样一种需求:

“你接口定义好了吗?定义好了的话能不能先帮我做一个 Mock Server 让我先跑起来?”

Alfred2 插件:Hasher

工具化思维

最近在做的项目,需要频繁地转换 timestamp 到人类可识别的日期时间文本。之前一直在用一个 Chrome 的插件,可以快速转换各种格式,但是每次都要切换到 Chrome 实在是太不方便了,每次都要浪费1-3秒。这对一个懒人来说,是无法接受的。所以决定开始造工具了!

然后最近正好又买了正版的 Alfred2,也学了一点点 Python,那用 Python 给 Alfred2 做一个插件就再合适不过了!

源码和下载地址:传送门

自定义 JDBC Driver 连接公司数据库

DataGrip

DataGrip

JetBrains 家最近发布了新的数据库管理工具:DataGrip

Mac 上其实一直没有好用的数据库管理工具。Sequel Pro 一天一崩溃;MySQL 官方的各种快捷键很奇怪,而且只支持 MySQL;其他的就更别说了,根本没到可用这个级别。

DataGrip 就不一样了,用惯了 Intellij IDEA 后会非常熟悉。

DataGrip 的大部分功能(基本是所有功能,目前还真没发现什么不一样的)其实在 Intellij IDEA 里都有,那为什么还要额外装一个呢?

好吧,其实我是买了 JetBrains 家所有产品的授权,所以对我来说都不需要额外付钱了。

所以其实无论你是用 Intellij IDEA、 PyCharm 还是别的 JetBrains 家产品,都可以找到同样的数据库管理功能。

利用 PhantomReference 替代 finalize

问题来源

之前的一篇文章讲了 利用 WeakReference 关闭守护线程 ,守护线程一旦发现守护的对象不在了,就把自己清理掉。

这次的问题更棘手一些,假如一个对象有一些资源需要被关闭,那怎么处理?

很多人会说,这个简单啊!用 Java 的finalize

但在 Java 中的finalize真的设计得不好,一不小心就会引发很多问题。

解决 MHA 切换后导致应用无可用连接的问题

问题来源

环境:MHA + MySQL + c3p0

最近在一次 MHA 切换的时候,发现应用中的 c3p0 老连接一直在等待,而新进来的请求全部被 c3p0 拒绝了。

然后又过了很长时间,老的连接断开,然后恢复了正常。整个过程极其诡异。

利用 CDN 解决百度爬虫被 Github Pages 拒绝的问题

百度爬虫被 Github Pages 拒绝

前两天在知乎看到一个问题:如何解决百度爬虫无法爬取搭建在Github上的个人博客的问题?

我一看,这不是和我的情况一模一样吗?

我赶紧上去看了看我网站的统计信息:

Netty 自动重连

自动重连

用 Netty 写 Client 和 Server 的时候必须要去处理自动重连。

Server 端启动时的错误,要去不断重试。

Client 端不仅要处理启动时的错误,还要处理中途断开连接。

“秒杀”问题的数据库和SQL设计

问题的来源

上篇文章介绍了 ETL 场景下的高性能最终一致性解决方案,这次的问题也是一个常见的问题。

最近发现很多人被类似秒杀这样的设计困扰,其实这类问题可以很方便地解决,先来说说这类问题的关键点是什么:

  1. 一定要高性能,不然还能叫秒杀吗?
  2. 要强一致性,库存只有100个,不能卖出去101个吧?但是库存10000实际只卖了9999是否允许呢?
  3. 既然这里说了是秒杀,那往往还会针对每个用户有购买数量的限制。

总结一下,还是那几个词:高性能强一致性!

下文的所有解决方案是在 Mysql InnoDB 下做的。因为用到了很多数据库特性。其他的数据库或其他的数据库引擎会有不同的表现,请注意。

高性能、最终一致性的数据同步方案

问题的来源

先描述一下问题:

两个系统的数据需要做数据同步,可以是数据库到数据库,也可以是数据库到内存。要求高性能(速度快),最终一致性(数据不能错)。

2014年总结

一年一篇

又到了一年一篇时间了,今年真的有很多话想要说,也经历了很多很多很多,这些事是我在2013年完全想不到的。

但是没想到,我还是做了!