jmap 命令使用

jdk 自带的命令用来 dump heap info,或者查看 ClassLoader info,等等。

命令格式

jmap [OPTION] PID

使用实例

不加任何参数

命令

jmap pid

查看 pid 内存信息。

查看堆信息

jmap -heap pid

查看堆对象信息

统计对象 count ,live 表示在使用

jamp -histo pid
jmap -histo:live pid

查看 classLoader

jmap -clstats pid

生成堆快照

jmap -dump:format=b,file=heapdump.phrof pid

hprof 二进制格式转储 Java 堆到指定 filename 的文件中,live 选项将堆中活动的对象转存。

执行的过程中为了保证 dump 的信息是可靠的,所以会暂停应用, 线上系统慎用

文件可以用 jhat 分析。

错误

在运行 jmap 的时候可能遇到如下错误:

Attaching to process ID 18078, please wait...
Error attaching to process: sun.jvm.hotspot.runtime.VMVersionMismatchException: Supported versions are 25.131-b11. Target VM is 25.152-b38
sun.jvm.hotspot.debugger.DebuggerException: sun.jvm.hotspot.runtime.VMVersionMismatchException: Supported versions are 25.131-b11. Target VM is 25.152-b38
    at sun.jvm.hotspot.HotSpotAgent.setupVM(HotSpotAgent.java:435)
    at sun.jvm.hotspot.HotSpotAgent.go(HotSpotAgent.java:305)
    at sun.jvm.hotspot.HotSpotAgent.attach(HotSpotAgent.java:140)
    at sun.jvm.hotspot.tools.Tool.start(Tool.java:185)
    at sun.jvm.hotspot.tools.Tool.execute(Tool.java:118)
    at sun.jvm.hotspot.tools.PMap.main(PMap.java:72)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at sun.tools.jmap.JMap.runTool(JMap.java:201)
    at sun.tools.jmap.JMap.main(JMap.java:130)

解决办法就是保证 jmap 的版本 也就是 JDK 的版本和运行的 JVM 的版本,也就是 JRE 的版本一致。

我使用 Java VisualVM GUI 来查看当前进程使用的 Java 版本,或者直接 ps 查看进程,然后再使用对应的 jmap 的版本。

要保证 jmap 运行的版本和运行的 java 进程程序使用同一个的 JRE(JDK) 的方法就是在 Linux 下使用

sudo update-alternatives --config java

来配置保证使用相同的 Java 程序。

reference


2015-01-02 jmap , jstack , jdk , jvm , java

继续折腾 WNDR3800 之 shadowsocks

之前 也说过在 Openwrt 下使用迅雷远程下载,现在因为不想在 PC 端总是开着一个 shadowsocks 的程序,所以将 shadowsocks 安装到路由器端。然后还顺带解决一下 DNS 污染,和流量智能转发。

Shadowsocks

下载 编译好的 ipk

opkg update
opkg install libpolarssl
opkg install shadowsocks-libev_1.5.1_ar71xx.ipk

shadowsocks 安装后有三个命令,ss-local 启动 sock5 代理,ss-redir 启动透明代理,ss-tunnel 启动隧道。这里使用了 ss-local 和 ss-redir

# 编辑 vim /etc/shadowsocks.json
{
    "server":"『服务器 ipv4/ipv6 地址』",
    "server_port":8388, #服务器端口
    "local_port":1081, #本地 sock5 代理端口
    "password":"『密码』",
    "timeout":300,
    "method":"『加密方式』"
}

修改配置文件/etc/init.d/shadowsocks

START=95
SERVICE_USE_PID=1
SERVICE_WRITE_PID=1
SERVICE_DAEMONIZE=1
CONFIG=/etc/shadowsocks.json
start() {
    service_start /usr/bin/ss-local -c $CONFIG
	service_start /usr/bin/ss-redir -c $CONFIG
}
stop() {
    service_stop /usr/bin/ss-local
	service_stop /usr/bin/ss-redir
}

添加执行权限,设置开机启动

chmod +x /etc/init.d/shadowsocks
/etc/init.d/shadowsocks enable

pdnsd

opkg update
opkg install pdnsd

配置/etc/init.d/pdnsd.conf

global {
    #debug = on;
    perm_cache=1024;
    cache_dir="/var/pdnsd";
    run_as="nobody";
    server_port = 1053;   #使用 1053 作为 DNS 端口,默认是 53,一定要修改否则会跟默认 dnsmasq 冲突
    server_ip = 127.0.0.1;
    status_ctl = on;
    query_method=tcp_only;#最重要的配置,只使用 tcp 查询上级 DNS
    min_ttl=15m;
    max_ttl=1w;
    timeout=10;
}
server {
    label= "googledns"; #这个 label 随便写
    ip = 8.8.8.8;    #这里为上级 dns 的 ip 地址,要求必须支持 TCP 查询,相关说明见后文注解
    root_server = on;
    uptest = none;   #不去检测 dns 是否无效。
}

启用 pdnsd,并设置为开机启动:

/etc/init.d/pdnsd enable
/etc/init.d/pdnsd restart

完成!

dnsmasq 和 ipset

openwrt 默认安装的 dnsmasq 不支持 ipset,需要先卸载,换成 dnsmasq-full,输入一下命令查看 dnsmasq 版本,写着 no ipset 的就需要安装完整版。

dnsmasq -v

运行以下命令:

opkg update
opkg install kmod-ipt-ipset ipset ipset-dns
opkg remove dnsmasq
opkg install dnsmasq-full

dnsmasq-full 从这里 下载,设置 dnsmasq 对特定域名使用本地的 pdnsd 进行解析: 为了保持配置文件整洁,建议在 /etc/dnsmasq.conf 最后加入:

conf-dir=/etc/dnsmasq.d

然后新建 mkdir 目录 /etc/dnsmasq.d ,在里面加入一个 conf,名字任选。譬如 /etc/dnsmasq.d/fuckgfw.conf , 下面是我的文件内容,你可以按自己需要整理自己的:

#Google and Youtube
server=/.google.com/127.0.0.1#1053
server=/.google.com.hk/127.0.0.1#1053
server=/.gstatic.com/127.0.0.1#1053
server=/.ggpht.com/127.0.0.1#1053
server=/.googleusercontent.com/127.0.0.1#1053
server=/.appspot.com/127.0.0.1#1053
server=/.googlecode.com/127.0.0.1#1053
server=/.googleapis.com/127.0.0.1#1053
server=/.gmail.com/127.0.0.1#1053
server=/.google-analytics.com/127.0.0.1#1053
server=/.youtube.com/127.0.0.1#1053
server=/.googlevideo.com/127.0.0.1#1053
server=/.youtube-nocookie.com/127.0.0.1#1053
server=/.ytimg.com/127.0.0.1#1053
server=/.blogspot.com/127.0.0.1#1053
server=/.blogger.com/127.0.0.1#1053

#FaceBook
server=/.facebook.com/127.0.0.1#1053
server=/.thefacebook.com/127.0.0.1#1053
server=/.facebook.net/127.0.0.1#1053
server=/.fbcdn.net/127.0.0.1#1053
server=/.akamaihd.net/127.0.0.1#1053

#Twitter
server=/.twitter.com/127.0.0.1#1053
server=/.t.co/127.0.0.1#1053
server=/.bitly.com/127.0.0.1#1053
server=/.twimg.com/127.0.0.1#1053
server=/.tinypic.com/127.0.0.1#1053
server=/.yfrog.com/127.0.0.1#1053

#Google and Youtube
ipset=/.google.com/setmefree
ipset=/.google.com.hk/setmefree
ipset=/.gstatic.com/setmefree
ipset=/.ggpht.com/setmefree
ipset=/.googleusercontent.com/setmefree
ipset=/.appspot.com/setmefree
ipset=/.googlecode.com/setmefree
ipset=/.googleapis.com/setmefree
ipset=/.gmail.com/setmefree
ipset=/.google-analytics.com/setmefree
ipset=/.youtube.com/setmefree
ipset=/.googlevideo.com/setmefree
ipset=/.youtube-nocookie.com/setmefree
ipset=/.ytimg.com/setmefree
ipset=/.blogspot.com/setmefree
ipset=/.blogger.com/setmefree

#FaceBook
ipset=/.facebook.com/setmefree
ipset=/.thefacebook.com/setmefree
ipset=/.facebook.net/setmefree
ipset=/.fbcdn.net/setmefree
ipset=/.akamaihd.net/setmefree

#Twitter
ipset=/.twitter.com/setmefree
ipset=/.t.co/setmefree
ipset=/.bitly.com/setmefree
ipset=/.twimg.com/setmefree
ipset=/.tinypic.com/setmefree
ipset=/.yfrog.com/setmefree

#Dropbox
ipset=/.dropbox.com/setmefree

#1024
ipset=/.t66y.com/setmefree

#shadowsocks.org
ipset=/.shadowsocks.org/setmefree

#btdigg
ipset=/.btdigg.org/setmefree

#sf.net
ipset=/.sourceforge.net/setmefree

#feedly
ipset=/.feedly.com/setmefree

按照这种格式指定特定的域名走代理。 server=/google.com/127.0.0.1#1053的含义是 google.com 通过本地 1053 端口解析地址 ipset=/google.com/setmefree 的含义给 google.com 的数据包打上标记,一会配置iptables时会用到 接下来配置iptables,在/etc/firewall.user里加上两行

ipset -N setmefree iphash
iptables -t nat -A PREROUTING -p tcp -m set --match-set setmefree dst -j REDIRECT --to-port 1081

每条记录都需要跟一条 ipset 设置,不要忘了。作用是把打上了标记的数据包重定向到 ss-redir 的透明代理端口

root@OpenWrt:~# cd /usr/bin
touch shadowsocks-firewall
vi shadowsocks-firewall

修改文件内容

#!/bin/sh

#create a new chain named SHADOWSOCKS
iptables -t nat -N SHADOWSOCKS

# Ignore your shadowsocks server's addresses
# It's very IMPORTANT, just be careful.
iptables -t nat -A SHADOWSOCKS -d YOUR-SERVERS-IP-ADDRESS -j RETURN

# Ignore LANs IP address
iptables -t nat -A SHADOWSOCKS -d 0.0.0.0/8 -j RETURN
iptables -t nat -A SHADOWSOCKS -d 10.0.0.0/8 -j RETURN
iptables -t nat -A SHADOWSOCKS -d 127.0.0.0/8 -j RETURN
iptables -t nat -A SHADOWSOCKS -d 169.254.0.0/16 -j RETURN
iptables -t nat -A SHADOWSOCKS -d 172.16.0.0/12 -j RETURN
iptables -t nat -A SHADOWSOCKS -d 192.168.0.0/16 -j RETURN
iptables -t nat -A SHADOWSOCKS -d 224.0.0.0/4 -j RETURN
iptables -t nat -A SHADOWSOCKS -d 240.0.0.0/4 -j RETURN

# Ignore Asia IP address
iptables -t nat -A SHADOWSOCKS -d 1.0.0.0/8 -j RETURN
iptables -t nat -A SHADOWSOCKS -d 14.0.0.0/8 -j RETURN
iptables -t nat -A SHADOWSOCKS -d 27.0.0.0/8 -j RETURN
iptables -t nat -A SHADOWSOCKS -d 36.0.0.0/8 -j RETURN
iptables -t nat -A SHADOWSOCKS -d 39.0.0.0/8 -j RETURN
iptables -t nat -A SHADOWSOCKS -d 42.0.0.0/8 -j RETURN
iptables -t nat -A SHADOWSOCKS -d 49.0.0.0/8 -j RETURN
iptables -t nat -A SHADOWSOCKS -d 58.0.0.0/8 -j RETURN
iptables -t nat -A SHADOWSOCKS -d 59.0.0.0/8 -j RETURN
iptables -t nat -A SHADOWSOCKS -d 60.0.0.0/8 -j RETURN
iptables -t nat -A SHADOWSOCKS -d 61.0.0.0/8 -j RETURN
iptables -t nat -A SHADOWSOCKS -d 101.0.0.0/8 -j RETURN
iptables -t nat -A SHADOWSOCKS -d 103.0.0.0/8 -j RETURN
iptables -t nat -A SHADOWSOCKS -d 106.0.0.0/8 -j RETURN
iptables -t nat -A SHADOWSOCKS -d 110.0.0.0/8 -j RETURN
iptables -t nat -A SHADOWSOCKS -d 111.0.0.0/8 -j RETURN
iptables -t nat -A SHADOWSOCKS -d 112.0.0.0/8 -j RETURN
iptables -t nat -A SHADOWSOCKS -d 113.0.0.0/8 -j RETURN
iptables -t nat -A SHADOWSOCKS -d 114.0.0.0/8 -j RETURN
iptables -t nat -A SHADOWSOCKS -d 115.0.0.0/8 -j RETURN
iptables -t nat -A SHADOWSOCKS -d 116.0.0.0/8 -j RETURN
iptables -t nat -A SHADOWSOCKS -d 117.0.0.0/8 -j RETURN
iptables -t nat -A SHADOWSOCKS -d 118.0.0.0/8 -j RETURN
iptables -t nat -A SHADOWSOCKS -d 119.0.0.0/8 -j RETURN
iptables -t nat -A SHADOWSOCKS -d 120.0.0.0/8 -j RETURN
iptables -t nat -A SHADOWSOCKS -d 121.0.0.0/8 -j RETURN
iptables -t nat -A SHADOWSOCKS -d 122.0.0.0/8 -j RETURN
iptables -t nat -A SHADOWSOCKS -d 123.0.0.0/8 -j RETURN
iptables -t nat -A SHADOWSOCKS -d 124.0.0.0/8 -j RETURN
iptables -t nat -A SHADOWSOCKS -d 125.0.0.0/8 -j RETURN
iptables -t nat -A SHADOWSOCKS -d 126.0.0.0/8 -j RETURN
iptables -t nat -A SHADOWSOCKS -d 169.0.0.0/8 -j RETURN
iptables -t nat -A SHADOWSOCKS -d 175.0.0.0/8 -j RETURN
iptables -t nat -A SHADOWSOCKS -d 180.0.0.0/8 -j RETURN
iptables -t nat -A SHADOWSOCKS -d 182.0.0.0/8 -j RETURN
iptables -t nat -A SHADOWSOCKS -d 183.0.0.0/8 -j RETURN
iptables -t nat -A SHADOWSOCKS -d 202.0.0.0/8 -j RETURN
iptables -t nat -A SHADOWSOCKS -d 203.0.0.0/8 -j RETURN
iptables -t nat -A SHADOWSOCKS -d 210.0.0.0/8 -j RETURN
iptables -t nat -A SHADOWSOCKS -d 211.0.0.0/8 -j RETURN
iptables -t nat -A SHADOWSOCKS -d 218.0.0.0/8 -j RETURN
iptables -t nat -A SHADOWSOCKS -d 219.0.0.0/8 -j RETURN
iptables -t nat -A SHADOWSOCKS -d 220.0.0.0/8 -j RETURN
iptables -t nat -A SHADOWSOCKS -d 221.0.0.0/8 -j RETURN
iptables -t nat -A SHADOWSOCKS -d 222.0.0.0/8 -j RETURN
iptables -t nat -A SHADOWSOCKS -d 223.0.0.0/8 -j RETURN

# Anything else should be redirected to shadowsocks's local port
iptables -t nat -A SHADOWSOCKS -p tcp -j REDIRECT --to-ports 1081

# Apply the rules
iptables -t nat -A PREROUTING -p tcp -j SHADOWSOCKS

解释 iptables -t nat -A SHADOWSOCKS -p tcp -j REDIRECT --to-ports 8024 这里的 8024 必须和 OpenWrt 路由器 /etc/shadowsocks.json里的 local_port 一样,也就是说,如果 /etc/shadowsocks.json"local_port":1081, 那这里的 8024 也要改成 1081(如果照着我上面的本地端口填了 8080,这里就改成 8080)

配置成功后,chmod +x shadowsocks-firewall给其运行权限。

运行

 /usr/bin/shadowsocks-firewall

重启 dnsmasq 和 firewall 就可以实现流量自动分流了

/etc/init.d/dnsmasq restart
/etc/init.d/firewall restart

以后只要修改dnsmasq的配置文件就可以指定更多的地址走代理

可选方案 解决 dns 污染

这里比较方便的是,通过 ChinaDNS 就可以了。

和安装 ShadowSocks 一样,可以先通过 WinSCP 上传到路由器。

opkg install ChinaDNS-C_1.0.0_ar71xx.ipk  # 安装
/etc/init.d/chinadns start                # 运行
/etc/init.d/chinadns enable               # 开机启动

reference

  1. http://hong.im/2014/07/08/use-ipset-with-shadowsocks-on-openwrt/
  2. http://www.jianshu.com/p/4800eec60516
  3. http://blog.berry10086.com/Tech/Openwrt/openwrt-shadowsocks-ipset/
  4. http://www.shuyz.com/install-shadowsocks-on-hg255d-openwrt-and-config-nat.html
  5. http://hong.im/2014/03/16/configure-an-openwrt-based-router-to-use-shadowsocks-and-redirect-foreign-traffic/

2014-11-24 shadowsocks , openwrt , knowledge , shadowsocks-libev

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输入法

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

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

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

很多东西看官方的wiki就能看明白,今天折腾Rime输入法主要是在Windows下,解决了几个问题。

##词库 之前一直使用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
#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在文件头部分,除了系统预设词库之外,还导入了其他的细胞词库

  3. 码表中的词彚格式

    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

参考:

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

##修改配置文件定製指南

###更改候选词数 修改文件 default.custom.yaml

patch:
  "menu/page_size": 10

候选词最多支持10个。

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

参考链接

###小狼毫外观设定

参考链接

# 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) tab键上面,1左边的那个键 切换Rime输入方案 shift+delete 删除选中候选词 ctrl+ np 上下选词

参考链接


2014-11-21 输入法 , Rime

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

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

电子书

最近文章

  • Maven 插件学习之: shade 插件 maven shade plugin 插件允许把工程使用到的依赖打包到一个 uber-jar(单一 jar 包) 中并隐藏(重命名)起来。
  • Cinnamon 桌面下 Applets 推荐 使用 Linux Mint 一些时候,真的发现有些功能和配置真的非常舒服,以前也写过一篇文章说的是 Cinnamon 桌面自带的 nemo 文件管理器,这可能是我用过的所有系统中自带文件管理器让我用的最舒服的了。所以这里再总结一篇 Cinnamon 下好用的 applets 。
  • maven 相关的错误 deploy 遇到 400 错误
  • 设计模式之行为模式 设计模式的行为模式关注类和对象如何交互,以及如何负责对应的事务,也就是怎么定义类的行为和职责。
  • 启动挂载配置 fstab 文件 因为之前克隆系统 获知了 fstab 文件,用来在启动系统时挂载对应硬盘分区中的系统。打开我自己系统的文件之后也发现可以配置挂载其他 FAT 或者 NTFS 格式的 Windows 下的分区。而最近可能因为 SSD 挂掉的原因,系统无法启动,再次把 fstab 放到了重要的位置,所以才有了这样一篇文章,主要用来总结一下 /etc/fstab 文件的作用及配置。