Play Clash of Clans

玩部落冲突(Clash of Clans)也已经四个多月了,这是我第一个花钱在上面的游戏,不过最近因为给别人看COC乱点花了我1200左右的钻石,顿时玩下去的信心都没有了,既然没有动力了,就来总结一下吧,就当是个结束。

很早知道这个游戏,看到很多人玩,包括很多身边的同学。但是机缘巧合有一好友也开始玩,就带着我一起开始玩了,于是从暑假开始,到今天11/5,差不多正好4个月时间,除了魔兽争霸这个游戏,还真没有一个游戏能让我坚持玩这么长时间的。什么吸引我呢?这个游戏依靠策略,攻打的策略,守家的策略,让人欲罢不能。另外就是好友及部落机制。再次就是不想偷菜种菜那么没有头脑,收集金币及圣水都是需要一定的技巧。虽然被人乱点坑了很多金币,并且不得不赞扬游戏公司对游戏参数的设置,让人无比的想花钱,并且会让人觉得花的很值得。

Clash of Clans 8本阵型

Clash of Clans

Clash of Clans 双菱形

##一些网站 YouTube Channal https://www.youtube.com/channel/UCxNMYToYIBPYV829BJcmUQg 这个频道从低等级开始,一步一步升级,单人模式,攻击策略,防御策略很全面,可以关注。

之前几个布阵的网站都是直接从Google点进去的,根本记不住网址,所以用Google喽搜喽。

##关于钻石 关于钻石,网上很多说免费的钻石的,千万别信,基本都是假的,稍微真的就是去赚礼品卡的钱,然后用礼品卡买钻石。游戏中成就和清理地面的灌木石块等等都能获取一定的钻石,所以省着点用很快能够买到第三个农民500钻,等第四个农民1000钻其实也应该很快,如果不出意外2000钻的第五个农民我马上也能有了,只是。。。。

最后有一点,我在升级过程中吃了很多苦头,就是千万不要着急升级大本营,COC匹配对手有一定的算法,当时也Google了,会根据一定的算法,等级越高越不好打,所以最好在每一个大本营造完全不建筑并且升级到最高等级不能升级再升大本营。

##一些技巧

  • 搜寻对手时可以多搜寻一些,直到找到一个资源丰富的
  • 搜寻对手时注意观察阵型及金矿圣水收集器的位置,如果在外围可以轻松拿下。
  • 单人模式一定要留到升级完气球之后,一个气球搞定

参考:


2014-11-23 游戏 , Game , ClashOfClans

推荐网站之求字体:通过图片找字体

推荐网站之求字体:通过图片找到对应字体。

求字体 http://www.qiuziti.com/

最早遇到这个问题是我当时看陈墨评金庸系列书籍的时候封面上很漂亮的字体,下图中很大篇幅的小字。

赏析金庸

当时我还没遇见这个求字体网站,我是直接在百度知道问的别人,正好还有人知道,当时就记住了这个字体—-超世纪粗行书。 今天看到别人在摄影上加上了很好看的Logo,不禁想知道中文的字体,于是找到了这个网站。使用体验都很好,因而推荐出来。

找字体


2014-11-22 fonts , website , 推荐网站

Rime 输入法配置记录

Rime ime 是中州韻輸入法引擎 (Rime Input Method Engine),项目网址如下

按照官网给出的定义:Rime 不是一种输入法,是从各种常见键盘输入法中提炼出来的抽象的输入算法框架,Rime 涵盖了大多数输入法的共性,所以在不同设定下,Rime 可化身为不同的输入法用来打字。Rime 是跨平台的输入法软件,Rime 输入方案可通用于以下发行版:

  • 【中州韻】 fcitx-rime → Linux
  • 【小狼毫】 Weasel → Windows
  • 【鼠鬚管】 Squirrel → Mac OS X

很多东西看官方的 wiki 就能看明白,希望在你继续看下去之前,先看完下面几个网址:

相信如果你看完了官方的文档应该对 Rime 的安装和配置有了一定的了解,相信你在看得过程中也已经把 Rime 对应的版本安装上了,不同发行版的配置目录不同,通过 yaml 文件来配置,本文就在官方文档的基础上调整了一些配置来适应我的习惯。你不一定要完全按照我的配置来,不过我相信读完这篇文章,你一定能够随心配置出适合你自己输入习惯的 Rime。

安装

关于安装本来不想多说什么,基本上都是非常简单的,但是在 Linux 上的一些使用经验告诉我,Linux 发行版上的 Rime,fcitx-rime 要比 ibus 版本的要好用,虽然官方建议的是 ibus 版本,但是我还是建议你使用一下 fcitx 版本的,并且结合 fcitx 的扩展会开启一个新的世界,比如自带粘贴版历史,自带日韩语输入,这一切会让输入体验上升一个高度。

sudo apt install -y fcitx fcitx-rime

更多发行版见官网

几个输入法

在初了解 Rime 的时候经常会被 Rime 中的几个输入方案的名字搞混,其实这三个方案 朙月拼音,以及该方案的简体字版本,语句流版本都是同一个方案,不过在体验上略有差别,「语句流」风格的输入方案,在空格确认后,字词并不立即上屏,而是在输入句末的标点或者按下回车时整个句子才上屏。

配置文件

安装完之后, fcitx-rime 的大部分的配置文件在 ~/.config/fcitx/rime 下,如果是 ibus 版本,将对应的 fcitx 替换成 ibus 即是配置地址,如果打开该目录能看到一系列默认配置:

  • default.yaml: 全局配置
  • weasel.yaml : 发行版配置,比如 Windows 下就是 weasel
  • installation.yaml: 安装信息,其中包括了输入法数据备份的选项
  • *.schema.yaml: 各输入方案的配置文件,一般认为 schema 前的是输入方案的名字,一个输入方案可能对应多个字典
  • user.yaml: 用户状态

用户自定义:

  • *.dict.yaml : 用户字典
  • *.custom.yaml: 用户对 default.yaml, *.schema.yaml 等配置文件进行修改的配置文件

修改 Rime 配置文件并使之生效的方法很简单,保存文件,在 Rime 菜单中点击部署,就可以立即看到效果。Rime 建议使用 *.custom.yaml 的方式来自定义配置,因为 Rime 升级时会覆盖 Rime 自己的默认配置文件。

如果配置了同步目录,那么在同步目录能看到

  • *.userdb.txt : Rime 记录用户输入习惯的目录,分别记录了该输入方案下用户输入的历史纪录,备份级别:重要,具体文件内容解析可以参考后文
  • UUID/ : 用户配置同步目录

虽然现在很多手机上的输入法支持双语输入,但是桌面版的输入法除了搜狗,其他真的做的不行,但是 Rime 支持很多种双语切换时的处理方式。比如某些情况下一直在输入中文,但是中间要输入英文,通常的做法就是按下 Shift 来快速切换到英文模式,那么已经输入的内容怎么处理,Rime 可以选择:

  • inline_ascii: 在输入法的临时英文编辑区内输入字母、数字、符号、空格等,回车上屏后自动复位到中文
  • commit_text: 已输入的候选文字上屏并切换至西文输入模式
  • commit_code: 已输入的编码字符上屏并切换至西文输入模式
  • clear: 丢弃已输入的内容并切换至西文输入模式
  • noop: 屏蔽该切换键

具体设置如下:

ascii_composer:
  good_old_caps_lock: true
  switch_key:
    Caps_Lock: noop
    Eisu_toggle: clear
    Shift_L: commit_code
    Shift_R: commit_text
    Control_L: commit_text
    Control_R: noop

在设置自定义键的时候左右 Shift 和 fcitx 的快捷键有冲突。fcitx 设置中 额外的激活输入法快捷键双侧 Shift 改掉或者禁用。

对于左 Shift 是将候选词上屏,Enter 则是将输入的内容原封不动上屏,和我之前的习惯保持一致。

扩展词库

Rime 自带的联想词库有其自身的局限,但是 Rime 可以支持扩展词典,在 Rime 配置目录下新建 *.dict.yaml 这样的文件:

luna_pinyin.mywords.dict.yaml

在文件中输入

# Rime dictionary
# encoding: utf-8

---
name: luna_pinyin.mywords
version: "2019.08.23"
sort: by_weight
use_preset_vocabulary: true
# 從 luna_pinyin.dict.yaml 導入包含單字的碼表
import_tables:
  - luna_pinyin
...

# table begins

# 自定義的詞條
中州韵	zhong zhou yun	1
小狼毫	xiao lang hao
自动注音的词

这里需要注意的是 Rime 的码表,是 Tab 分割的三列,分别是文字、编码、使用频次,编码的定义以音节加空格分割。在制作自己的码表时一定要注意使用 Tab 分割。

编辑文件 luna_pinyin.custom.yaml

patch:
  translator/dictionary: luna_pinyin.mywords

部署,就可以快速导入到 Rime 中。

部署之后尝试输入词库中任意一个比较复杂的词,理论上应该看到正确的词出现,否则可能词库未加载成功,那么需要到 /tmp/rime* 目录下查看 ERROR 日志。

关于如何制作自己的词库,后来我又写了一篇文章,可以参考这里

同步配置

installation.yaml 文件中配置:

 sync_dic: "/path/to/rsync"
 installation_id: "mint-config"

然后点击 Rime 图标,部署,同步,这样用户配置和词库都会在配置的同步路径中。如果不修改 installation.yaml 配置,那么 Rime 默认会生成一个 UUID 的目录来存放同步文件

如果更换了电脑,将同步文件同步下来,然后配置 installation.yaml ,执行部署,同步,部署,然后配置、用户词库都可以了。

不同电脑之间的同步内容会以 installation_id 为名生成一个文件夹,文件的配置不会相互互通,但是用户字典是会同步的。

简单地来描述 Rime 的同步机制就是,不同电脑都会在同步目录中新建一个自己的 UUID 或者指定名字的目录,该目录下会保存所有自定义的修改,包括用户输入习惯的字典 *.userdb.txt .

在点击同步时,Rime 会,会把同步目录中其他的 userdb.txt 合并:

sync/*/*.userdb.txt = 合并到 => 本地 *.userdb = 导出为 => sync/<installation_id>/*.userdb.txt`
其他电脑 = 複製來或從網盤同步下載 => sync/<installation_id>/ = 本地同步 => sync/<installation_id>/ = 複製走或同步上傳到網盤 => 其他电脑同步

也就不需要手动去合并字典,只需要在合适的时机同步一下目录即可。Rime 会自动处理 userdb.txt 的合并问题。

不过需要注意的是 Rime 虽然会将自定义配置及词库同步到目录,但这只是一个单向的同步,其他机器依然需要手动处理自定义配置及词库。

userdb.txt 文件格式解析

在同步后可以在同步目录观察到 *.userdb.txt 每一种输入方案都会对应一个这样的文件,其中保存的是用户的输入历史,打开文件看很容易可以猜测到每一行中的含义:

# Rime user dictionary
#@/db_name	luna_pinyin.userdb
#@/db_type	userdb
#@/rime_version	1.2.9
#@/tick	425369
#@/user_id	mint-config
a 	吖	c=14 d=4.71446e-09 t=425369
a 	呵	c=1 d=6.28595e-10 t=425369
a 	啊	c=8781 d=3.80755 t=425369

解释:

  • c 输入法 commit 的次数 1,这个数可能因为输入时删除掉前面的词而减少,或者如果用户手动 shift+delete 删除掉候选词也会 reset 成 0

特殊配置

Rime 有一些默认设置,比如上下键选词,但是很少人打字的时候会把手移动到上下键去选词。

这里记录一下我自己的一些适配,用以调整我的习惯。

在修改 Rime 配置是,可以打开 Rime 的日志,对于我使用 fcitx-rime ,那么对应的日志在

/tmp/rime.fcitx-rime.*

一般有 ERROR,WARNING, INFO 三个文件。每一次部署时最好同时开着文件观察错误情况。

每一页候选词数量

~/.config/fcitx/rime 配置目录下,vi default.custom.yaml

patch:
  schema_list:
    - schema: luna_pinyin
    - schema: luna_pinyin_simp
    - schema: luna_pinyin_fluency
  menu:
    page_size: 6

切换简体繁体

Rime 自带繁简切换,菜单中就可以设置。

切换全角半角

Rime 自带

模糊音配置

https://gist.github.com/2320943 作为模板保存到 luna_pinyin_simp.custom.yamlluna_pinyin_tw.custom.yamlluna_pinyin_fluency.custom.yaml即可。

对于模糊音设置,官网有介绍 luna_pinyin 的实现方式

对于我,这条加上还是很有必要的

  • ining

参考链接

中英文混输

需要英文字典 ``

# 加載 easy_en 依賴
"schema/dependencies/@next": easy_en
# 載入翻譯英文的碼表翻譯器,取名爲 english
"engine/translators/@next": table_translator@english
# english 翻譯器的設定項
english:
  dictionary: easy_en
  spelling_hints: 9
  enable_completion: true
  enable_sentence: false
  initial_quality: -3

rime 相关命令

安装完 Rime 后,会安装 /usr/bin/rime_dict_manager 工具和 /usr/bin/rime_deployr 工具。

在运行这两个工具前需要关闭正在使用的 Rime 输入法,否则会占用需要的文件,而出现错误:

E0114 17:38:47.016017  9869 level_db.cc:291] Error opening db 'luna_pinyin.userdb' read-only.

rime_dict_manager

管理工具,在 fcitx 的配置目录 ~/.config/fcitx/rime/ 下运行

rime_dict_manager -l

会列出当前输入法配置方案。

导出词典

rime_dict_manager -e luna_pinyin export.txt

完整参数:

➜ /usr/bin/rime_dict_manager
options:
		-l|--list
		-s|--sync
		-b|--backup dict_name
		-r|--restore xxx.userdb.txt
		-e|--export dict_name export.txt
		-i|--import dict_name import.txt

rime_deployer

完整参数:

➜ /usr/bin/rime_deployer
options:
		--build [dest_dir [shared_data_dir]]
		--add-schema schema_id [...]
		--set-active-schema schema_id
		--compile x.schema.yaml [dest_dir [shared_data_dir]]

皮肤

自动生成主题皮肤

material 质感的主题,很好看

fcitx 官方制作

配置管理工具

Linux 终端配置 Rime 工具

OS X:

总结

到这里,就会发现 Rime 已经能够满足日场的需求,我用全拼,培养一段时间之后词库也很满足我的需求了。而到搜狗官网去看其介绍,细胞词库,云端输入,自动纠错,多彩皮肤,长词联想,网址输入,大部分的功能 Rime 都能做到,并且没有隐私问题,数据完全掌握在自己手里何乐而不为。

历史内容

之前一直使用 Google 拼音输入法,Google 拼音输入法能够导出一套用户长期积累的词库。我利用“深蓝词库转换“工具将 Google 拼音输入法导出的词库,大概 7 万多条转成 Rime 词库格式。然后开始菜单调出,小狼毫用户词典管理,选中 luna_pinying,点击“导入文本码表”导入词库。瞬间就可以从 Google 拼音输入法转移到 Rime 输入法。导入文本码表只是针对 Google 拼音输入法中由用户积累的词汇。一般只建议将最为关键,带有词频信息的词库使用“导入文本码表”的方法导入到 Rime 输入法。

关于词库,Rime 输入法的词库有两部分组成。以下摘自贴吧:

  • 一部分是由系统文本词库(一般以 xxx.dict.yaml 结尾)通过「重新部署 /deploy」生成的固态词典(一般以 xxx.table.bin 结尾),这部份词库因为在输入过程是固定不変的,所以存在用大量的词彚,也不允许用戸来直接删除。
  • 另一部分就是记录我们用戸输入习惯的用戸词典(一般以 xxx.userdb.kct)结尾。这部份词库的词彚,正常情况下是由用戸输入的时候随时生成的;其词彚可以动态调整,数量理论上来说不会特别多,也允许用戸自行删除(shift+delete)。

佛振同学在设计用户词典时,没有考虑到有导入大词库的需求,就按照估计用戸可能积累起来的词彚量,把容量设置为「十万」规模以提升存储效率,超过这个量性能则会下降。

佛振同学设计「【小狼毫】用戸词典管理」的初衷和真正目的,在於譲大家将自己従其他输入法中积累出来的用戸词彚,可以顺利地迁移到 rime 中。而不是譲你把其他输入法整个系统词库都搬进来。如今,「【小狼毫】用戸词典管理」这个功能和界面,已经被众多的小白同学稀里糊涂地滥用了。

如何正确的导入词库?答:新增固态词典引用多份码表文件

批量添加词汇,过去一直没有简易的做法。现在可以这样做:以【朙月拼音】为例,在输入方案裏指定一个新的词典名为 luna_pinyin.extended.dict.yaml

#luna_pinyin.custom.yaml
patch:
translator/dictionary: luna_pinyin.extended

然后在用户目录创建一个词典文件 luna_pinyin.extended.dict.yaml

#Rime dictionary
---
name: luna_pinyin.extended
version: "2013.04.22"
sort: by_weight
use_preset_vocabulary: true
import_tables:
  - luna_pinyin
...
# table begins
鸹鸹! gua gua 100

这样一来,部署【朙月拼音】这个输入方案时,将编译 luna_pinyin.extended 这部词典,而这部词典除了导入【八股文】词汇表之外,还导入了名为 luna_pinyin 的词典文件,即 luna_pinyin.dict.yaml 。被导入的词典文件只取其码表,忽略 YAML 段。

被导入的码表与本词典自带的码表共同决定了编码集合。当然也可以:本文件的码表完全为空,只用来按需合并多个外部码表文件。

luna_pinyin.extended 这个词典的神奇之处是:虽然luna_pinyin.schema.yaml 已设置为加载名为 luna_pinyin.extended 的词典,但配套的用户词典名却是「luna_pinyin」,即 Rime 自动取句点之前的部分为用户词典名,以保证按以上方法增补了词汇之后,不至於因为改变词典名而抛弃原有的用户词典。

请注意,此法的设计用途是合并编码方案相同的多份词典文件,而不是用来将不同的编码混在一起。

具体的示例代码可参考 https://gist.github.com/lotem/5443073

其中心思想提炼出来就是

  1. 先譲输入方案引用一个新的系统词库码表(佛振同学在 gist.github.com 上的示例中是 luna_pinyin.kunki.dict.yaml),即给输入方案luna_pinyin(明月拼音)打一个补靪,将调用的词库重置为luna_pinyin.kunki.dict.yaml
  2. 创建一个luna_pinyin.kunki.dict.yaml 的文件,加入好你需要导入的词彚(如「瑾昀」等等)。竝导入内置的系统词库(import_tables: luna_pinyin)。

其実佛振同学import_tables的这个做法,頪似於 C 语言编程中的#include 头文件。其目的和工作机制都是一様的。目的是引用头文件(或是系统预设词库)竝添加上自己的内容;工作机制是在编译(或是重新部署的时候),将链接到的不同的文本文件合并成一个文件,竝処理成二进制文件。

我另外要在佛振同学的基础上补充几点

  1. luna_pinyin.custom.yamlluna_pinyin.extended.dict.yaml都要放入用戸文件夹中
  2. 通过import_tables的方法,不仅仅可以导入预设的词典,甚至可以导入其他的自定义词典

以笔者为例子,我在朙月拼音输入方案中设定的词库名叫 luna_pinyin.extended.dict.yaml

而我 luna_pinyin.extended.dict.yaml 在文件头部分,除了系统预设词库之外,还导入了其他的细胞词库

import_tables:
  - luna_pinyin
  - luna_pinyin.extra_hanzi
  - luna_pinyin.sgmain
  - luna_pinyin.chat
  - luna_pinyin.net
  - luna_pinyin.user
  - luna_pinyin.cn_en
  - luna_pinyin.website
  - luna_pinyin.computer
  - luna_pinyin.place
  - luna_pinyin.shopping
  - luna_pinyin.sougou
  - luna_pinyin.kaomoji
  - mywords
  1. 码表中的词彚格式

    3.1 码表文件必须是 utf-8 无 bom 的编码。不能用 ansi,否则出来的词彚会乱码 3.2 Rime 对词彚的格式有着厳格的限定,其标凖形式是「词彚<tab>ci hui<tab>100」(方引号内部的部分,<tab>表示制表符(顕示为空白字符,不是空格))。

拼音码表的词彚格式是一个词彚占一行,不同的属性之间以制表符为间隔,编码之间以半角空格为间隔。従左往右依次是词彚、编码、词频。其中编码和词频是可省略的。也就是说

词彚<tab>ci hui」、「词彚<tab><tab>100」、「词彚

都是合法词库文件格式。

如果词频省略,那麼输入法会优先调用「八股文」(一个预设的中文语言模型,包含词彚和词频两穜属性)的词频,如果八股文找不到该词彚的词频,那麼这个词彚的词频就当成 0 来処理。

如果编码省略,那麼输入法在重新部署,将文本码表生成固态词典的时候,会根据词库中的单字来给词彚自动编码(如果是拼音的话,叫「给词彚注音」更妥帖) 比如词库中有

我<tab>wo
和<tab>he
你<tab>ni
我和你

四个 item,那麼「我和你」这个省略了编码的词彚在生成固态词典的时候会自动被注音上「wo he ni」。其中有一个特别需要注意的地方,那就是処理多音字。对於含多音字的词彚,我们要侭量避免譲输入法给他自动注音,因为会帯来错误的读音(比如「重庆」读成「zhong qing」)所以一般含多音字的词彚都要最好标注上读音。如果实在没辧法弄到读音也没関系。因为 Rime 已经给多音字的罕见音做了降频処理。従而使得多音字的罕见音不会参与词彚的自动注音。

関於自动注音的具躰的细节可以看 rime 的 wiki,这裏我就不多说了。総而言之,我廃话那麼多,是为了譲大家了解 rime 词库的工作机制,其実就为了告诉大家两句话:「在导入词彚的时候,一般来说只要加纯汉字就够了。含多音字的词,系统词库一般都有,如果没有才要考虑给这个词注上音。」

另外,系统词库中,已经包含了完整的单字注音和罕用读音降频処理,大家可以放心地导入纯汉字词彚,不用太过担心。(所以一定给要记得import_tables: luna_pinyin,来使自定义码表获得系统词库中的单字注音、含多音字词彚注音以及系统词彚词频)

关於楼主配置的多个词库挂接的方法实例,可参考由 rime-aca 友情提供的「朙月拼音·扩充词库」

下载地址:https://bintray.com/rime-aca/dictionaries/luna_pinyin.dict

参考:

其他词库下载 搜狗词库 来源

小狼毫外观设定

# weasel.custom.yaml
patch:
  "style/font_face": "华文行楷"  # 字體名稱,從記事本等處的系統字體對話框裏能看到
  "style/font_point": 16     # 字號,只認數字的,不認「五號」、「小五」這樣的

  style/horizontal: true      # 候選橫排
  style/inline_preedit: true  # 內嵌編碼(僅支持 TSF)
  style/display_tray_icon: true  # 顯示托盤圖標

一些快捷键

  • ctrl+grave (grave) tab 键上面,1 左边的那个键 切换 Rime 输入方案
  • shift+delete 删除选中候选词
  • ctrl+ n/p 上下选择候选词
  • Ctrl+b/f 类似于左箭头,右箭头,可以快速调整输入
  • Ctrl+a/e 贯标快速跳转到句首或者句末
  • Ctrl+d 删除
  • Ctrl+h 回退,删除
  • Ctrl+g 清空输入
  • Ctrl+k 删词,等效于 Shift + delete
  • -/+ 或者 tab 来翻页

更多的快捷键可以在 default.yaml 配置中看到。

一些问题

遇到 Rime 在 Deploy 字典时

Encode failure:

的问题,这些字典中的字符可能存在问题。

reference


2014-11-21 输入法 , rime , input-method , cjk , language , korean , japanese , chinese , squirrel , 小狼毫 , 中州韵 , 鼠须管

一系列计算机相关图书列表

代办事项中一直存在这样一个列表,一直没有完全吸收,这里先列着慢慢消化吧。不过大多数情况下都是直接豆瓣搜索看评价看了,也没有来得及维护这个列表,找个时间整理成豆列吧。

计算机系统与网络

  • 《图灵的秘密》
  • 《计算机系统概论》
  • 《深入理解 Linux 内核》
  • 《深入 Linux 内核架构》
  • 《TCP/IP 详解 卷 1:协议》
  • 《Linux 系统编程(第 2 版)》
  • 《Linux 内核设计与实现(第 3 版)》
  • 《深入理解计算机系统(原书第 2 版)》
  • 《计算机程序的构造和解释(原书第 2 版)》
  • 《鸟哥的 Linux 私房菜(基础学习篇 第三版)》
  • 《编码:隐匿在计算机软硬件背后的语言》
  • 《性能之颠:洞悉系统、企业与云计算》
  • 《UNIX 网络编程 卷 1:套接字联网 API(第 3 版)》
  • 《UNIX 网络编程 卷 2:进程间通信》
  • 《Windows 核心编程(第 5 版)》
  • 《WireShark 网络分析就这么简单》
  • 《WireShark 网络分析的艺术》

编程通用

  • 《编程原本》
  • 《代码大全》
  • 《UNIX 编程艺术》
  • 《代码整洁之道》
  • 《编程珠玑(续)》
  • 《编程珠玑(第 2 版)》
  • 《软件调试的艺术》
  • 《修改代码的艺术》
  • 《编程语言实现模式》
  • 《编写可读代码的艺术》
  • 《程序设计方法(中文版)》
  • 《解析极限编程:拥抱变化》
  • 《精通正则表达式(第 3 版)》
  • 《现代编译原理 : C 语言描述》
  • 《编译原理 : 原理、技术与工具》
  • 《重构:改善既有代码的设计》
  • 《七周七语言:理解多种编程范型》
  • 《调试九法:软硬件错误的排查之道》
  • 《程序设计语言:实践之路(第 3 版)》
  • 《计算的本质:深入剖析程序和计算机》
  • 《设计模式 : 可复用面向对象软件的基础》

算法与数据结构

  • 《算法(英文版 第 4 版)》
  • 《算法导论(原书第 2 版)》
  • 《Python 算法教程(第 2 版)》
  • 《算法设计与分析基础(第 3 版)》
  • 《学习 JavaScript 数据结构与算法》
  • 《数据结构与算法分析 : C++ 描述(第 3 版)》
  • 《数据结构与算法分析 : C 语言描述(第 2 版)》
  • 《数据结构与算法分析 : Java 语言描述(第 2 版)》

职业修炼与规划

  • 《大教堂与集市》
  • 《卓有成效的程序员》
  • 《程序员的职业素养》
  • 《程序员修炼之道:从小工到专家》
  • 《软件开发者路线图:从学徒到高手》
  • 《我编程,我快乐:程序员职业规划之道》
  • 《程序员的思维修炼:开发认知潜能的九堂课》
  • 《高效程序员的 45 个习惯:敏捷开发修炼之道(修订版)》

大师访谈

  • 《编程大师智慧》
  • 《编程大师访谈录》
  • 《编程人生 : 15 位软件先驱访谈录》
  • 《奇思妙想 : 15 位计算机天才及其重大发现》
  • 《图灵和 ACM 图灵奖(1966-2015 第五版) 纪念计算机诞生 70 周年》

架构 / 性能

  • 《微服务设计》
  • 《大数据日知录》
  • 《企业应用架构模式》
  • 《Web 性能权威指南》
  • 《SRE:Google 运维解密》
  • 《发布!软件的设计与部署》
  • 《高扩展性网站的 50 条原则》
  • 《大型网站技术架构:核心原理与案例分析》
  • 《恰如其分的软件架构:风险驱动的设计方法》
  • 《软件系统架构:使用视点和视角与利益相关者合作(第 2 版)》

Web 前端

  • 《高性能 JavaScript》
  • 《锋利的 jQuery(第 2 版)》
  • 《编写可维护的 JavaScript》
  • 《你不知道的 JavaScript(上)》
  • 《JavaScript 权威指南(第 6 版)》
  • 《JavaScript 语言精粹(修订版)》
  • 《JavaScript DOM 编程艺术 (第 2 版)》
  • 《JavaScript 高级程序设计(第 3 版)》
  • 《JavaScript 异步编程:设计快速响应的网络应用》
  • 《Effective JavaScript:编写高质量 JavaScript 代码的 68 个有效方法》
  • 《HTML5 权威指南》
  • 《HTML5 秘籍(第 2 版)》
  • 《HTML5 与 CSS3 基础教程(第八版)》
  • 《CSS 揭秘》
  • 《CSS 设计指南(第 3 版)》
  • 《CSS 权威指南(第 3 版)》
  • 《深入浅出 HTML 与 CSS》

Java 开发

  • 《Java8 实战》
  • 《Java 并发编程实战》
  • 《Java 性能权威指南》
  • 《Java 程序员修炼之道》
  • 《实战 Java 高并发程序设计》
  • 《Java 编程思想 (第 4 版)》
  • 《深入理解 Java 虚拟机(第 2 版)》
  • 《Effective java 中文版(第 2 版)》
  • 《Java 核心技术·卷 1:基础知识(原书第 9 版)》
  • 《Java 核心技术(卷 2):高级特性(原书第 9 版) : 高级特性》

.NET

  • 《精通 C#(第 6 版)》
  • 《深入理解 C#(第 3 版)》
  • 《CLR via C#(第 4 版)》

Python

  • 《集体智慧编程》
  • 《笨办法学 Python》
  • 《Python 基础教程》
  • 《Python 源码剖析》
  • 《Head First Python》
  • 《与孩子一起学编程》
  • 《Python 学习手册(第 4 版)》
  • 《Python Cookbook(第 3 版)》
  • 《Python 参考手册(第 4 版)》
  • 《Python 核心编程(第 3 版)》
  • 《Python 科学计算(第 2 版)》
  • 《利用 Python 进行数据分析》
  • 《Think Python:像计算机科学家一样思考 Python(第 2 版)》
  • 《Python 编程实战:运用设计模式、并发和程序库创建高质量程序》
  • 《Python 绝技:运用 Python 成为顶级黑客》
  • 《Flask Web 开发:基于 Python 的 Web 应用开发实战》

Android

  • 《Android 编程权威指南(第 2 版)》
  • 《移动应用 UI 设计模式(第 2 版)》

iOS

  • 《iOS 编程实战》
  • 《iOS 编程(第 4 版)》
  • 《Objective-C 高级编程》
  • 《Effective Objective C 2.0:编写高质量 iOS 与 OS X 代码的 52 个有效方法》

PHP

  • 《Head First PHP & MySQL(中文版)》
  • 《PHP 高级程序设计 : 模式、框架与测试》
  • 《深入 PHP:面向对象、模式与实践(第 3 版)》

C 语言

  • 《C 标准库》
  • 《C 和指针》
  • 《C 专家编程》
  • 《C 陷阱与缺陷》
  • 《C 语言接口与实现》
  • 《C 程序设计语言(第 2 版)》
  • 《C 语言参考手册(第 5 版)》

C++

  • 《C++ 标准库》
  • 《C++ 编程思想》
  • 《C++ 语言的设计与演化》
  • 《C++ 程序设计原理与实践》
  • 《C++ Primer (中文第 5 版)》
  • 《C++ 程序设计语言(第 1-3 部分)(原书第 4 版) 》
  • 《More Effective C++:35 个改善编程与设计的有效方法(中文版) 》
  • 《Effective C++: 改善程序与设计的 55 个具体做法(第 3 版)(中文版) 》

机器学习和数据挖掘

  • 《数据之巅》
  • 《矩阵分析》
  • 《机器学习》
  • 《统计学习方法》
  • 《机器学习导论》
  • 《推荐系统实践》
  • 《机器学习实战》
  • 《Web 数据挖掘》
  • 《深入浅出统计学》
  • 《模式分类(第 2 版)》
  • 《概率论与数理统计》
  • 《统计学习基础(第 2 版)(英文) 》
  • 《数据挖掘:概念与技术(第 3 版)》
  • 《数据挖掘:实用机器学习工具与技术(原书第 3 版)》
  • 《大数据:互联网大规模数据挖掘与分布式处理(第 2 版)》

数据库

  • 《SQL 应用重构》
  • 《SQL Cookbook》
  • 《高性能 MySQL (第 3 版)》
  • 《深入浅出 SQL(中文版)》
  • 《MySQL 技术内幕 : InnoDB 存储引擎(第 2 版)》
  • 《深入浅出 MySQL : 数据库开发、优化与管理维护》

测试

  • 《探索式软件测试》
  • 《有效的单元测试》
  • 《Google 软件测试之道》

项目与团队

  • 《人月神话》
  • 《快速软件开发》
  • 《人件(原书第 3 版)》
  • 《门后的秘密:卓越管理的故事》
  • 《极客与团队:软件工程师的团队生存秘笈》

求职面试

  • 《程序员面试金典(第 5 版)》
  • 《编程之美 : 微软技术面试心得》
  • 《金领简历:敲开苹果、微软、谷歌的大门》
  • 《剑指 Offer:名企面试官精讲典型编程题(纪念版)》

编程之外

  • 《暗时间》
  • 《数学之美》
  • 《赢得朋友》
  • 《精益创业》
  • 《批判性思维》
  • 《世界是数字的》
  • 《程序员的数学》
  • 《程序员健康指南》
  • 《禅与摩托车维修艺术》
  • 《关键对话:如何高效能沟通》
  • 《写作法宝:非虚构写作指南》
  • 《黑客与画家 : 来自计算机时代的高见》
  • 《软件随想录 : 程序员部落酋长 Joel 谈软件》
  • 《如何把事情做到最好:改变全球 9800 万人的人生指导书》

  • https://web.archive.org/web/20170728202627/http://www.pydevops.com/2016/11/03/%E7%A8%8B%E5%BA%8F%E5%91%98%E8%AF%BB%E4%B9%A6%E5%88%97%E8%A1%A8%E6%8E%A8%E8%8D%90/

2014-11-20 book , computer-science , network , linux

Nexus 5 不同版本

要给哥弄个Nexus 5,网上一查有美版的D820,还有国际版的D821。顺手做个笔记LG D820 VS LG D821。两个版本的LG Nexus 5在几乎所有的配置和外观上都没有任何的区别,主要区别在通讯模块上,一个支持GSM/CDMA/WCDMA/LTE,而另外一个不支持CDMA,具体的支持情况外媒梳理如下:

##北美Nexus 5版本 (LG D820):

  • GSM: 850/900/1800/1900 MHz
  • CDMA: Band Class: 0/1/10(这个频段是中国电信也支持的,其实大多数有CDMA的国家都在这个频段范围内,所以是支持所有CDMA频段的)
  • WCDMA: Bands: 1/2/4/5/6/8/19
  • LTE: Bands: 1/2/4/5/17/19/25/26/41

##Nexus 5国际版本,没有CDMA (LG D821):

  • GSM: 850/900/1800/1900 MHz
  • WCDMA: Bands: 1/2/4/5/6/8
  • LTE: Bands: 1/3/5/7/8/20

D820能够兼容AT&T、T-Mobile和Sprint的2G、3G和LTE网络;而D821则可兼容欧洲、亚洲等其余地区的网络频段。

D820美版需要破解才能电信4G,D821支持联通4G,中国移动所使用的是特有的频段,不支持

##D820(H)、D820(E)、D820(S)区别

D820(H)、D820(E)、D820(S)三者其实硬件都是一样的,就是RAM颗粒使用得不一样而已。 D820(H)是Skhynix(海力士)的RAM颗粒,D820(E)是Elpida(尔必达)的RAM颗粒,D820(S)是Samsung(三星)的RAM颗粒。查了下LG的内部资料,貌似D820(S)故障率最高,无故黑砖的同学警惕是否买到D820(S)的机器~

查看D820(H)、D820(E)、D820(S)方法~关机后,按音量“-”以及开机键同时开机,然后进bootloader查看~

参考:


2014-11-12 Android , Nexus , Google , LG

Vim 插件之:vim-repeat

这个插件顾名思义,就是扩展了 vim 中 . 的功能,有些插件实现的复杂修改(比如修改 surrounding) 用原生的 . 无法实现,而用该插件可以实现。

Installation

Plug 'tpope/vim-repeat'

Usage

既然提到了 vim.repeat 就不得不提到 vim 的 . 操作。

  • 比如使用 diw 删除了一个 word,那么可以使用 . 来删除另一个 word
  • 如果使用 dd 删除了一行,那么可以使用 5. 来删除 5 行
  • 如果在 insert 模式下,输入 hello!,那么使用 ESC 进入 normal 模式,那么移动光标,在另外一个地方使用 . 可以快速输入 hello!

而如果使用 :help repeat 就会发现 vim 支持的 repeat,日常使用的 . 只不过是冰山一角。. 被叫做 single-repeat,vim 还支持

  • multi-repeat
  • complex-repeat
  • using-scripts

等等复杂的 repeat commands。

multi-repeat

vim 中的 multi-repeat 其实日常中也非常熟悉,比如 :2,5g/^$/d 这种类似的命令就被叫做 multi-repeat. 解释一下这个例子,就是从 2 到 5 行中匹配 ^$ (也就是空行) 的内容执行命令 d (删除)。

恢复到这个命令最原本的模式

:[range]g[lobal]!/{pattern}/[cmd]

这条命令的也是就是在行数范围 range 的行上,匹配 pattern 的行,执行 Ex command(默认是 :p)

:[range]g[lobal]/{pattern}/[cmd]

这条命令的也是就是在行数范围 range 的行上,匹配 pattern 的行,执行 Ex command(默认是 :p)

:[range]v[global]/{pattern}/[cmd]

:g!

几点说明:

  • 对于上面在 pattern 两边的 / 可以使用其他非字母单字节字符来替换,比如使用 \, ", |, 等,这种方式使得可以在 pattern 中直接使用 /
  • 对于这里的 cmd 是 vim 的 Ex cmd,使用 :help ex-cmd-index 来查看

常见的 Ex 命令

  • :d delete lines
  • :g execute commands for matching lines
  • :grep run ‘grepprg’ and jump to first match
  • :help
  • :insert
  • :ls
  • :m move lines
  • :new create a new empty window
  • :w write to a file
  • :wq
  • :x
  • :z

比如替换文本中所有 pat 为 PAT

:g/pat/s//PAT/g

同样也可以使用 :%s/pat/PAT/g

g 命令是一个非常强大的命令,更多的可以参考下一章节的 g 使用。

complex-repeats

更为复杂的 repeat ,那就需要使用到 vim 内置的 register 0-9a-zA-z"

q{0-9a-zA-z"}           " 来开启录制
q                       " 之后使用 q 来停止录制
@{0-9z-aA-Z".=*+}       " 执行 Register 中的内容,`%` 当前文件名,`#` 可选文件名,这两个 Register 不能使用
@@                      " 执行上一次

Power of g

delete all line match pattern

:g/pattern/d

delete all lines not match pattern

:g!/pattern/d
:v/pattern/d

copy all match lines to the end of file

:g/pattern/t$

move all match lines to the end of file

:g/pattern/m$

copy all lines matching pattern to register ‘a’

qaq:g/pattern/y A

说明:

  • qaq 清空 Register a
  • y A 是 Ex cmd (:help :y), yank the current line into register A (append to register a)

reverse entire file

:g/^/m0

reference


2014-11-03 vim , vim-plugin , tpope , vim-repeat

Google推出inbox的一点思考

前一天就看到Rumor说Google有一款inbox产品要发布,没想到今天一早就看到+Sundar Pichai 发了一Po 说发布这个产品了。第一时间申请了邀请码,可是到目前为止也没见邀请码的踪影,也就只能从一些介绍,截图,视频中看到一些端倪,也由此写下一些想法。 inbox with nexus 6

##改变 Gmail发布已有10年,这十年时间Gmail改变了人们使用邮箱的习惯,而这十年变化的东西太多了,邮箱这一概念早被人说是应该淘汰的东西,时至今日邮箱却依然还是日常生活,工作交流中很重要的一个环节,可是邮箱亟需要变革,不仅是作为用户而言,并且是邮箱服务提供商应该需要思考的问题,越来越多的垃圾邮件,越来越多的不必要的邮件出现在用户的收件箱。而今天Gmail团队给自己的服务一个evolution,虽然Gmail已经在不久前启用了分类服务,能够帮助过滤一些无用的邮件,但可能Gmail团队觉得还不够,他们要以一种智能的方式帮助用户收发邮件—-他们在官方博客上这样说:designed to focus on what really matters. 用户只需要关注他们真正需要关注的。改变总是好的,无论这个改变是好是坏,改变意味着不满足与现有的状态,期望以一种理想的状态而活着。所以无论这个服务是否会像waze失败,最后总会有收获inbox web design 图片来自Verge

##UI设计、功能变革 那就来看看这个服务让人耳目一新的功能,首先让人眼前一亮的就是UI的设计,无论是Web还是移动端,简直就是Material Design的推广,靓丽的颜色配合着无比流畅的动画,首先让使用者的体验就很爽朗。其次就是博客中宣传的:Bundles,Highlights,Reminders, Assists, and Snooze,这三个功能构成inbox的主体,虽然Bundles就是Gmail中的不同Tab分类,Highlights应该也就是Gmail中的星,Reminders,Assists,and Snooze也就是Gmail中的工作表,可是inbox给使用者的感受是不一样的,让我想到的第一个词语就是GTD,getting things done. 这个词我第一次接触是在本科上的一门校外选修课上老师讲的。邮箱的作用难道不是这个吗?原来我们转了大大的一圈又回到了邮箱最原始的作用,帮助工作生活交流,Gmail原来一种时间乱糟糟的顺序给我们安排,而inbox是以一种事情重要程度,get more import things done first.

##背后算法 说到inbox这里,就不免让我想起Google Now,想起Andrew Ng的机器学习,Google Now是Google推出的个人助手,机器学习是一门公开课,我们这学期也在学,inbox能够提供这样的一种服务,Google要在背后做的运算是及其大的,如果要做的更加智能要做的或许更多,一封邮件重要与否,一封邮件对于某一个个人重要与否,都需要背后很强大的算法计算得出。而同样你得提供更多的数据,所谓的给予的多,收获的更多。当然这只是我片面的想象,背后的数据谁也不知道,除非你去问Google的employee们。

##inbox展望 inbox作为Gmail的一个革新,无论如何我都是期待的。目前我还没用过还不知道真正的使用体验也就不好说什么了。只是Google各种产品的混乱逻辑也我也弄不清楚了,虽然Gmail一直有工作表这样的功能,但却把GTD的功能做的很烂,虽然之前的keep也有GTD类似的功能,却放在类似记事本一样的笔记类应用中。当然那些产品加上那些功能也不是多此一举,却一时间让人无法选择。我原本以为所谓的inbox应该是所有服务的一个inbox,当然Gmail是最最最重要的一个inbox,而Google+的通知呢?在Web上无处不在的通知难道不应该出现在inbox中?Blogger的评论呢?YouTube制作者的评论呢?或许那死了的Reader还有那个你关注的博客又更新了一篇文章呢?我原本以为的inbox是那样的,最后的结果是我真的想多了。 但转念一想,或许不久Google Now能够给我们提供吧,期待未来。


2014-11-02 Google , inbox , Gmail

手机信号字母表示

使用智能手机的朋友会发现,在手机信号旁边或者上面都会有一些奇怪的字母,比如3G、E、H等等,这些字母都代表什么意思呢?哪种网络状态速度最快?下面让我们详细了解一下吧!

  1. G指GPRS,它是GSM移动电话用户可用的一种移动数据业务,GPRS可说是GSM的延续,是2.5G网络。在iPhone手机上显示O;2.5G的速度约为10KB/s

  2. E指EDGE网络,是增强型数据速率GSM演进技术,属2.75G,速度约为20KB~30KB/s

  3. 3G指普通3G网络,在国内常见的3G有电信的CDMA2000、联通的WCDMA和移动的TD-SCDMA三种,速度在2-7M;

  4. H见于联通的WCDMA手机上,指3G的升级版HSDPA网络,是3.5G,速度可达14.4M;

  5. H+常见于中国联通的WCDMA手机上,hsdpa的升级版HSPA+,是3.75G,速度可达21M-42M;

从网络速度对比来看,从慢到快依次是 G<E<3G<H<H+

日常生活中,在使用手机的过程中,我们常常可以在屏幕的状态栏上方看到网络信号的标识,大概有G/3G/T/E/1X/H/H+这些信号标识,这些标志代表什么含义呢?

移动卡网络信号有:G、E、T(或者H)

China Mobile

G:G是GPRS通用分组无线服务技术(General Packet Radio Service)的简称,它是GSM移动电话用户可用的一种移动数据业务,GPRS可说是GSM的延续。GPRS的传输速率可提升至56甚至114Kbps,理论上资费较为便宜。具有高速数据传输速度10倍于GSM、永远在线、仅按数据流量计费的特点;

E:E是EDGE(Enhanced Data Rate for GSM Evolution)增强型数据速率GSM演进技术的简称,是一种从GSM到3G的过渡技术,GPRS到第三代移动通信的过渡性技术方案(GPRS俗称2.5G, EDGE俗称2.75G.)。现在中国移动的EDGE网络已经基本上覆盖全国,只有一些较为偏僻的地区无法访问,其传输速率在峰值可以达到384kbps,现在比较主流的无线网络传输方式;

T或者(H):T是TD-SCDMA(Time Division-Synchronous Code Division Multiple Access时分同步码分多址)的简称,其是中国提出的第三代移动通信标准(简称3G),也是ITU批准的三个3G标准中的一个以我国知识产权为主的、被国际上广泛接受和认可的无线通信国际标准。现在使用的版本是R4版本,理论下载数值为378.2KB/S。

移动卡的用户在信号不稳定时,手机可以在这些信号中自动转换,使你的手机基本通话要求得以保证不间断。

联通卡网络信号有:G、3G(或者H或者3.5G)、H+

unicom

G:这里不用介绍了,和移动的G是一样的,但是由于联通建的基站比较少,所以网络信号质量很差,大家都不愿意用了;

3G(或者H或者3.5G):HSDPA(High Speed Downlink Packet Access)高速下行分组接入,是一种移动通信协议,亦称为3.5G(3½G),它的下载速度理论呢是可以达到7.2Mbp/s。在国内的三大运营商中,联通的3G是做的最好的,很多人用;

H+:HSPA+的英文全称为 High-Speed Packet Access+,增强型高速分组接入技术,是HSPA的强化版本,最高的下行21Mbps,大部分HSPA+手机基本都是支持5.76Mbps的最高上行速度和21Mbps或者28Mbps的最高下行速度,相比较HSPA的速度更快。总的来说HSPA+比HSPA的速度更快,性能更好,技术更先进,同时网络也更稳定,是目前LTE技术运用之前的最快的网络!其属于联通3.75G网络,当前的联通3G网络覆盖较好。显示H+的时候网速是最快的,理论速率可以达到42Mbp/s的,也就是联通目前畅销的WO卡。

电信卡网络信号有:1X、3G

telecom

1X:1X即CDMA1x,也就是我们通常所说的电信的2G网络,CDMA1X手机上网的传输速率可达每秒钟144Kb,不过在现在的情况下,1X已经满足不了用户的需求了。不过电信2G(也就是1X)对比其它运营商的G属于是最稳定的,也是表现最好的信号;

3G:3G是指3G信号CDMA2000(EVDO.A),EV-DO是3G CDMA的技术名称,在手机上为了简便显示为3G,它的速率理论上达到3M,但实际上一般只有1.6M左右。它是基于移动网络的多址分发同时提供网络流量,这3家运营商的3G网络信号覆盖最好最广的就是电信的3G信号了,他的实测下载速度峰值可以达到290Kb/s左右,电信卡的资费理论上也比较便宜点;

reference


2014-10-24 Android , Knowledge

照片添加GPS信息

在玩Ingress之后的很长一段时间内,我觉得如果照片没有地理位置信息是一种缺失,而去年买的 Nikon 单反没有GPS模块,Nikon提供的GPS模块需要单独购买价格不便宜并且携带不方便,于是我找到一种既便宜又简洁的方式可以给照片添加上GPS信息。

需要借助的工具:

具体原理是:按照时间顺序,将手机记录的GPS信息写入相机拍摄的照片中。

具体步骤:

  1. 调校相机时间和手机时间保持一致
  2. 使用My Tracks应用记录GPS信息,保证在使用单反拍照前后一直在记录。所以最好的办法是出门前打开My Tracks,回家关闭记录。
  3. 回到家,导出照片,安装GeoSetter软件,将My Tracks记录的文件导出为gpx文件
  4. 打开GeoSetter,全选所有照片,在菜单中找到和GPS文件同步,快捷键Ctrl+G,找到Android手机中Export出的gpx文件,同步。
  5. Ctrl+S,保存。

之后GPS信息就被写到照片文件中了。


2014-10-02 DSLR , GPS , Nikon , 摄影

优化 Java 中正则表达式

Java 中和正则相关的工具类都在 java.util.regex 包下,Java 使用了 Nondeterministic Finite Automaton (NFA),之所以称为非确定性是因为当正则匹配给定字符串时,每一个字符都可能和正则匹配多次。这个匹配引擎被广泛的使用在 .NET, PHP, perl, Python, Ruby 中。很多人认为正则处理很快,很强大,但是其实不同正则表达式的写法可能导致消耗的时间和空间相差几十倍甚至上百倍,当在一些移动设备中使用正则时则要更加注意。

在引擎内部,NFA 使用回溯(backtracking) ,通常情况下针对给定的字符串,正则表达式可能有不止一种匹配方式,那么规则匹配引擎则会尽可能匹配所有可能,直到失败。

为了更好的理解 NFA 和回溯,举一个简单的例子,比如有一个正则表达式 sc(ored|ared|oring)x ,而输入的文本是 scared

在开始的时候,引擎会查找到 sc,立即找到匹配的前两个字符,接着会从第三个字符开始匹配 ored,发现不匹配则会尝试下一个可能 ared,这个匹配成功,继续匹配后面的 x,此时发现不成功,那么引擎会回溯回去匹配第三个可能 oring,同样也没有匹配。那么引擎会回溯到第二个字符开始继续匹配 sc,直到匹配到字符结尾,然后抛出匹配失败。

优化回溯

在上面的例子中就能看到,NFA 使用回溯来进行规则匹配,上面的例子也非常容易发现回溯的一个问题,就是即使是很简单的例子,也可能导致回溯非常多次。由此可以想象,当回溯失控时对应用程序的性能影响。因此优化正则表达式的一个很重要的部分就是尽量减少回溯的次数。

因为回溯的存在,在遇到现实复杂情况时,正则匹配可能需要花费大量时间来寻找完整的匹配。更糟糕的是,引擎花费大量的时间来匹配从而宣告一次失败,这个时间远比一次成功的匹配来得多。因此需要记住的是,当测试正则表达式的速度时,测试正则匹配不成功的时候,而不是测试成功的匹配。而当测试匹配时,则尽量使用刚刚好匹配的字符串,因为这种字符串花费最长的时间。

避免重新编译正则

当程序中需要不止一次使用相同的正则表达式时,预先编译好后使用。先使用 Pattern.compile() 定义好,而不是直接使用 Pattern.matches()matches() 方法内部每一次都会重新编译表达式。

并且记住对于不同的输入字符串,我们可以复用 Matcher 对象,不过要记住调用 reset() 方法。

合理使用括号

如果不需要引用括号内容,使用非捕获型括号 (?:PATTERN),节省捕获时间,减少回溯使用状态数量。只在必要时使用括号捕获。

不要滥用字符组

比如在 [Ff] 应当使用不区分大小写的匹配而不是字符组

准确表达意图

正则表达式提供很多结构(字符组,多选结构,量词等等),很多结构功能存在重叠,做同一件事情可能有不同的表达,这个时候应该选择最适当的结构。比如多选结构和字符组,多选结构完全覆盖了字符组。(a|b|c|d)[abcd] 匹配的文本是一样的,但是多选结构用于处理“可能出现若干表达式”,而字符组是专门用于处理“可能出现若干字符”的,这种情况字符组效率要远远高于多选结构。所以应当选择用 [abcd].

避免多选结构多个分支匹配相同文本

正则非常灵活,往往同一个表达式可能匹配多种不同形态的文本,但是如果一个表达式中包含若干”能匹配不同形态文本“的子表达式,那么子表达式能匹配的文本有重叠就可能有效率问题。

比如 a+a+,再比如 [0-9]+\w+ 前后连接部分产生重复匹配问题。

两条规则

  • 凡是 regex1*regex2*(量词不限于*) 的表达式,都要尽力避免 regex1 和 regex2 能匹配相同的内容
  • 凡是 (regex1|regex2) 的表达式,尽力避免 regex1 和 regex2 匹配相同的内容

使用起始终止锚点

除非是及其罕见的情况,否则以 .* 开头的正则表达式都应该在最前面添加 ^ 或者 \A 如果这个正则表达式在某个字符串的开头不能匹配,那么显然在其他位置它也不能匹配。添加锚点无论是手工添加还是通过优化自动添加都能够配合开头字符 / 字符串 / 字串识别优化,节省大量不必要的工作

在表达式前面独立出 ^ 和 \G

^(?:abc|123)(^abc|^123) 在逻辑上是等价的,但是许多正则引擎指挥对第一个表达式使用 开头字符 / 字符串 / 字串识别优化。所以第一种办法的效率高得多

在表达式结尾独立出 $

确定起止锚点能够提高匹配速度,如果使用了 $ 标记结尾,正则引擎会从符合条件的长度开始匹配,而略过目标字符串中其他不关心的字符。

暴露尽可能多的匹配部分

xx* 替代 x+ 能够暴露必须匹配的 x 同样,用-----{0,2}代替-{5,7}

th(?:is|at) 替代 (?:this|that) ,就能暴露出必须的 th。如果不同的多选分支的结尾部分相同,我们也可以从右面”提取”。例如 (?:optim|standard)ization

对于传统 NFA,一旦匹配到结果就会停止。

用字符组代替分支条件

比如对于想要匹配的 a 或 b 或 c 或 d,使用 [a-d] 而不要使用 (?:a|b|c|d)。字符组比使用分支条件速度快。

谨慎使用点号

谨慎使用点号,星号,加号这样的元字符,只要能确定范围,就不要用点号。只要能够预测重复范围,就不要使用量词。

别过分依赖正则

正则表达式确实很强大,但是不要过分依赖正则。

最常见的错误就是,只要字符串操作就能完成,但非要用正则。比如判定一个字符串以什么开头,或者什么结尾,或者判断是否包含某一个子串。

reference


2014-09-30 java , regex

电子书

最近文章

  • 威联通折腾篇十七:Docker 安装的 NextCloud 升级、备份及恢复 之前有文章写过如何在 Qnap 上使用 Container Station 来安装 NextCloud,之前重度使用 NextCloud,里面已经存了近 70G 的文件内容,这次系统重建后,下载新的镜像,然后重新恢复,费了一番时间,主要是恢复数据库,然后还有本地挂载的文件,以及升级版本。
  • 威联通折腾篇十六:为 Container Station 更换镜像 都知道其实 QNAP 的 Container Station 就是 Docker,所以桌面版可以修改的国内镜像地址,QNAP 系统上也能够修改,可以快速提高镜像的下载速度。
  • 备份数据及系统思考 上周五 NAS 系统盘挂掉后一个周末都没有过好,一边忙着备份数据,一边要忙着整理系统应用和配置。早以前除了云端同步数据曾经出现过一两次数据丢失的情况,本地保存的数据还没有出现过管理的问题,系统会用 Clonezilla 全量备份,笔电数据则辅以同步工具 Dropbox 和自建的 NextCloud,平时丢数据的可能倒是比较小,但唯一疏漏的 NAS,因为硬盘不是一次性买全而是分了几次,所以从一开始就没有规划好存储与备份,而系统的酷狼 4T 盘可能经过几次家里停电,SMART INFO 出现警告的时候也没有来得及备份,所以造成了从周五开始突然系统盘只读状态,无奈只能立即开启 rsync 手动先将系统盘中的数据备份到其他盘。等到周日把损坏的系统盘送修之后,是时候来思考一下如何管理本地数据了。
  • QNAP 上 SQL server 数据备份 平时没有注意备份 QNAP 上系统盘的数据,从昨天开始系统盘突然只读,而无法写入,发现磁盘有问题了,无奈只能边申请售后,边想着怎么备份数据,还要恢复这么多的配置。
  • 云服务 free tier AWS