<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Python on KK的博客</title><link>https://spin6lock.github.io/tags/python/</link><description>Recent content in Python on KK的博客</description><generator>Hugo</generator><language>zh-CN</language><lastBuildDate>Sun, 14 May 2023 00:00:00 +0800</lastBuildDate><atom:link href="https://spin6lock.github.io/tags/python/feed.xml" rel="self" type="application/rss+xml"/><item><title> 视频分析</title><link>https://spin6lock.github.io/2023/05/14/%E8%A7%86%E9%A2%91%E5%88%86%E6%9E%90.html</link><pubDate>Sun, 14 May 2023 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2023/05/14/%E8%A7%86%E9%A2%91%E5%88%86%E6%9E%90.html</guid><description>&lt;p&gt;最近 AI 因为 ChatGPT 大热，正好找个由头玩一下，家里为了看娃装了个摄像头，一周拍的录像大概 20 多 G，可以拿来练练手。之前都是老婆人肉一个个看的，我这次先筛选出有动静的片段，后续老婆再看&lt;/p&gt;</description></item><item><title> 发布 pysproto</title><link>https://spin6lock.github.io/2021/09/04/%E5%8F%91%E5%B8%83pysproto.html</link><pubDate>Sat, 04 Sep 2021 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2021/09/04/%E5%8F%91%E5%B8%83pysproto.html</guid><description>&lt;p&gt;今天是个值得纪念的日子，我终于将适用于 Python 3 的 &lt;a href="https://github.com/spin6lock/python-sproto/"&gt;pysproto&lt;/a&gt; 成功上传到 pypi 了，顺便写一篇博客吐槽下 Python 的打包发布系统&lt;/p&gt;&#10;&lt;p&gt;依稀记得之前将 C 文件都放在 src 目录里，结果死活编译不过，于是都散装放在根目录了；然后 Pypi 要先发布测试包，再在网页操作一下，发布成正式包。setup.py 作为包的描述文件，long_description 字段还得用 reStructure Text 的格式写，不然就提交不过。pysproto 这个模块需要头文件，但是屡屡打包都没打进去。感觉打包模块在这里是 broken 的，&lt;a href="https://stackoverflow.com/a/35400299"&gt; 有个 stackoverflow&lt;/a&gt; 的回答精确描述了我的感受 : 在 sources 字段列举头文件会导致无法编译，distutil 不能区分 .h 文件，会试图编译对应的 .o 文件；在 headers 字段列举头文件会被忽略；在 setup 函数的 headers 字段里列举头文件能识别，但是不会被打进包里；在 Extension 函数的 include_dirs 里列举头文件，也不会打进包里。最后还是用了最高赞答案的 MANIFEST.in 文件里写一行 &lt;code&gt;graft 头文件路径 &lt;/code&gt;, 终于解决问题。。。&lt;/p&gt;</description></item><item><title> 博客中英文间添加空格</title><link>https://spin6lock.github.io/2020/02/01/%E5%8D%9A%E5%AE%A2%E4%B8%AD%E8%8B%B1%E6%96%87%E9%97%B4%E6%B7%BB%E5%8A%A0%E7%A9%BA%E6%A0%BC.html</link><pubDate>Sat, 01 Feb 2020 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2020/02/01/%E5%8D%9A%E5%AE%A2%E4%B8%AD%E8%8B%B1%E6%96%87%E9%97%B4%E6%B7%BB%E5%8A%A0%E7%A9%BA%E6%A0%BC.html</guid><description>&lt;p&gt;因为新冠病毒肺炎疫情，春节在家待了 11 天了，百无聊赖之下，想着优化一下老博客的排版。准备在中英文间补上空格，显得更美观一点，结果一篇博客都没改完就觉得累死了。。准备写工具来搞&lt;/p&gt;</description></item><item><title>git 与 redmine 联动</title><link>https://spin6lock.github.io/2020/01/17/git%E4%B8%8Eredmine%E8%81%94%E5%8A%A8.html</link><pubDate>Fri, 17 Jan 2020 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2020/01/17/git%E4%B8%8Eredmine%E8%81%94%E5%8A%A8.html</guid><description>&lt;p&gt;现在留给开发的提交权限越来越少了，qc 同学为了保证测试覆盖，让搞了个钩子，提交信息里必须写单号，没有 qc 单子的提交会弹钉钉警告，提错版本的也会被警告，心累。最近一周比较闲，决定用 Python 脚本做个类似的检查辅助一下&lt;/p&gt;</description></item><item><title>jemalloc 内存占用问题</title><link>https://spin6lock.github.io/2019/11/28/jemalloc%E5%86%85%E5%AD%98%E5%8D%A0%E7%94%A8%E9%97%AE%E9%A2%98.html</link><pubDate>Thu, 28 Nov 2019 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2019/11/28/jemalloc%E5%86%85%E5%AD%98%E5%8D%A0%E7%94%A8%E9%97%AE%E9%A2%98.html</guid><description>&lt;p&gt;最近，有部分越南的服务器内存不断上涨，怀疑是内存泄漏，因为框架提供的内存报告里，C 内存和 Lua 占用内存都不大，和 ps 里看的差好多。总内存在 12G 左右，C 和 Lua 的加起来约 4G，两者相差了 8G&lt;/p&gt;</description></item><item><title>罕见的 coredump 了</title><link>https://spin6lock.github.io/2019/10/26/%E7%BD%95%E8%A7%81%E7%9A%84coredump%E4%BA%86.html</link><pubDate>Sat, 26 Oct 2019 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2019/10/26/%E7%BD%95%E8%A7%81%E7%9A%84coredump%E4%BA%86.html</guid><description>&lt;p&gt;最近，项目在越南版删档测试的时候，发生了罕见的 coredump，简单记一点排查日志&lt;/p&gt;&#10;&lt;p&gt;目前的敏感词过滤是在 C 层做判定的，先后经过几个项目考验，模块算是比较稳定了。越南版有个需求，需要将敏感词里的空格去掉。比如敏感词是 abc，现在不能说 abc 了，但是玩家可以输入 a b c，所以需要过滤掉空格。有同事就对 C 层改了一下，判断 rune 是 32 的时候，就继续判断后续字符，出事的代码大致如下：&lt;/p&gt;</description></item><item><title>iPhone 惊爆史诗级漏洞？漏洞细节解析</title><link>https://spin6lock.github.io/2019/09/29/iPhone%E6%83%8A%E7%88%86%E5%8F%B2%E8%AF%97%E7%BA%A7%E6%BC%8F%E6%B4%9E-%E6%BC%8F%E6%B4%9E%E7%BB%86%E8%8A%82%E8%A7%A3%E6%9E%90.html</link><pubDate>Sun, 29 Sep 2019 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2019/09/29/iPhone%E6%83%8A%E7%88%86%E5%8F%B2%E8%AF%97%E7%BA%A7%E6%BC%8F%E6%B4%9E-%E6%BC%8F%E6%B4%9E%E7%BB%86%E8%8A%82%E8%A7%A3%E6%9E%90.html</guid><description>&lt;p&gt;最近 @axi0mX 提到 iOS 有一个不能修复的漏洞，命名 checkm8（读 checkmate），可以击穿 iPhone 4S 到 iPhone X 间的所有 iOS 设备。而且由于这个漏洞存在于只读的 bootrom 中，苹果应该没法通过系统更新来修复掉。他发布这个漏洞是为了让大家可以安全的在最新系统下越狱，这样系统更安全，开发者也有更大的空间。&lt;/p&gt;</description></item><item><title>线程数与游戏卡顿</title><link>https://spin6lock.github.io/2019/09/21/%E7%BA%BF%E7%A8%8B%E6%95%B0%E4%B8%8E%E6%B8%B8%E6%88%8F%E5%8D%A1%E9%A1%BF.html</link><pubDate>Sat, 21 Sep 2019 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2019/09/21/%E7%BA%BF%E7%A8%8B%E6%95%B0%E4%B8%8E%E6%B8%B8%E6%88%8F%E5%8D%A1%E9%A1%BF.html</guid><description>&lt;p&gt;在某天凌晨，欧美服出现了卡顿，但是服务器的 CPU 并不高，内部服务监控日志来看，是 clusteragent 的 mq overload 了，网卡 IO 从流量上来看，也没达到瓶颈。后来，对方 SA 说是参数配错了，8 核的机器配了 24 线程，改成 8 线程后重启，就不卡顿了。这里排查的时候用到了 tracetag，虽然有点麻烦，还是值得的。&lt;/p&gt;</description></item><item><title>技能问题引发内存泄漏</title><link>https://spin6lock.github.io/2019/08/09/%E6%8A%80%E8%83%BD%E9%97%AE%E9%A2%98%E5%BC%95%E5%8F%91%E5%86%85%E5%AD%98%E6%B3%84%E6%BC%8F.html</link><pubDate>Fri, 09 Aug 2019 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2019/08/09/%E6%8A%80%E8%83%BD%E9%97%AE%E9%A2%98%E5%BC%95%E5%8F%91%E5%86%85%E5%AD%98%E6%B3%84%E6%BC%8F.html</guid><description>&lt;p&gt;最近，在国服上的新职业技能，包含了一个弱点标记技能。玩家用技能打怪的时候，有一定概率给怪挂上弱点，下次攻击时用另一个技能攻击弱点，能爆出更大伤害。弱点的生命周期大约半分钟，过了以后弱点会消失，玩家退出场景后，弱点也会消失。&lt;/p&gt;</description></item><item><title>PullRequest 找原作者做 review</title><link>https://spin6lock.github.io/2019/07/30/PullRequest%E6%89%BE%E5%8E%9F%E4%BD%9C%E8%80%85%E5%81%9Areview.html</link><pubDate>Tue, 30 Jul 2019 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2019/07/30/PullRequest%E6%89%BE%E5%8E%9F%E4%BD%9C%E8%80%85%E5%81%9Areview.html</guid><description>&lt;p&gt;最近对代码库进行了一次全局替换，改了 150 个左右的文件，发了 PR 后需要找原作者确认一下，于是写了个工具做 git blame，&lt;a href="https://github.com/spin6lock/check_original_author"&gt; 地址在这里 &lt;/a&gt;&lt;/p&gt;&#10;&lt;p&gt;写完发现一个问题，如果只是新增一个函数，没有调用，是应该不用找原作者的 &amp;hellip;&amp;hellip; 但是，要识别出新增一个函数，没想象中容易，需要基于 ast 来做 diff，才能发现。也就是说，这个工具对于批量替换的功能，才比较好用，其他改动不太合适，蛋疼&lt;/p&gt;</description></item><item><title>Nginx 超时设定</title><link>https://spin6lock.github.io/2019/07/11/Nginx%E8%B6%85%E6%97%B6%E8%AE%BE%E5%AE%9A.html</link><pubDate>Thu, 11 Jul 2019 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2019/07/11/Nginx%E8%B6%85%E6%97%B6%E8%AE%BE%E5%AE%9A.html</guid><description>&lt;p&gt;最近针对公司的 goscon 网关发了一个 PR，新增了握手阶段的超时判定。现在回顾一下 Nginx 的所有超时判定，看看目前还缺少哪些判定&lt;/p&gt;&#10;&lt;p&gt;&lt;code&gt;**client_header_timeout （默认 60 秒）**&lt;/code&gt;&lt;/p&gt;</description></item><item><title>Rust 对协程的思考</title><link>https://spin6lock.github.io/2019/06/02/Rust%E5%AF%B9%E5%8D%8F%E7%A8%8B%E7%9A%84%E6%80%9D%E8%80%83.html</link><pubDate>Sun, 02 Jun 2019 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2019/06/02/Rust%E5%AF%B9%E5%8D%8F%E7%A8%8B%E7%9A%84%E6%80%9D%E8%80%83.html</guid><description>&lt;p&gt;最近和同事聊起来，觉得 lua 缺乏编译型语言的类型校验功能，还有变量拼写检查之类的，导致线上总是有低级错误出现。比如最近有一个是变量名拼写少了一个字母，导致某功能没开启；还有一个是变量传参时，之前测试多加了一个参数，测试完成后忘记删了，导致参数顺序不对。之前看过有个 TypeLua，没想到现在已经不怎么维护了，去搞了 Titan-lang，然而 Titan 也是 4 个月没动静了。。。&lt;/p&gt;</description></item><item><title>Python 的定时执行</title><link>https://spin6lock.github.io/2019/05/29/Python%E7%9A%84%E5%AE%9A%E6%97%B6%E6%89%A7%E8%A1%8C.html</link><pubDate>Wed, 29 May 2019 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2019/05/29/Python%E7%9A%84%E5%AE%9A%E6%97%B6%E6%89%A7%E8%A1%8C.html</guid><description>&lt;p&gt;最近手把手教妹子写 Python，被一篇博客误导了，这里记录一下。&lt;/p&gt;&#10;&lt;p&gt;妹子需要的是一个定时闹钟，到点往钉钉群里推个消息。她一顿搜索猛如虎，参照着其他人的博客，搞了一个 while：&lt;/p&gt;</description></item><item><title>Mesh 内存分配器的 mmap 小技巧</title><link>https://spin6lock.github.io/2019/03/05/Mesh%E5%86%85%E5%AD%98%E5%88%86%E9%85%8D%E5%99%A8%E7%9A%84mmap%E5%B0%8F%E6%8A%80%E5%B7%A7.html</link><pubDate>Tue, 05 Mar 2019 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2019/03/05/Mesh%E5%86%85%E5%AD%98%E5%88%86%E9%85%8D%E5%99%A8%E7%9A%84mmap%E5%B0%8F%E6%8A%80%E5%B7%A7.html</guid><description>&lt;p&gt;最近看了 &lt;a href="https://arxiv.org/abs/1902.04738"&gt; 一篇内存分配器的论文 &lt;/a&gt;，原理很简单，但是里面的数学论证还没看懂，这次先简单写一下原理和用到的 API。&lt;/p&gt;&#10;&lt;p&gt;内存分配器是用于封装操作系统提供的底层 API，给应用程序提供动态内存的。内存不断申请释放后，往往会形成内存碎片。当需要申请一段较大的内存时，当前剩余内存总量是够的，但是被当前申请的内存块隔断成一个个小隔间，内存分配器无法给出指定长度的内存。这时就只能向操作系统重新申请，或者对应用程序返回分配失败了。&lt;/p&gt;</description></item><item><title>尝鲜 svnup</title><link>https://spin6lock.github.io/2019/01/24/%E5%B0%9D%E9%B2%9Csvnup.html</link><pubDate>Thu, 24 Jan 2019 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2019/01/24/%E5%B0%9D%E9%B2%9Csvnup.html</guid><description>&lt;p&gt;最近有同事折腾了一下 svnup 的编译，终于可以在 Mac OS X 和 Linux 上面编译通过了，&lt;a href="https://github.com/lvzixun/svnup/"&gt; 仓库在这里：https://github.com/lvzixun/svnup/&lt;/a&gt;&lt;/p&gt;</description></item><item><title>HTTPPostmultipartform-data 支持</title><link>https://spin6lock.github.io/2018/12/24/HTTPPostmultipartform-data%E6%94%AF%E6%8C%81.html</link><pubDate>Mon, 24 Dec 2018 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2018/12/24/HTTPPostmultipartform-data%E6%94%AF%E6%8C%81.html</guid><description>&lt;p&gt;最近需要向平台发送录像文件，但是 Skynet 没有 multipart/form-data 的 Post 请求支持，写篇 blog 记录一下&lt;/p&gt;&#10;&lt;p&gt;所以只能有最原始的 httpc.request 方法了。请求头比较灵活，可以自己设置为 Content-type: multipart/form-data; 除了这个，还需要设置一个 boundary，用来分割需要同时上传多个 field 的情况。每个 field 长这样：&lt;/p&gt;</description></item><item><title>MongoDB 慢查询性能分析</title><link>https://spin6lock.github.io/2018/11/25/MongoDB%E6%85%A2%E6%9F%A5%E8%AF%A2%E6%80%A7%E8%83%BD%E5%88%86%E6%9E%90.html</link><pubDate>Sun, 25 Nov 2018 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2018/11/25/MongoDB%E6%85%A2%E6%9F%A5%E8%AF%A2%E6%80%A7%E8%83%BD%E5%88%86%E6%9E%90.html</guid><description/></item><item><title>redis 的 LRU 算法（二）</title><link>https://spin6lock.github.io/2018/09/24/redis%E7%9A%84LRU%E7%AE%97%E6%B3%95-%E4%BA%8C.html</link><pubDate>Mon, 24 Sep 2018 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2018/09/24/redis%E7%9A%84LRU%E7%AE%97%E6%B3%95-%E4%BA%8C.html</guid><description>&lt;p&gt;&lt;a href="https://www.cnblogs.com/Lifehacker/p/redis_random_lru.html"&gt; 前文再续，书接上一回 &lt;/a&gt;。上次讲到 redis 的 LRU 算法，文章实在精妙，最近可能有机会用到其中的技巧，顺便将下半部翻译出来，实现的时候参考下。&lt;/p&gt;&#10;&lt;p&gt;搏击俱乐部的第一法则：用裸眼观测你的算法&lt;/p&gt;</description></item><item><title>Skynet 服务热点火焰图分析</title><link>https://spin6lock.github.io/2018/09/15/Skynet%E6%9C%8D%E5%8A%A1%E7%83%AD%E7%82%B9%E7%81%AB%E7%84%B0%E5%9B%BE%E5%88%86%E6%9E%90.html</link><pubDate>Sat, 15 Sep 2018 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2018/09/15/Skynet%E6%9C%8D%E5%8A%A1%E7%83%AD%E7%82%B9%E7%81%AB%E7%84%B0%E5%9B%BE%E5%88%86%E6%9E%90.html</guid><description>&lt;p&gt;最近花了一周时间对场景服务进行热点分析，利用 &lt;a href="http://www.cnblogs.com/Lifehacker/p/skynet_flamegraph.html"&gt; 以前的火焰图工具 &lt;/a&gt; 做了一点微小的贡献，分享下心得（仓库地址在 &lt;a href="https://github.com/spin6lock/skynet_systemtap_set"&gt;https://github.com/spin6lock/skynet_systemtap_set&lt;/a&gt;）。&lt;/p&gt;&#10;&lt;p&gt;&lt;a href="https://github.com/cloudwu/skynet"&gt;Skynet 是一个轻量级的多线程在线游戏框架 &lt;/a&gt;。线程作为 worker，从服务的队列中抽出有消息的，然后处理上面的消息。服务间通过发消息来相互通信。目前服务主要是用 Lua 进行编写。&lt;/p&gt;</description></item><item><title>内存爆灯</title><link>https://spin6lock.github.io/2018/08/26/%E5%86%85%E5%AD%98%E7%88%86%E7%81%AF.html</link><pubDate>Sun, 26 Aug 2018 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2018/08/26/%E5%86%85%E5%AD%98%E7%88%86%E7%81%AF.html</guid><description>&lt;p&gt;最近产品在韩国上线了，上线后的第一个周末，人数最多的一服内存爆了，被 OOM 杀掉宕机了，很郁闷&lt;/p&gt;&#10;&lt;p&gt;机器用的 4 核 16G，aws 的实例。周四开服后，每天零点左右的在线人数峰值，内存都超过了 80% 的告警线。但是运营方不希望停机，于是采取了定时通过 GM 指令调用 gc，15 分钟回收一次内存，希望撑过峰值。到了周六晚，白天加班回到家，有点松懈了，就没再盯着内存曲线看，结果一不留神就爆了。。。峰值从 78% 飙升到 91%，只用了 7 分钟，定时 gc 没赶上，就这样挂了&lt;/p&gt;</description></item><item><title>时区问题</title><link>https://spin6lock.github.io/2018/07/30/%E6%97%B6%E5%8C%BA%E9%97%AE%E9%A2%98.html</link><pubDate>Mon, 30 Jul 2018 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2018/07/30/%E6%97%B6%E5%8C%BA%E9%97%AE%E9%A2%98.html</guid><description>&lt;p&gt;最近，游戏要上国外运营了，搞完就算告一段落了放下种种不舍，搞好时区的问题，好好的送它一程吧&lt;/p&gt;&#10;&lt;p&gt;受时区影响的问题主要分两类，一类是运营活动，一类是特殊玩法的开启。每天定时刷新的本来就有考虑时区，略过不表&lt;/p&gt;</description></item><item><title>与机器共生</title><link>https://spin6lock.github.io/2018/06/22/%E4%B8%8E%E6%9C%BA%E5%99%A8%E5%85%B1%E7%94%9F.html</link><pubDate>Fri, 22 Jun 2018 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2018/06/22/%E4%B8%8E%E6%9C%BA%E5%99%A8%E5%85%B1%E7%94%9F.html</guid><description>&lt;p&gt;最近写代码比较少，干脆分享一点八卦，博诸君一笑 :)&lt;/p&gt;&#10;&lt;p&gt;几年前，在 GitHub 上建了几个 golang 的项目，主要是练手用的，也没几个人关注。最近几天，忽然几个仓库同时收到 PR，&lt;a href="https://github.com/spin6lock/go_mud/pull/4"&gt; 类似这样的 &lt;/a&gt;，大意就是对仓库跑了下 gofmt，其他别的都没干，请合并修改。然后在 issue 里写明了项目的地址，原来还是用 golang 写爬虫做的。自动用 GitHub 的 API 爬取 golang 的仓库，clone 到本地，跑完 gofmt 后，看看有没有修改，有修改就提交 PR。&lt;/p&gt;</description></item><item><title>bug 狩猎</title><link>https://spin6lock.github.io/2018/06/20/bug%E7%8B%A9%E7%8C%8E.html</link><pubDate>Wed, 20 Jun 2018 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2018/06/20/bug%E7%8B%A9%E7%8C%8E.html</guid><description>&lt;p&gt;最近需求少了，终于有时间修一下底层的 bug，做一点工具方便查 bug，写篇文章简单记录一下。&lt;/p&gt;&#10;&lt;p&gt;一是优化了一个玩法进程的启动速度。这个玩法需要用战力做匹配，玩家按战力分段放进不同的桶里，每个桶用 skiplist 组织。启动服务器的时候，会遍历所有玩家，放进对应的桶里，方便正式开放的时候进行搜索匹配。之前是遍历策划配置的战力分段表，高端玩家几乎要遍历完整个表才能进到桶里。现在改成了二分查找，匹配速度提高了好多&lt;/p&gt;</description></item><item><title>LessonLearned</title><link>https://spin6lock.github.io/2018/04/21/LessonLearned.html</link><pubDate>Sat, 21 Apr 2018 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2018/04/21/LessonLearned.html</guid><description>&lt;p&gt;最近，中兴 ZTE 违反美国商务部禁令，向伊朗出售敏感技术，被美国下达长达 7 年的禁止令，教训十分深刻。以诚待人，信守承诺，才能在商业社会站稳脚跟。&lt;/p&gt;&#10;&lt;p&gt;还是说说最近自己上的一课吧。上了港台服以后，奇奇怪怪的问题比较多。其中之一是玩家被异常登录了。现象是玩家登录游戏，提示账号被异常登录。这种现象本来应该在玩家顶号操作时，被顶号的设备上出现的。不应该在正在登录的活跃客户端上显示&lt;/p&gt;</description></item><item><title>下划线引起的血案</title><link>https://spin6lock.github.io/2018/03/11/%E4%B8%8B%E5%88%92%E7%BA%BF%E5%BC%95%E8%B5%B7%E7%9A%84%E8%A1%80%E6%A1%88.html</link><pubDate>Sun, 11 Mar 2018 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2018/03/11/%E4%B8%8B%E5%88%92%E7%BA%BF%E5%BC%95%E8%B5%B7%E7%9A%84%E8%A1%80%E6%A1%88.html</guid><description>&lt;p&gt;最近公司搬迁，所有虚拟机都要重新部署，累死了。然后 Python 一堆依赖以前没管理好，直接装全局位置，也忘记导出一份版本号到新机器来安装。这是祸根&lt;/p&gt;&#10;&lt;p&gt;换到新机器后，Skynet 和 Golang 相关应用都跑起来了。但是 Python 写的内部应用有点问题，网站认证后，认证用户名 valid_username 一直传不到应用里。检查过内部 Oauth 的代码，以及 Nginx 的转发配置，都没有问题。最终通过重放请求定位到是 Gevent 丢掉了这个参数。同事帮忙翻了下 &lt;a href="http://www.gevent.org/whatsnew_1_2.html"&gt; 更新日志 &lt;/a&gt;，发现因为安全问题，带下划线的变量不再传递了，参考 &lt;a href="https://github.com/gevent/gevent/issues/819"&gt;issue 819 &lt;/a&gt; 和 &lt;a href="https://github.com/gevent/gevent/issues/775"&gt;issue 775&lt;/a&gt;&lt;/p&gt;</description></item><item><title>Intel 的 CPU 漏洞：Spectre</title><link>https://spin6lock.github.io/2018/01/14/Intel%E7%9A%84CPU%E6%BC%8F%E6%B4%9E-Spectre.html</link><pubDate>Sun, 14 Jan 2018 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2018/01/14/Intel%E7%9A%84CPU%E6%BC%8F%E6%B4%9E-Spectre.html</guid><description>&lt;p&gt;最近觉得越来越忙，写博客都没精力了。一定是太沉迷农药和刷即刻了&lt;/p&gt;&#10;&lt;p&gt;17 年年底，18 年年初，Intel 被爆出了 Meltdown（熔断）和 Spectre（幽灵）漏洞。等 Spectre 攻击的 POC 出来以后，&lt;a href="https://github.com/Eugnis/spectre-attack"&gt; 去 github 围观了一下 &lt;/a&gt;，真的非常精妙，好想贴上来分享一下。&lt;/p&gt;</description></item><item><title>git 和 redmine 同步</title><link>https://spin6lock.github.io/2017/11/25/git%E5%92%8Credmine%E5%90%8C%E6%AD%A5.html</link><pubDate>Sat, 25 Nov 2017 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2017/11/25/git%E5%92%8Credmine%E5%90%8C%E6%AD%A5.html</guid><description>&lt;p&gt;最近实现了 github 以及内部的 gitbucket 与 redmine 的同步。&lt;/p&gt;&#10;&lt;p&gt;redmine 是内部使用的一套工单系统，用于跟踪 bug 和需求，由于最近同时开发的版本比较多，在不同分支的提交容易漏掉。现在改为用 redmine 的工单跟踪需求和 bug 修复，提交的时候，只要在提交日志里写上单号，机器人就可以将提交信息同步到表单，可以方便的跟踪到提交有没有漏提交到指定分支。&lt;/p&gt;</description></item><item><title>syslog 日志打印</title><link>https://spin6lock.github.io/2017/09/03/syslog%E6%97%A5%E5%BF%97%E6%89%93%E5%8D%B0.html</link><pubDate>Sun, 03 Sep 2017 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2017/09/03/syslog%E6%97%A5%E5%BF%97%E6%89%93%E5%8D%B0.html</guid><description/></item><item><title>redis 的 LRU 算法（一）</title><link>https://spin6lock.github.io/2017/07/31/redis%E7%9A%84LRU%E7%AE%97%E6%B3%95-%E4%B8%80.html</link><pubDate>Mon, 31 Jul 2017 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2017/07/31/redis%E7%9A%84LRU%E7%AE%97%E6%B3%95-%E4%B8%80.html</guid><description>&lt;p&gt;最近加班比较累，完全不想写作了。。&lt;/p&gt;&#10;&lt;p&gt;刚看到 &lt;a href="http://antirez.com/news/109"&gt; 一篇有趣的文章 &lt;/a&gt;，是 redis 的作者 antirez 对 redis 的 LRU 算法的回顾。LRU 算法是 Least Recently Used 的意思，将最近最少使用的资源丢掉。Redis 经常被用作 cache，如果能够将不常用的 key 移除，尽量保留常用的，那内存的利用率就相当高了。当然，LRU 也有弱点，考虑下面一种情况：&lt;/p&gt;</description></item><item><title>skynet 的网络收发</title><link>https://spin6lock.github.io/2017/07/02/skynet%E7%9A%84%E7%BD%91%E7%BB%9C%E6%94%B6%E5%8F%91.html</link><pubDate>Sun, 02 Jul 2017 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2017/07/02/skynet%E7%9A%84%E7%BD%91%E7%BB%9C%E6%94%B6%E5%8F%91.html</guid><description>&lt;p&gt;最近，有位前同事在 skynet 仓库里提了个 &lt;a href="https://github.com/cloudwu/skynet/issues/646"&gt; 有关网络性能的 issue&lt;/a&gt;，正好理一下 skynet 的流程。&lt;/p&gt;</description></item><item><title>skynet 的火焰图</title><link>https://spin6lock.github.io/2017/04/30/skynet%E7%9A%84%E7%81%AB%E7%84%B0%E5%9B%BE.html</link><pubDate>Sun, 30 Apr 2017 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2017/04/30/skynet%E7%9A%84%E7%81%AB%E7%84%B0%E5%9B%BE.html</guid><description>&lt;p&gt;之前搞过一下 systemtap（&lt;a href="http://www.cnblogs.com/Lifehacker/p/how_to_install_systemtap_on_centos.html"&gt;systemtap 折腾笔记 &lt;/a&gt;），可惜很快琐事缠身，没有继续搞下去。最近偷空搞了一下，有点意思。&lt;/p&gt;&#10;&lt;p&gt;章大大的思路，是用 perl 生成 systemtap 脚本，从 /proc/$pid/maps 里面扫出 liblua.so 的地址。然后 hook 这个地址里，以 luaL_* 和 lua_* 开头的 lua 虚拟机 C 函数。hook 住的函数里，都会有个参数 L，这个 L 表示 lua 的虚拟机。接下来就是按 lua 的 C 代码撸一遍，看看怎么从 L 的内存结构里，dump 出整个 lua 的运行栈。相当于在 systemtap 里，重新实现一遍官方的 debug.traceback。&lt;/p&gt;</description></item><item><title>伤感三月</title><link>https://spin6lock.github.io/2017/03/31/%E4%BC%A4%E6%84%9F%E4%B8%89%E6%9C%88.html</link><pubDate>Fri, 31 Mar 2017 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2017/03/31/%E4%BC%A4%E6%84%9F%E4%B8%89%E6%9C%88.html</guid><description>&lt;p&gt;带着我经历过两个项目的 boss 离职了，好遗憾。老同事过来我们组帮忙了，算是一个小小的惊喜。&lt;/p&gt;&#10;&lt;p&gt;最近看了《垃圾回收的算法与实现》，说实话，译者的水平比较有限，有几处明显的理解错误。不过，书里的插图还是很易懂的，看着伪代码和插图，勉强读了下来。读完会比较清醒的意识到，即使有 gc 帮助，还是有可能会有内存泄漏的。月中抽空压测了一下，的确发现了有泄漏。。&lt;/p&gt;</description></item><item><title>加班月</title><link>https://spin6lock.github.io/2017/02/28/%E5%8A%A0%E7%8F%AD%E6%9C%88.html</link><pubDate>Tue, 28 Feb 2017 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2017/02/28/%E5%8A%A0%E7%8F%AD%E6%9C%88.html</guid><description>&lt;p&gt;本月都在埋头加班，没搞什么有趣的东西，就分享一篇 Cloudflare 捅的篓子吧 XD&lt;/p&gt;&#10;&lt;p&gt;Google 有个叫 Project Zero 的安全团队，成员 Tavis Ormandy 某天做一个语料库项目，突然发现 Google 缓存数据里出现了完整的 https 请求。排查发现这些请求都来自于 Cloudflare。Cloudflare 是业界闻名的 CDN，通过 DNS 解释的原理工作，不需要修改页面的资源地址，而是将代理资源的域名，解释到靠近访客的 Cloudflare 服务器上，以此达到加速效果。Tavis 怀疑这次事故跟 Cloudflare 的 ScrapeShield 产品有关。ScrapeShield 是一个页面改写的产品，用来在网页里混入不可见的随机字符串，以跟踪爬虫的来源；对爬虫改写正文里的 email，以防被批量爬 Email 地址发垃圾邮件。（参见 Tavis Ormandy 的 &lt;a href="https://bugs.chromium.org/p/project-zero/issues/detail?id=1139"&gt; 报告 &lt;/a&gt;）&lt;/p&gt;</description></item><item><title>theevolutionofLua 全文翻译</title><link>https://spin6lock.github.io/2017/01/25/theevolutionofLua%E5%85%A8%E6%96%87%E7%BF%BB%E8%AF%91.html</link><pubDate>Wed, 25 Jan 2017 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2017/01/25/theevolutionofLua%E5%85%A8%E6%96%87%E7%BF%BB%E8%AF%91.html</guid><description>&lt;p&gt;终于赶在春节前将论文全文翻译完，以后有时间将前面三章重新翻译一次，因为刚开始的时候没打算全文翻译的。。第一次每天花 25 分钟完成这么长的一篇翻译，证明滴水可以穿石，哈哈哈&lt;/p&gt;</description></item><item><title>2016 年终总结</title><link>https://spin6lock.github.io/2016/12/31/2016%E5%B9%B4%E7%BB%88%E6%80%BB%E7%BB%93.html</link><pubDate>Sat, 31 Dec 2016 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2016/12/31/2016%E5%B9%B4%E7%BB%88%E6%80%BB%E7%BB%93.html</guid><description>&lt;p&gt;今年写了 14 篇博客，比去年的 18 篇要少，没有什么新技术，有点遗憾。倒是读了几篇好文章，比如 Linkedin 团队分享的 The Log，还有 The evolution of Lua。看了一下去年的 &lt;a href="http://www.cnblogs.com/Lifehacker/p/2015_summary.html"&gt; 年终总结 &lt;/a&gt;，发现目标基本都没完成｡ﾟヽ (ﾟД`)ﾉﾟ｡ 只有坚持博客这点算是完成了。关于 TCP/IP 协议，其实很想就 Google 家的 BBR 写一篇短文，等下试试。建站这点完全提不起动力，买了域名和 VPS 之后，就搭了个 Google 网页代理就算了。。&lt;/p&gt;</description></item><item><title>《一个 Go 程序系统线程暴涨的问题》结论</title><link>https://spin6lock.github.io/2016/09/18/%E4%B8%80%E4%B8%AAGo%E7%A8%8B%E5%BA%8F%E7%B3%BB%E7%BB%9F%E7%BA%BF%E7%A8%8B%E6%9A%B4%E6%B6%A8%E7%9A%84%E9%97%AE%E9%A2%98-%E7%BB%93%E8%AE%BA.html</link><pubDate>Sun, 18 Sep 2016 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2016/09/18/%E4%B8%80%E4%B8%AAGo%E7%A8%8B%E5%BA%8F%E7%B3%BB%E7%BB%9F%E7%BA%BF%E7%A8%8B%E6%9A%B4%E6%B6%A8%E7%9A%84%E9%97%AE%E9%A2%98-%E7%BB%93%E8%AE%BA.html</guid><description>&lt;p&gt;原文地址：https://zhuanlan.zhihu.com/p/22474724&lt;/p&gt;&#10;&lt;p&gt;作者的结论没写好，我来说两句。。&lt;/p&gt;</description></item><item><title>空中换心</title><link>https://spin6lock.github.io/2016/09/03/%E7%A9%BA%E4%B8%AD%E6%8D%A2%E5%BF%83.html</link><pubDate>Sat, 03 Sep 2016 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2016/09/03/%E7%A9%BA%E4%B8%AD%E6%8D%A2%E5%BF%83.html</guid><description>&lt;p&gt;最近一周在做一件非常刺激的事情，刺激到不想再干第二遍了 T_T。。。还有一个月就要内测的时候，换掉服务器架构，而且还要同时做需求，无异于对空中的飞机换引擎啊&lt;/p&gt;</description></item><item><title>阅读分享：游戏服务器的设计与面向日志的工作流</title><link>https://spin6lock.github.io/2016/07/31/%E9%98%85%E8%AF%BB%E5%88%86%E4%BA%AB-%E6%B8%B8%E6%88%8F%E6%9C%8D%E5%8A%A1%E5%99%A8%E7%9A%84%E8%AE%BE%E8%AE%A1%E4%B8%8E%E9%9D%A2%E5%90%91%E6%97%A5%E5%BF%97%E7%9A%84%E5%B7%A5%E4%BD%9C%E6%B5%81.html</link><pubDate>Sun, 31 Jul 2016 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2016/07/31/%E9%98%85%E8%AF%BB%E5%88%86%E4%BA%AB-%E6%B8%B8%E6%88%8F%E6%9C%8D%E5%8A%A1%E5%99%A8%E7%9A%84%E8%AE%BE%E8%AE%A1%E4%B8%8E%E9%9D%A2%E5%90%91%E6%97%A5%E5%BF%97%E7%9A%84%E5%B7%A5%E4%BD%9C%E6%B5%81.html</guid><description>&lt;p&gt;7 月的工作平淡无奇，除了 X 系统由借鉴 A 游戏改成借鉴 B 游戏，就没什么了，还是谈点别的吧。&lt;/p&gt;&#10;&lt;p&gt;最近看了 &lt;a href="http://www.cnblogs.com/fingerpass/p/game-server-programming-paradigm.html"&gt;《游戏服务器端究竟解决了什么问题》&lt;/a&gt;，推荐给大家。作者关于烂框架的分析很有趣，框架定义角色时，不恰当的角色划分，会引起额外的复杂度，作者文章中后部分有分析。&lt;/p&gt;&#10;&lt;p&gt;作者对服务器消息流通的分析，相当见功力。游戏的服务器端，可以抽象的看成消息的生产者和消费者的集合。每一个生产者 / 消费者，就是一个服务。skynet 的优势，在于提供了服务这个封装，一组功能相对独立的逻辑，可以组合在一个服务内，通过 skynet 转发通信，为其他服务提供相应功能。常见的消息生产者，包括和客户端通信、解包的 gate 模块，skynet 提供的 timer 定时驱动。服务就是对这些消息进行响应，并通过和其他服务的互动，完成自己的功能。&lt;/p&gt;</description></item><item><title>六月小结</title><link>https://spin6lock.github.io/2016/06/30/%E5%85%AD%E6%9C%88%E5%B0%8F%E7%BB%93.html</link><pubDate>Thu, 30 Jun 2016 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2016/06/30/%E5%85%AD%E6%9C%88%E5%B0%8F%E7%BB%93.html</guid><description>&lt;p&gt;六月的最后一天，解决了一个服务死循环的问题。吐槽下 skynet，既然已经可以检测到 endless loop，为什么不直接做个调试器去打出死循环在哪里？而且默认不自带超时功能，死了以后基本上服务统计的 gm 指令都挂了。要做超时的 call，还需要自己套个代理服务上去。&lt;/p&gt;</description></item><item><title>忙忙忙</title><link>https://spin6lock.github.io/2016/05/29/%E5%BF%99%E5%BF%99%E5%BF%99.html</link><pubDate>Sun, 29 May 2016 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2016/05/29/%E5%BF%99%E5%BF%99%E5%BF%99.html</guid><description>&lt;p&gt;最近都在加班，没什么好写的。每周六天，没事也要过来，有点崩溃。&lt;/p&gt;&#10;&lt;p&gt;邮箱、聊天之类的都做成信道，尽量和数据抽离开，由具体系统处理对客户端的数据转换，但是 orm 那块不够灵活。如果不走 orm，担心数据格式不对，直接用字符串保存的话，又丢了格式，以后运营的时候不好查找数据。&lt;/p&gt;</description></item><item><title>回炉重铸 - 设计模式的领悟</title><link>https://spin6lock.github.io/2016/04/30/%E5%9B%9E%E7%82%89%E9%87%8D%E9%93%B8-%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E7%9A%84%E9%A2%86%E6%82%9F.html</link><pubDate>Sat, 30 Apr 2016 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2016/04/30/%E5%9B%9E%E7%82%89%E9%87%8D%E9%93%B8-%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E7%9A%84%E9%A2%86%E6%82%9F.html</guid><description>&lt;p&gt;整个四月都在回炉重造之前的英雄成长系统，就因为决定换一个方向，累死。回头看看去年，没想到也是 4 月 30 号写的博客。。。&lt;/p&gt;&#10;&lt;p&gt;重造的过程里，同时在看《head first 设计模式》这本书。作者加了很多有趣的插图进去，以前是很讨厌这么做作的书，但是现在读来觉得没那么累，挺好的，可能是老了吧。。。里面提到的开放 - 封闭原则很有启发意义。以前写代码，写的很老实，不够偷懒，总是一字一句把策划的文案搬进去，抽象层次不够，搞的人很累。开放 - 封闭原则就教导，写代码应该对扩展开放，以后策划有新需求，只要在少数几处地方加个入口就行。对修改封闭这个倒是没有想好，策划总是在改案子，而且很多时候改动的幅度很大，怎么实现不修改没想好。目前是抽取了一堆工具函数出来，将策划的需求拼凑成一张表格，然后逐项检查，有新需求加新工具函数。&lt;/p&gt;</description></item><item><title>pythonsproto 支持 64 位有符号整数</title><link>https://spin6lock.github.io/2016/03/29/pythonsproto%E6%94%AF%E6%8C%8164%E4%BD%8D%E6%9C%89%E7%AC%A6%E5%8F%B7%E6%95%B4%E6%95%B0.html</link><pubDate>Tue, 29 Mar 2016 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2016/03/29/pythonsproto%E6%94%AF%E6%8C%8164%E4%BD%8D%E6%9C%89%E7%AC%A6%E5%8F%B7%E6%95%B4%E6%95%B0.html</guid><description>&lt;p&gt;小伙伴需要 64 位整数做物品的 id，之前 python sproto 的判断有问题，写篇日志记录一下。&lt;/p&gt;&#10;&lt;p&gt;之前有问题的代码是这样的：&lt;/p&gt;&#10;&lt;div class="td-code td-code--untitled" id="td-code-dd639446-fence-0" data-td-code data-td-code-auto-id&#10; data-td-language="" data-td-line-count="10"&gt;&#10; &lt;div class="td-code__viewport" id="td-code-dd639446-fence-0-viewport" data-td-code-viewport&gt;&lt;pre tabindex="0"&gt;&lt;code&gt; if (!PyInt_Check(data)) {&#10; PyErr_SetObject(SprotoError, PyString_FromFormat(&amp;#34;type mismatch, tag:%s, expected int&amp;#34;, tagname));&#10; return -1;&#10; }&#10; long i = PyInt_AsLong(data);&#10; int vh = i &amp;gt;&amp;gt; 31;&#10; if (vh == 0 || vh == -1) {&#10; *(uint32_t *)args-&amp;gt;value = (uint32_t)i;&#10; return 4;&#10; } else {&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&#10;&lt;/div&gt;&#10;&lt;p&gt;这里有两个问题。一，long 只保证有 32bit（via &lt;a href="https://en.wikipedia.org/wiki/C_data_types"&gt;wiki&lt;/a&gt;），有可能 data 是 64bit 的，这个时候就会丢数据。二，vh 的定义是 int，这里会丢数据。vh 是 i 通过位移得到的，目的是判断高位有没有数据，如果只有符号位有意义，就不用 64bit 存了，可以转到 32bit 里放数据。但是，我把 vh 强转成 int，这样刚好就丢掉了符号位，然后让次高位充当了符号位，这时候得到的数据是错误的。&lt;/p&gt;</description></item><item><title>pysprotobug 修复</title><link>https://spin6lock.github.io/2016/03/25/pysprotobug%E4%BF%AE%E5%A4%8D.html</link><pubDate>Fri, 25 Mar 2016 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2016/03/25/pysprotobug%E4%BF%AE%E5%A4%8D.html</guid><description>&lt;p&gt;最近，找隔壁组的同学测试了一下我的 pysproto，他们提了很多有益的建议，非常感谢。&lt;/p&gt;&#10;&lt;p&gt;在测试中，出现了一次诡异的 coredump。当数据变大的时候，就有很大的机率遇上 double free。在 sproto 和 python sproto 插件里插了一堆打印点后，发现 sproto 在解包的时候报错了。但是 unpack 的代码相当简单，下意识忽略过去了。找云大侠看了一下数据，发现的确有个长度数据错了。至于是在哪一层出错了，还是要再找找。接着我们尝试了直接用 lua 版的 sproto 解包和打包，都没有问题。包的收发也是在单机进行的，不存在问题。于是又绕回到 unpack 上去了。仔细想想，数据越来越大的时候才会出问题。有可能跟默认缓冲区的大小有关，这个大小设置为 1024 了，难道 Realloc 的时候出错了？&lt;/p&gt;</description></item><item><title>最近设计的反思</title><link>https://spin6lock.github.io/2016/03/20/%E6%9C%80%E8%BF%91%E8%AE%BE%E8%AE%A1%E7%9A%84%E5%8F%8D%E6%80%9D.html</link><pubDate>Sun, 20 Mar 2016 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2016/03/20/%E6%9C%80%E8%BF%91%E8%AE%BE%E8%AE%A1%E7%9A%84%E5%8F%8D%E6%80%9D.html</guid><description>&lt;p&gt;最近完成了邮箱的功能。&lt;/p&gt;&#10;&lt;p&gt;邮箱的设计参考了 mmzb 的设计，基于一套 msgsrv 来实现。msgsrv 是一个消息中转的服务，这个服务是为了简化玩家之间消息传递的过程。比如邮箱要向一个离线玩家发信，为了避免对离线玩家的数据进行修改，会通过 msgsrv 发送到玩家对应的 msgbox 里。玩家上线后，会自动查询自己的 msgsrv，检索未读消息。当玩家上线时，会主动在 msgsrv 中发起订阅。每当有新的消息进入，msgsrv 会直接发送到玩家所在的 agent 上，实现实时通知。唯一例外的情况，是全局消息的发送。一条全局消息发送的时候，只是向一个全局的队列里插入一份数据。玩家只会在登录时检索一次这个全局队列，并记住自己的检索位置。缺点是全局消息的通知不及时，需要玩家离线再上线才能收到。需要实时的消息，可以通过聊天系统解决。&lt;/p&gt;</description></item><item><title>服务器被发现存在未授权访问</title><link>https://spin6lock.github.io/2016/02/19/%E6%9C%8D%E5%8A%A1%E5%99%A8%E8%A2%AB%E5%8F%91%E7%8E%B0%E5%AD%98%E5%9C%A8%E6%9C%AA%E6%8E%88%E6%9D%83%E8%AE%BF%E9%97%AE.html</link><pubDate>Fri, 19 Feb 2016 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2016/02/19/%E6%9C%8D%E5%8A%A1%E5%99%A8%E8%A2%AB%E5%8F%91%E7%8E%B0%E5%AD%98%E5%9C%A8%E6%9C%AA%E6%8E%88%E6%9D%83%E8%AE%BF%E9%97%AE.html</guid><description>&lt;p&gt;今天下午，友商的同学突然发了个确认信息过来，让我们确认一下服务器的归属。然后就抛出了个大新闻：我司服务器存在问题，所有文件都可以任意访问。根据对方反映的信息，确认是之前玩票性质的一个项目：avalon 出了问题。https://github.com/ejoy/avalon/blob/master/lualib/staticfile.lua#L12-L17 这里没有做输入检查，就直接使用 io.open 了。&lt;/p&gt;</description></item><item><title>RRDtool 简介</title><link>https://spin6lock.github.io/2016/02/06/RRDtool%E7%AE%80%E4%BB%8B.html</link><pubDate>Sat, 06 Feb 2016 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2016/02/06/RRDtool%E7%AE%80%E4%BB%8B.html</guid><description>&lt;p&gt;最近公司换了办公地址，新厂址的宽带质量不怎么样，于是用 RRDTool 布了一套网络质量监控的系统，来定位公司内部与机房的连接问题。RRDTool 是一套经典的工具，前身是 MRTG，因为其中的性能有所不足，绘图的灵活性不够，于是作者 Tobias Oetiker 又重新开发了一套 RRDTool。这套工具包含了日志记录和图表绘制两部分，可以满足各种指标监控的用途。&lt;/p&gt;</description></item><item><title>折腾域名的 dns</title><link>https://spin6lock.github.io/2016/01/10/%E6%8A%98%E8%85%BE%E5%9F%9F%E5%90%8D%E7%9A%84dns.html</link><pubDate>Sun, 10 Jan 2016 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2016/01/10/%E6%8A%98%E8%85%BE%E5%9F%9F%E5%90%8D%E7%9A%84dns.html</guid><description>&lt;p&gt;最近，购买域名的时候遇到了几个概念，刚开始不是很懂，最后都是直接找客服给我改好的，现在小结一下帮助理解。&lt;/p&gt;&#10;&lt;p&gt;DNS 域名管理是按后缀进行分组的，比如 .com 域名，作为最早的商用域名，有很高的推广价值。再比如各个国家的顶级域名，例如中国的 .cn，加拿大的 .ca，简单易记。我们购买的，是通常意义上，www 与顶级域名之间的部分，叫二级域名。&lt;/p&gt;</description></item><item><title>2015 年终总结</title><link>https://spin6lock.github.io/2016/01/03/2015%E5%B9%B4%E7%BB%88%E6%80%BB%E7%BB%93.html</link><pubDate>Sun, 03 Jan 2016 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2016/01/03/2015%E5%B9%B4%E7%BB%88%E6%80%BB%E7%BB%93.html</guid><description>&lt;p&gt;2015 年是我第一次感觉人生过得快的一年。这一年买房了，月供比较重，有种喘不过气的感觉。15 年的阅读量比 14 年少，主要是网络小说看的少了，人文类的阅读量上来了，比较耗费时间。另外，15 年计算机专业的书读的很少，那本《redis 设计与实现》还没看完，有点遗憾。15 年开始思考一些大问题，比如两性平等，科技进步带来的发展，比如文明发展为什么不均衡，主体与客体，人为什么会感觉愉快。&lt;/p&gt;</description></item><item><title>mmzb 游戏事故分析</title><link>https://spin6lock.github.io/2015/12/20/mmzb%E6%B8%B8%E6%88%8F%E4%BA%8B%E6%95%85%E5%88%86%E6%9E%90.html</link><pubDate>Sun, 20 Dec 2015 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2015/12/20/mmzb%E6%B8%B8%E6%88%8F%E4%BA%8B%E6%95%85%E5%88%86%E6%9E%90.html</guid><description>&lt;p&gt;最近一次线上更新，老项目挂了，遍地哀嚎，日活跃掉了好多，心痛。。。&lt;/p&gt;&#10;&lt;p&gt;这次维护时，SA 为了缩减硬件资源，做了一次数据库迁移。给到开发手上的 player db，只有一些索引数据，不带有任一玩家数据。玩家上线的时候，skynet 自动从 redis-persist 服务中拉取（redis-persist 是一个基于旁路监听的 redis 落地程序，相对独立，参见 &lt;a href="http://www.cnblogs.com/Lifehacker/p/redis_persist_publish.html"&gt; 之前的博文 &lt;/a&gt;）。这也是 RP 服务的第一次高强度使用。按之前的策略，每次玩家下线都会在 RP 服务中存档，三个月不上线的玩家，会自动从 redis 数据库中移除，以节约内存。当流失玩家再度上线时，skynet 先从 redis 中直接查询，无法加载到玩家的话，再度从 RP 服务中拉取，可以简单的将 RP 服务视作 redis 的一个二级缓存。玩家下线后，数据继续在 redis 中保留三个月。所以，设计之初，RP 服务就是作为一个低频服务存在的，没有考虑到大量加载玩家的情况。&lt;/p&gt;</description></item><item><title>为 sproto 手写了一个 pythonparser</title><link>https://spin6lock.github.io/2015/12/13/%E4%B8%BAsproto%E6%89%8B%E5%86%99%E4%BA%86%E4%B8%80%E4%B8%AApythonparser.html</link><pubDate>Sun, 13 Dec 2015 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2015/12/13/%E4%B8%BAsproto%E6%89%8B%E5%86%99%E4%BA%86%E4%B8%80%E4%B8%AApythonparser.html</guid><description>&lt;p&gt;这是 sproto 系列文章的第三篇，可以参考前面的《&lt;a href="http://www.cnblogs.com/Lifehacker/p/python_sproto_introduction.html"&gt; 为 sproto 添加 python 绑定 &lt;/a&gt;》、《&lt;a href="http://www.cnblogs.com/Lifehacker/p/add_unorder_map_support_to_sproto.html"&gt; 为 python-sproto 添加 map 支持 &lt;/a&gt;》。&lt;/p&gt;&#10;&lt;div class="td-code td-code--untitled" id="td-code-6bd99c2e-fence-0" data-td-code data-td-code-auto-id&#10; data-td-language="" data-td-line-count="22"&gt;&#10; &lt;div class="td-code__viewport" id="td-code-6bd99c2e-fence-0-viewport" data-td-code-viewport&gt;&lt;pre tabindex="0"&gt;&lt;code&gt;.type {&#10; .field {&#10; name 0 : string&#10; buildin 1 : integer&#10; type 2 : integer&#10; tag 3 : integer&#10; array 4 : boolean&#10; key 5 : integer # If key exists, array must be true, and it&amp;#39;s a map.&#10; }&#10; name 0 : string&#10; fields 1 : *field&#10;}&#10;.protocol {&#10; name 0 : string&#10; tag 1 : integer&#10; request 2 : integer # index&#10; response 3 : integer # index&#10;}&#10;.group {&#10; type 0 : *type&#10; protocol 1 : *protocol&#10;}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&#10;&lt;/div&gt;&#10;&lt;p&gt;这么简单的结构，正好拿来练手写 parser。Lua 的 LPEG 库实在太强大，于是先试了一下 pypeg2 去解决这个问题。尝试的过程参见：https://github.com/spin6lock/sproto_python_parser，最后失败了。回想了一下，PEG 文法其实跟上下文无关文法相当类似，只是不存在二义性，能够通过一个 token 来完全决定接下来的解析树。这个跟递归下降法有点类似了，便顺手撸了一发：&lt;a href="https://github.com/spin6lock/yapsp"&gt;https://github.com/spin6lock/yapsp&lt;/a&gt;&lt;/p&gt;</description></item><item><title>Lua 小技巧</title><link>https://spin6lock.github.io/2015/11/17/Lua%E5%B0%8F%E6%8A%80%E5%B7%A7.html</link><pubDate>Tue, 17 Nov 2015 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2015/11/17/Lua%E5%B0%8F%E6%8A%80%E5%B7%A7.html</guid><description>&lt;p&gt;来公司以后，业务逻辑都用 lua 写。写了好长时间了，到最近才觉得有点掌握了 Lua 的灵活。最近用 Lua 写了个类似集合一样的东西，如果两次向集合里放入同一个元素，就会报错，方便检查配置。代码如下：&lt;/p&gt;</description></item><item><title>Techparty- 广州 10 月 31 日 Docker 专场沙龙后记</title><link>https://spin6lock.github.io/2015/10/31/Techparty-%E5%B9%BF%E5%B7%9E10%E6%9C%8831%E6%97%A5Docker%E4%B8%93%E5%9C%BA%E6%B2%99%E9%BE%99%E5%90%8E%E8%AE%B0.html</link><pubDate>Sat, 31 Oct 2015 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2015/10/31/Techparty-%E5%B9%BF%E5%B7%9E10%E6%9C%8831%E6%97%A5Docker%E4%B8%93%E5%9C%BA%E6%B2%99%E9%BE%99%E5%90%8E%E8%AE%B0.html</guid><description>&lt;p&gt;华为的童鞋技术能力很强，但是两位讲师的都没听进去。重点听了两个，一个是芒果 TV 的 Docker 之路，另一个是 Coding 的实践和思考。&lt;/p&gt;&#10;&lt;p&gt;芒果 TV 的主讲人是一直仰慕的 CMGS，从豆瓣出来后去了国企芒果台。因为内部阻力问题，无法实现 PaaS。转而实现了细粒度的调度。物理机 +Docker 为芒果台省了不少机器，而且性能还比 AWS 的要强。实践上，主要用到了 MacVLan，在二层网络上做网络调度。还有 Devicemapper，但是 dm 受镜像大小的影响比较大，超过 2G 大小的镜像就会有明显的性能下降。Docker 里跑的，主要是 Redis cluster。80G 的 redis 实例，分成了 80 个 1G 的 instance 来跑，分别错开 AOF 时机，避免触发 OOM。网络设置用的是 Eru-agent，自己开发的私货，同时负责监控。Docker 自带的监控在早期版本里，一直是个脑残，每秒取一次 metric 数据，严重影响性能。&lt;/p&gt;</description></item><item><title>1password 密码库格式更新</title><link>https://spin6lock.github.io/2015/10/19/1password%E5%AF%86%E7%A0%81%E5%BA%93%E6%A0%BC%E5%BC%8F%E6%9B%B4%E6%96%B0.html</link><pubDate>Mon, 19 Oct 2015 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2015/10/19/1password%E5%AF%86%E7%A0%81%E5%BA%93%E6%A0%BC%E5%BC%8F%E6%9B%B4%E6%96%B0.html</guid><description>&lt;p&gt;由于国内网络安全做的太差，经常发生被脱裤的事件，比如最近的网易邮箱（via &lt;a href="http://www.wooyun.org/bugs/wooyun-2015-0147763"&gt; 乌云 &lt;/a&gt;），所以只好用 1password 这类密码管理软件，实现一站一密。昨晚半夜冻醒了，刷推刷到了这个：&lt;a href="http://myers.io/2015/10/22/1password-leaks-your-data/"&gt;1password-leaks-your-data&lt;/a&gt;，整个人吓醒了 =_=# 作者有点标题党，脱水版可以参见 reddit 的 &lt;a href="https://www.reddit.com/r/technology/comments/3p9ihw/1password_leaks_your_data/"&gt; 这篇文章 &lt;/a&gt;，大意是 1password 的旧密码库格式叫 agilechains，大体是 json 结构，里面只有密码是加密的，密码项的名字和 URL 并未加密。官方提到历史原因，早期计算能力弱，只好加密关键部位。官方推出的密码库更新指南在此：&lt;a href="https://discussions.agilebits.com/discussion/39875/getting-your-data-into-the-opvault-format"&gt;Switching to OPVault format&lt;/a&gt;&lt;/p&gt;</description></item><item><title>SSL 加密与系统时间</title><link>https://spin6lock.github.io/2015/10/17/SSL%E5%8A%A0%E5%AF%86%E4%B8%8E%E7%B3%BB%E7%BB%9F%E6%97%B6%E9%97%B4.html</link><pubDate>Sat, 17 Oct 2015 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2015/10/17/SSL%E5%8A%A0%E5%AF%86%E4%B8%8E%E7%B3%BB%E7%BB%9F%E6%97%B6%E9%97%B4.html</guid><description>&lt;p&gt;最近，家里的神州老笔记本没电池了，要拆 C 面才能换主板电池，懒得动手，于是搞了个 Network Time 来做对时。主要是未搞对时之前，所有 https 的站点都用不了，老人家也抱怨炒股不行，崩溃了。。。这时候才知道，原来证书也是要验证时间的。&lt;/p&gt;</description></item><item><title>python 和 nodejs 的 aes128 加密对比</title><link>https://spin6lock.github.io/2015/10/14/python%E5%92%8Cnodejs%E7%9A%84aes128%E5%8A%A0%E5%AF%86%E5%AF%B9%E6%AF%94.html</link><pubDate>Wed, 14 Oct 2015 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2015/10/14/python%E5%92%8Cnodejs%E7%9A%84aes128%E5%8A%A0%E5%AF%86%E5%AF%B9%E6%AF%94.html</guid><description>&lt;p&gt;之前的机器人是用 python 写的，有同事想改写成 nodejs 版，但是验证一直通不过，于是帮忙爬了一下文档。&lt;/p&gt;&#10;&lt;div class="td-code td-code--untitled" id="td-code-75231360-fence-0" data-td-code data-td-code-auto-id&#10; data-td-language="" data-td-line-count="13"&gt;&#10; &lt;div class="td-code__viewport" id="td-code-75231360-fence-0-viewport" data-td-code-viewport&gt;&lt;pre tabindex="0"&gt;&lt;code&gt;#encoding:utf8&#10;&#10;from Crypto.Cipher import AES&#10;import binascii&#10;&#10;key = &amp;#39;abcdabcdabcdabcd&amp;#39;&#10;plaintext = &amp;#39;Secret Message A&amp;#39;&#10;&#10;encobj = AES.new(key, AES.MODE_ECB)&#10;ciphertext = encobj.encrypt(plaintext)&#10;&#10;# Resulting ciphertext in hex&#10;print ciphertext.encode(&amp;#39;hex&amp;#39;)&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&#10;&lt;/div&gt;&#10;&lt;div class="td-code td-code--untitled" id="td-code-75231360-fence-1" data-td-code data-td-code-auto-id&#10; data-td-language="" data-td-line-count="15"&gt;&#10; &lt;div class="td-code__viewport" id="td-code-75231360-fence-1-viewport" data-td-code-viewport&gt;&lt;pre tabindex="0"&gt;&lt;code&gt;var crypto = require(&amp;#34;crypto&amp;#34;);&#10;var key = new Buffer(&amp;#39;abcdabcdabcdabcd&amp;#39;,&amp;#39;ascii&amp;#39;);&#10;var text = &amp;#39;Secret Message A&amp;#39;;&#10;&#10;var cipher = crypto.createCipheriv(&amp;#39;AES-128-ECB&amp;#39;,key,&amp;#39;&amp;#39;);&#10;var decipher = crypto.createDecipheriv(&amp;#39;AES-128-ECB&amp;#39;,key,&amp;#39;&amp;#39;);&#10;var c1 = []&#10;var c2 = []&#10;c1.push(cipher.update(text, &amp;#34;ascii&amp;#34;, &amp;#34;hex&amp;#34;))&#10;c1.push(cipher.final(&amp;#34;hex&amp;#34;))&#10;var encrypted_text = c1.join(&amp;#39;&amp;#39;)&#10;console.log(encrypted_text)&#10;c2.push(decipher.update(encrypted_text, &amp;#34;hex&amp;#34;, &amp;#34;ascii&amp;#34;))&#10;c2.push(decipher.final(&amp;#34;ascii&amp;#34;))&#10;console.log(c2.join(&amp;#39;&amp;#39;))&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&#10;&lt;/div&gt;&#10;&lt;p&gt;但是有个问题，nodejs 版加密出来的密文，总是比 python 版要长。感觉 nodejs 最后的 final 方法，输出了多余的东西。参考了一些网文，如果密文不够一个 block，update 是没有输出的，如果超过一个 block，update 只会输出一个 block，剩余的放在 final 里返回。用 python 版解密看了一下，原来 final 在密文刚好一个 block 的情况下，会返回 padding 字符串。。。。&lt;/p&gt;</description></item><item><title>9 月补记</title><link>https://spin6lock.github.io/2015/10/02/9%E6%9C%88%E8%A1%A5%E8%AE%B0.html</link><pubDate>Fri, 02 Oct 2015 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2015/10/02/9%E6%9C%88%E8%A1%A5%E8%AE%B0.html</guid><description>&lt;p&gt;9 月份本来打算搞一下 bt，可惜一直没时间完成种子下载的部分，暂此搁笔。&lt;/p&gt;&#10;&lt;p&gt;由于 XcodeGhost 肆虐，于是顺手搞了个 XcodeGhost 的服务器版：https://github.com/spin6lock/XcodeGhostServer，联系 SA 帮忙指向本机，结果公司里大家都更新的好快，只发现一位同学中招 :) 只是弹窗还有点问题，JSON 里面的字段都有了，不知道是不是 scheme 不对，所以 openUrl 的时候有问题，稍后再看看。&lt;/p&gt;</description></item><item><title>对 bt 的一些想法</title><link>https://spin6lock.github.io/2015/09/09/%E5%AF%B9bt%E7%9A%84%E4%B8%80%E4%BA%9B%E6%83%B3%E6%B3%95.html</link><pubDate>Wed, 09 Sep 2015 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2015/09/09/%E5%AF%B9bt%E7%9A%84%E4%B8%80%E4%BA%9B%E6%83%B3%E6%B3%95.html</guid><description>&lt;p&gt;一直想做一个像 &lt;a href="http://www.cnblogs.com/cilizhushou.com"&gt; 磁力助手 &lt;/a&gt; 这样的网站，参考了 &lt;a href="http://xiaoxia.org/2013/05/11/magnet-search-engine/"&gt; 小虾的文章 &lt;/a&gt;。最近花了比较多的时间，自己实现了一遍，写写实验过程的体验。&lt;/p&gt;&#10;&lt;p&gt;术语：&lt;/p&gt;&#10;&lt;p&gt;DHT 网络是为了&lt;/p&gt;&#10;&lt;p&gt;参考文章：&lt;/p&gt;</description></item><item><title>旧梦重温</title><link>https://spin6lock.github.io/2015/08/31/%E6%97%A7%E6%A2%A6%E9%87%8D%E6%B8%A9.html</link><pubDate>Mon, 31 Aug 2015 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2015/08/31/%E6%97%A7%E6%A2%A6%E9%87%8D%E6%B8%A9.html</guid><description>&lt;p&gt;这个月主要在搞两件事，其一是：https://github.com/spin6lock/pydnsproxy，其二是一个 bt 客户端，用来搜索磁力链接，下载种子的，还没搞好。&lt;/p&gt;</description></item><item><title>树莓派改用中山大学软件源</title><link>https://spin6lock.github.io/2015/07/26/%E6%A0%91%E8%8E%93%E6%B4%BE%E6%94%B9%E7%94%A8%E4%B8%AD%E5%B1%B1%E5%A4%A7%E5%AD%A6%E8%BD%AF%E4%BB%B6%E6%BA%90.html</link><pubDate>Sun, 26 Jul 2015 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2015/07/26/%E6%A0%91%E8%8E%93%E6%B4%BE%E6%94%B9%E7%94%A8%E4%B8%AD%E5%B1%B1%E5%A4%A7%E5%AD%A6%E8%BD%AF%E4%BB%B6%E6%BA%90.html</guid><description>&lt;p&gt;**** 最近借了同事的第一代树莓派来玩，主要是想试试玩 SDR，之前听说可以上传一个月的航班广播（ADS-B 广播信息）就可以获得永久资格，随时查阅附近有什么航班飞行。后来发现 flightradar24.com 已经升级规则了，要持续上传数据。。。于是打算听听收音机算了，上手装了 raspbian，毕竟 debian 系统比较熟悉。国内网速着急，先换个源&lt;/p&gt;</description></item><item><title>翻译 lpeg 入门教程</title><link>https://spin6lock.github.io/2015/06/25/%E7%BF%BB%E8%AF%91lpeg%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B.html</link><pubDate>Thu, 25 Jun 2015 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2015/06/25/%E7%BF%BB%E8%AF%91lpeg%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B.html</guid><description>&lt;h2 id="原文地址httplua-usersorgwikilpegtutorial"&gt;原文地址：&lt;a href="http://lua-users.org/wiki/LpegTutorial%20"&gt;http://lua-users.org/wiki/LpegTutorial &lt;/a&gt;&#10;&lt;/h2&gt;&#10;&lt;h2 id="简单匹配"&gt;简单匹配&#10;&lt;/h2&gt;&#10;&lt;p&gt;LPeg 是一个用于文本匹配的有力表达方式，比 Lua 原生的字符串匹配和标准正则表达式更优异。但是，就像其他任何语言一样，你需要知道简单的词汇和如何组合他们。&lt;/p&gt;</description></item><item><title>为 python-sproto 添加 map 支持</title><link>https://spin6lock.github.io/2015/06/04/%E4%B8%BApython-sproto%E6%B7%BB%E5%8A%A0map%E6%94%AF%E6%8C%81.html</link><pubDate>Thu, 04 Jun 2015 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2015/06/04/%E4%B8%BApython-sproto%E6%B7%BB%E5%8A%A0map%E6%94%AF%E6%8C%81.html</guid><description>&lt;p&gt;上个月太忙了，做完这个修改还没写博客，现在补一下。。&lt;/p&gt;&#10;&lt;p&gt;之前使用 protobuf 做协议打包的时候，经常会有个痛点，没法用具体数据的值作为 key 来索引数据。比如现在客户端上传了造兵协议，协议大概长这样：&lt;/p&gt;</description></item><item><title>玩家回档原因分析</title><link>https://spin6lock.github.io/2015/04/30/%E7%8E%A9%E5%AE%B6%E5%9B%9E%E6%A1%A3%E5%8E%9F%E5%9B%A0%E5%88%86%E6%9E%90.html</link><pubDate>Thu, 30 Apr 2015 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2015/04/30/%E7%8E%A9%E5%AE%B6%E5%9B%9E%E6%A1%A3%E5%8E%9F%E5%9B%A0%E5%88%86%E6%9E%90.html</guid><description>&lt;p&gt;在最近一次维护后，玩家发现有较大规模的数据回档，还有一小部分玩家无法登录。现在尝试还原一下现场。&lt;/p&gt;&#10;&lt;p&gt;当天维护的时候，SA 执行了一次数据库维护。维护是通过一个脚本完成的，而且执行过多次，理论上没有问题。而维护的过程中，开发组这边需要执行一个脚本，给一批玩家增加经验。这一切完成后，QC 简单复测了一下，就开服了。开服后发现，服务器出现大量报错，而且都是玩家数据出现问题。定位这个问题的时候，发现玩家的数据丢掉了导致无法登录，顿时吓尿了 =_=||| 论坛里也有玩家开始叫骂，定位了一下貌似是那批增加经验的玩家，于是马上复查增加经验的脚本。玩家数据存储是使用 redis 数据库的，脚本里就使用了一条 hincrby 指令，不应该会清掉数据啊&lt;/p&gt;</description></item><item><title>为 sproto 添加 python 绑定</title><link>https://spin6lock.github.io/2015/03/19/%E4%B8%BAsproto%E6%B7%BB%E5%8A%A0python%E7%BB%91%E5%AE%9A.html</link><pubDate>Thu, 19 Mar 2015 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2015/03/19/%E4%B8%BAsproto%E6%B7%BB%E5%8A%A0python%E7%BB%91%E5%AE%9A.html</guid><description>&lt;p&gt;项目地址：&lt;a href="https://github.com/spin6lock/python-sproto"&gt;https://github.com/spin6lock/python-sproto&lt;/a&gt;&lt;/p&gt;&#10;&lt;p&gt;第一次写 Python 的 C 扩展，留点笔记记录一下。主要的参考文档是：&lt;a href="https://docs.python.org/2/extending/extending.html"&gt;Extending Python with C/C++&lt;/a&gt;, 之前也看过 cython，但是用 Python 语法写 C 还是没学会，稍后再尝试用 cython 写一遍看看。&lt;/p&gt;</description></item><item><title>如何快速编写 Vim 语法高亮文件</title><link>https://spin6lock.github.io/2015/03/11/%E5%A6%82%E4%BD%95%E5%BF%AB%E9%80%9F%E7%BC%96%E5%86%99Vim%E8%AF%AD%E6%B3%95%E9%AB%98%E4%BA%AE%E6%96%87%E4%BB%B6.html</link><pubDate>Wed, 11 Mar 2015 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2015/03/11/%E5%A6%82%E4%BD%95%E5%BF%AB%E9%80%9F%E7%BC%96%E5%86%99Vim%E8%AF%AD%E6%B3%95%E9%AB%98%E4%BA%AE%E6%96%87%E4%BB%B6.html</guid><description>&lt;p&gt;这里有一份 &lt;a href="http://vimcdoc.sourceforge.net/doc/syntax.html"&gt; 中文的入门文档 &lt;/a&gt;，但是太长了，不想读，所以有本文&lt;/p&gt;&#10;&lt;ol&gt;&#10;&lt;li&gt;最快的办法，就是找一个语法相近的语法高亮文件，稍微改一下&lt;/li&gt;&#10;&lt;li&gt;自己从头写的话，首先搞定关键字：&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;div class="td-code td-code--untitled" id="td-code-6708b91c-fence-0" data-td-code data-td-code-auto-id&#10; data-td-language="" data-td-line-count="3"&gt;&#10; &lt;div class="td-code__viewport" id="td-code-6708b91c-fence-0-viewport" data-td-code-viewport&gt;&lt;pre tabindex="0"&gt;&lt;code&gt;syntax case match &amp;#34; 是否区分大小写&#10;syntax keyword 你的关键字类别名字 x 关键字 1 关键字 2&#10;syntax keyword 同样填 x 的话，不会覆盖，只追加 关键字 3 关键字 4&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&#10;&lt;/div&gt;&#10;&lt;p&gt;关键字搞不定的，一般用正则匹配：&lt;/p&gt;</description></item><item><title>windows 调试器尝鲜</title><link>https://spin6lock.github.io/2015/02/23/windows%E8%B0%83%E8%AF%95%E5%99%A8%E5%B0%9D%E9%B2%9C.html</link><pubDate>Mon, 23 Feb 2015 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2015/02/23/windows%E8%B0%83%E8%AF%95%E5%99%A8%E5%B0%9D%E9%B2%9C.html</guid><description>&lt;p&gt;曾几何时，我也下载过看雪论坛精华看的津津有味。可惜一直没有动手去调试，学到的 x86 汇编指令也忘得差不多了。最近将老机器的 T4200 CPU 换成了更省电，温度更低的 P8800，为了支援新的 VT 虚拟化，特地将 Dell 1545 的 BIOS 从 A8 升级到 A14。顺带发现 SLIC 已经自动升级到 2.0 了。但是升级以后，win7 开始菜单的睡眠功能就无法使用了，于是萌生了降级刷 BIOS 的想法。&lt;/p&gt;</description></item><item><title>休斯顿，我们遇到了一个问题</title><link>https://spin6lock.github.io/2014/12/27/%E4%BC%91%E6%96%AF%E9%A1%BF-%E6%88%91%E4%BB%AC%E9%81%87%E5%88%B0%E4%BA%86%E4%B8%80%E4%B8%AA%E9%97%AE%E9%A2%98.html</link><pubDate>Sat, 27 Dec 2014 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2014/12/27/%E4%BC%91%E6%96%AF%E9%A1%BF-%E6%88%91%E4%BB%AC%E9%81%87%E5%88%B0%E4%BA%86%E4%B8%80%E4%B8%AA%E9%97%AE%E9%A2%98.html</guid><description>&lt;p&gt;最近和前端同学聊得比较多，聊着聊着发现前端回报了一个诡异的错误，服务器端发给客户端的 JSON 错了，解不开。前端同学 bs 了一下服务器用的 JSON 库，居然连编码都会出错。我检查了所用的库，前后端的确用的不是同一个 json.lua，于是跑了一次简单的压测。当然，没有发现问题。过了两天，又遇到同一个问题了，这次我留心了一下错误的详细内容：&lt;/p&gt;</description></item><item><title>糟糕的十一月</title><link>https://spin6lock.github.io/2014/11/30/%E7%B3%9F%E7%B3%95%E7%9A%84%E5%8D%81%E4%B8%80%E6%9C%88.html</link><pubDate>Sun, 30 Nov 2014 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2014/11/30/%E7%B3%9F%E7%B3%95%E7%9A%84%E5%8D%81%E4%B8%80%E6%9C%88.html</guid><description>&lt;p&gt;十一月感觉就是写邮件系统和两个策划要的活动而已。。。&lt;/p&gt;&#10;&lt;p&gt;一直觉得邮件系统十分简单，但是实现的时候却不是一回事。实现速度比预期的慢，一方面是边写边参考了礼包系统的结构，另一方面是抽象错误。就因为邮件放在礼包的位置，然后邮件看起来只是比礼包多一两个字段，所以就参考了礼包系统。这个错误实在太严重。表现层的相似性居然影响到后端的实现！！！&lt;/p&gt;</description></item><item><title>skynet 的协程</title><link>https://spin6lock.github.io/2014/10/26/skynet%E7%9A%84%E5%8D%8F%E7%A8%8B.html</link><pubDate>Sun, 26 Oct 2014 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2014/10/26/skynet%E7%9A%84%E5%8D%8F%E7%A8%8B.html</guid><description>&lt;p&gt;之前对 skynet 的印象，主要是来自于我对 golang 的理解，对 gevent 开发的经验，以及云风的 blog。对于底层的代码，并没有仔细去阅读过。最近在实现业务系统的时候，发现有同事在同一个函数里做了一个互斥的判断，才发现对 skynet 的理解有误。&lt;/p&gt;</description></item><item><title>redis-persist 上线</title><link>https://spin6lock.github.io/2014/10/16/redis-persist%E4%B8%8A%E7%BA%BF.html</link><pubDate>Thu, 16 Oct 2014 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2014/10/16/redis-persist%E4%B8%8A%E7%BA%BF.html</guid><description>&lt;p&gt;九月份惨不忍睹，因为代码质量不够高，直接被 Boss 喷成了筛子。被反复教育说要高质量的代码，要可维护、高性能&lt;/p&gt;&#10;&lt;p&gt;幸而，最后一周终于在紧张的加班中，灰度上线 redis-land-go 了，项目也改名为 redis-persist，&lt;a href="https://github.com/xjdrew/redis-persist"&gt;github 在此 &lt;/a&gt;。&lt;/p&gt;</description></item><item><title>忙里偷闲的八月</title><link>https://spin6lock.github.io/2014/08/30/%E5%BF%99%E9%87%8C%E5%81%B7%E9%97%B2%E7%9A%84%E5%85%AB%E6%9C%88.html</link><pubDate>Sat, 30 Aug 2014 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2014/08/30/%E5%BF%99%E9%87%8C%E5%81%B7%E9%97%B2%E7%9A%84%E5%85%AB%E6%9C%88.html</guid><description>&lt;p&gt;八月依然有些很狗血的策划案要做，以至于花了两周时间，周五做出来后，连策划自己都觉得配置超多超复杂。。。&lt;/p&gt;&#10;&lt;p&gt;这个月比较过瘾的，是下决心做了 dns 的实验。当时为了防止 DNS 污染，曾经用 Python 写过一个 DNS 代理，通过 TCP 管道传输解析包，避免墙的干扰，地址在 &lt;a href="https://code.google.com/p/pydnsproxy/"&gt;google code&lt;/a&gt;。项目原本是通过丢弃最先返回的 udp 包来实现的，后来改为了 TCP 查询。不过，当时硬着头皮读的 &lt;a href="https://www.ietf.org/rfc/rfc1035.txt"&gt;RFC1035&lt;/a&gt;，只读懂了 TCP 的部分，只要将接收到的包体加上长度作为包头，就可以直接丢到 TCP 管道的另一端，解包也是根据包头解出 DNS 返回包，送回到查询者即可。&lt;/p&gt;</description></item><item><title>并行的边界</title><link>https://spin6lock.github.io/2014/08/02/%E5%B9%B6%E8%A1%8C%E7%9A%84%E8%BE%B9%E7%95%8C.html</link><pubDate>Sat, 02 Aug 2014 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2014/08/02/%E5%B9%B6%E8%A1%8C%E7%9A%84%E8%BE%B9%E7%95%8C.html</guid><description>&lt;p&gt;七月份忙的狗一样，还一度要 12 点赶回公司修 bug，真累。。。&lt;/p&gt;&#10;&lt;p&gt;入职以来的这两个月，一直在业务层摸索，苦于没有文档，rpc 协议、单件服务的启动、为热更新去准备的环境变量等等，都要一一在摸索中问出来。幸而，终于走过了这一段。这也促使我开始思考，skynet、gevent、golang 之间，各自的优点和缺点是什么。&lt;/p&gt;</description></item><item><title>初来乍到</title><link>https://spin6lock.github.io/2014/06/15/%E5%88%9D%E6%9D%A5%E4%B9%8D%E5%88%B0.html</link><pubDate>Sun, 15 Jun 2014 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2014/06/15/%E5%88%9D%E6%9D%A5%E4%B9%8D%E5%88%B0.html</guid><description>&lt;p&gt;来到新公司后，终于有机会用 git 作为版本控制的工具。通过 github 私有仓库进行 Pull Request 和 code review，的确十分方便。使用的时候发现自己关于分支的知识不够用了，出现过一次提交 Pull Request 后被 merge，然后自己本地又 merge 了，导致 git pull 时版本冲突的问题。另外，客户端不希望出现 merge，所有对共享配置的修改，都需要用 rebase 方式合并，又犯了一次错误&lt;/p&gt;</description></item><item><title>进程 daemon 化</title><link>https://spin6lock.github.io/2014/05/26/%E8%BF%9B%E7%A8%8Bdaemon%E5%8C%96.html</link><pubDate>Mon, 26 May 2014 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2014/05/26/%E8%BF%9B%E7%A8%8Bdaemon%E5%8C%96.html</guid><description>&lt;p&gt;最近跳槽，转去简悦了，新公司的技术氛围很好，我要更加努力 ~&lt;/p&gt;&#10;&lt;p&gt;有些问题不写博客的时候，以为自己是懂的，但是实际讨论的时候，发现有一些细节还是没有搞清楚，这次试试讲进程怎样 daemon 化。&lt;/p&gt;</description></item><item><title>嵌入式课程设计 -- 第一天</title><link>https://spin6lock.github.io/2014/05/05/%E5%B5%8C%E5%85%A5%E5%BC%8F%E8%AF%BE%E7%A8%8B%E8%AE%BE%E8%AE%A1-%E7%AC%AC%E4%B8%80%E5%A4%A9.html</link><pubDate>Mon, 05 May 2014 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2014/05/05/%E5%B5%8C%E5%85%A5%E5%BC%8F%E8%AF%BE%E7%A8%8B%E8%AE%BE%E8%AE%A1-%E7%AC%AC%E4%B8%80%E5%A4%A9.html</guid><description>&lt;p&gt;今天花了一个早上去配置开发环境，晕死。。。&lt;/p&gt;&#10;&lt;p&gt;主要问题是找到一个合适的 2410 实验箱。电脑方面虽然普遍带毒，好歹还是能跑起来。但实验箱方面就比较麻烦。一个是线缆的配合，包括串行线，串行线方面有两种，一种是斜纹，一种是直纹的，它们分别是交叉线和非交叉线。另一个比较重要的线缆是 JTAG 线，我们见的 JTAG 线比较少，所以刚开始的时候拿了另一个实验箱的线。&lt;/p&gt;</description></item><item><title>引用计数 gc 机制使用不当导致内存泄漏</title><link>https://spin6lock.github.io/2014/05/05/%E5%BC%95%E7%94%A8%E8%AE%A1%E6%95%B0gc%E6%9C%BA%E5%88%B6%E4%BD%BF%E7%94%A8%E4%B8%8D%E5%BD%93%E5%AF%BC%E8%87%B4%E5%86%85%E5%AD%98%E6%B3%84%E6%BC%8F.html</link><pubDate>Mon, 05 May 2014 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2014/05/05/%E5%BC%95%E7%94%A8%E8%AE%A1%E6%95%B0gc%E6%9C%BA%E5%88%B6%E4%BD%BF%E7%94%A8%E4%B8%8D%E5%BD%93%E5%AF%BC%E8%87%B4%E5%86%85%E5%AD%98%E6%B3%84%E6%BC%8F.html</guid><description>&lt;p&gt;上一篇文章找同事 review 了一下，收到的反馈是铺垫太长了，我尽量直入正题，哈哈&lt;/p&gt;&#10;&lt;p&gt;最近 dbd 压测时发现内存泄漏，其实这个问题去年已经暴露了，参见这篇 &lt;a href="http://www.cnblogs.com/Lifehacker/p/stress_test_and_memory_leak_detect.html"&gt; 博客【压测周】&lt;/a&gt;。当时排查不够仔细，在此检讨下。关于 dbd 的内存问题，还有 &lt;a href="http://www.cnblogs.com/Lifehacker/p/thread_safe_problem_on_type_system.html"&gt; 这篇博客 &lt;/a&gt; 讨论线程安全，以及 &lt;a href="http://www.cnblogs.com/Lifehacker/p/dbd_structure_and_bson_format_process.html"&gt; 这篇博客 &lt;/a&gt; 讨论临时变量的处理。当时还存了一个尾巴，因为用到关联数组进行脏数据管理，这部分数据是怎么释放的一直没搞明白。今天算是搞明白了，这个内存泄漏的 bug 也源于此。&lt;/p&gt;</description></item><item><title>脚本引擎栈指针误操作引起内存泄露</title><link>https://spin6lock.github.io/2014/04/24/%E8%84%9A%E6%9C%AC%E5%BC%95%E6%93%8E%E6%A0%88%E6%8C%87%E9%92%88%E8%AF%AF%E6%93%8D%E4%BD%9C%E5%BC%95%E8%B5%B7%E5%86%85%E5%AD%98%E6%B3%84%E9%9C%B2.html</link><pubDate>Thu, 24 Apr 2014 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2014/04/24/%E8%84%9A%E6%9C%AC%E5%BC%95%E6%93%8E%E6%A0%88%E6%8C%87%E9%92%88%E8%AF%AF%E6%93%8D%E4%BD%9C%E5%BC%95%E8%B5%B7%E5%86%85%E5%AD%98%E6%B3%84%E9%9C%B2.html</guid><description>&lt;p&gt;最近，为了确定目标部署机器的配置，我们对服务器进行了玩家登录的压力测试。在 E7500 cpu，3G 内存的开发机上，同一时间登录人数不能超过 20 人。以 0.01 秒间隔登录，测试人数 5000 人，登录时一个核心在 30%-60% 之间波动，另一个核心比较空闲。稳定后，CPU 平均在 5% 一下（玩家只是登录后保持心跳），峰值内存在 2.3G 以内。但比较诡异的是，当玩家全部断开后，服务器的内存还是没有降下来。我觉得，可能是发生内存泄露了。&lt;/p&gt;</description></item><item><title>译 libev 和 libevent 的设计差异</title><link>https://spin6lock.github.io/2014/03/31/%E8%AF%91libev%E5%92%8Clibevent%E7%9A%84%E8%AE%BE%E8%AE%A1%E5%B7%AE%E5%BC%82.html</link><pubDate>Mon, 31 Mar 2014 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2014/03/31/%E8%AF%91libev%E5%92%8Clibevent%E7%9A%84%E8%AE%BE%E8%AE%A1%E5%B7%AE%E5%BC%82.html</guid><description>&lt;p&gt;本文译自 &lt;a href="http://stackoverflow.com/questions/9433864/whats-the-difference-between-libev-and-libevent"&gt;what&amp;rsquo;s the difference between libev and libevent?&lt;/a&gt; 作者是 libev 作者&lt;/p&gt;&#10;&lt;p&gt;[ 问 ] 两个库都是为异步 io 调度而设计，在 Linux 上都是使用 epoll 机制，在 FreeBSD 上则都是 kqueue，还有诸如此类的很多相通之处。&lt;/p&gt;</description></item><item><title>libevent 库 1.4 升级到 2.0 时无法 flush 的解决办法</title><link>https://spin6lock.github.io/2014/03/18/libevent%E5%BA%931.4%E5%8D%87%E7%BA%A7%E5%88%B02.0%E6%97%B6%E6%97%A0%E6%B3%95flush%E7%9A%84%E8%A7%A3%E5%86%B3%E5%8A%9E%E6%B3%95.html</link><pubDate>Tue, 18 Mar 2014 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2014/03/18/libevent%E5%BA%931.4%E5%8D%87%E7%BA%A7%E5%88%B02.0%E6%97%B6%E6%97%A0%E6%B3%95flush%E7%9A%84%E8%A7%A3%E5%86%B3%E5%8A%9E%E6%B3%95.html</guid><description>&lt;p&gt;libevent 的接口兼容性做的还算不错，基本上替换一下就转到新版本了。但是，强制 flush 数据的时候出了问题。目前的应用场景是，遇到顶号登录这种情形，先用 bufferevent_write 向客户端发送错误信息，然后再断开 socket。用的 flush 是这样的：&lt;/p&gt;</description></item><item><title>游戏协议加密及身份验证</title><link>https://spin6lock.github.io/2014/03/01/%E6%B8%B8%E6%88%8F%E5%8D%8F%E8%AE%AE%E5%8A%A0%E5%AF%86%E5%8F%8A%E8%BA%AB%E4%BB%BD%E9%AA%8C%E8%AF%81.html</link><pubDate>Sat, 01 Mar 2014 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2014/03/01/%E6%B8%B8%E6%88%8F%E5%8D%8F%E8%AE%AE%E5%8A%A0%E5%AF%86%E5%8F%8A%E8%BA%AB%E4%BB%BD%E9%AA%8C%E8%AF%81.html</guid><description>&lt;p&gt;时间如白驹过隙，一眨眼就过去了，本打算在 2 月份发这篇的，结果一直误以为 2 月有 31 日&lt;/p&gt;&#10;&lt;p&gt;这一块之前一直感兴趣，终于在 2 月份争取到机会去做这一块的工作。前辈给我留下了一个鉴权的框架：&lt;/p&gt;</description></item><item><title>初探 groupcache</title><link>https://spin6lock.github.io/2014/01/09/%E5%88%9D%E6%8E%A2groupcache.html</link><pubDate>Thu, 09 Jan 2014 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2014/01/09/%E5%88%9D%E6%8E%A2groupcache.html</guid><description>&lt;p&gt;groupcache 是用于 dl.google.com 的一个 memcached 的替代品，相对于 memcached，提供更小的功能集和更高的效率，以第三方库的形式提供服务。&lt;/p&gt;&#10;&lt;p&gt;groupcache 的常见部署可参考下图：&lt;/p&gt;&#10;&lt;img src="http://images.cnitblog.com/blog/90397/201401/091629188481.jpg" alt="" /&gt;&#10;&lt;p&gt;不同于 memcached，groupcache 面向的是静态的缓存系统，比如 google 家的下载站，用来缓存对应的文件区块。一经 set 操作，key 对应的 value 就不再变化。使用的时候，需要自定义缓存缺失时使用的 set 操作。当发生 miss 的时候，首先会从根据 key 的 consist hash 值找到对应的 peer，去 peer 里寻找对应的 value。如果找不到，则使用自定义的 get 函数从慢缓存（比如 db，文件读取）获取 alue，并填充对应 peer。下一次获取，就直接从 cache 里取出来，不再访问慢缓存。另外，为避免网络变成瓶颈，本地 peer 获取 cache 后，会存在本地的 localCache 里，通过 LRU 算法进行管理。&lt;/p&gt;</description></item><item><title>systemtap 折腾笔记</title><link>https://spin6lock.github.io/2013/11/22/systemtap%E6%8A%98%E8%85%BE%E7%AC%94%E8%AE%B0.html</link><pubDate>Fri, 22 Nov 2013 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2013/11/22/systemtap%E6%8A%98%E8%85%BE%E7%AC%94%E8%AE%B0.html</guid><description>&lt;p&gt;在这货上花费了不少时间，都是受了 @agentzh 大神的蛊惑 :) 他写的 nginx-systemtap-toolkit 监测的数据很有价值，对于系统优化实在是利器。&lt;/p&gt;&#10;&lt;p&gt;最早折腾 systemtap，是在 Ubuntu 12.04 上搞的，内核版本是 3.8.0-29-generic，流程参考 &lt;a href="https://sourceware.org/systemtap/wiki/SystemtapOnUbuntu"&gt; 官方教程 &lt;/a&gt;。因为 12.04 版本比较新，所以不需要重新编译内核了。然后添加带调试信息的内核，以及相关的 Linux 头文件。整个过程还算顺利，就是公司网速比较慢。下载完成后，用 ubuntu 官方仓库自带的 systemtap 1.6，却出现各种奇怪的 C 编译错误，于是换到了 git clone 下来的最新版本。这次错误信息友好了很多，但 tapset 的脚本跟内核的 dwarf 信息似乎对应不上，报 semantic error: not accessible at this address [man error::dwarf]。至此，ubuntu 上的 systemtap 只能打出 hello world，其他脚本都跑不了，遂放弃。教训是，systemtap 要新版，内核要老版，若用老 systemtap 和新内核，一般是会挂的。&lt;/p&gt;</description></item><item><title>Mongodb 在 NUMA 机器上的优化</title><link>https://spin6lock.github.io/2013/11/15/Mongodb%E5%9C%A8NUMA%E6%9C%BA%E5%99%A8%E4%B8%8A%E7%9A%84%E4%BC%98%E5%8C%96.html</link><pubDate>Fri, 15 Nov 2013 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2013/11/15/Mongodb%E5%9C%A8NUMA%E6%9C%BA%E5%99%A8%E4%B8%8A%E7%9A%84%E4%BC%98%E5%8C%96.html</guid><description>&lt;p&gt;10gen 在 mongodb 的部署指南上，提到了在 NUMA 机器上，mongodb 可能会出现问题，参见：http://docs.mongodb.org/manual/administration/production-notes/#production-numa&lt;/p&gt;</description></item><item><title>转设置 Android 手机以使用 ARMStreamline 进行性能分析（二）</title><link>https://spin6lock.github.io/2013/10/31/%E8%BD%AC%E8%AE%BE%E7%BD%AEAndroid%E6%89%8B%E6%9C%BA%E4%BB%A5%E4%BD%BF%E7%94%A8ARMStreamline%E8%BF%9B%E8%A1%8C%E6%80%A7%E8%83%BD%E5%88%86%E6%9E%90-%E4%BA%8C.html</link><pubDate>Thu, 31 Oct 2013 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2013/10/31/%E8%BD%AC%E8%AE%BE%E7%BD%AEAndroid%E6%89%8B%E6%9C%BA%E4%BB%A5%E4%BD%BF%E7%94%A8ARMStreamline%E8%BF%9B%E8%A1%8C%E6%80%A7%E8%83%BD%E5%88%86%E6%9E%90-%E4%BA%8C.html</guid><description>&lt;h2 id=""&gt;&#10;&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;General Setup( 常规设置 )，确保启用了 Profiling Support ( 分析支持 ) 选项。&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;Kernel Hacking( 内核开发 )，在子菜单中，导航至 Tracers 子菜单，然后按下 Enter。确保启用 Trace 进程上下文开关选项。&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;Kernel Features( 内核功能 )，确保启用 High Resolution Timer Support ( 高分辨率定时器支持 )。如果正在使用对称多处理器 (SMP) 设备，则启用 Use local timer interrupts （使用本地定时器中断）。&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;为加快工作速度，先下载一个内核更新包作为模板。对于 HTC Sensation 4G 手机，可通过 Google 来查找某些 &lt;a href="http://forum.xda-developers.com/showthread.php?t=1200403"&gt;kernel update packages&lt;/a&gt;（内核更新包）。&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;将其解压至工作文件夹&lt;workdir&gt;&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;用重新编译的内核文件 zImage 来替换&lt;workdir&gt;/kernel 文件夹中的 zImage 文件。&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;将 init.rc 复制到&lt;workdir&gt;/kernel 文件夹&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;在&lt;workdir&gt;/kernel 文件夹中编辑或创建 mkbooting.sh 脚本来更新启动镜像&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;将重新编译的内核模块（wifi 驱动程序）复制到&lt;workdir&gt;/system/lib/modules 文件夹&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;将 gator.ko 和 gatord 复制到&lt;workdir&gt;/system/xbin 文件夹&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;在&lt;workdir&gt;/META-INF/com/google/android/updater-script 文件夹中编辑 updater-script 文件。添加下列行来更新系统分区，并将 gatord 程序的权限设置成可执行。&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;在&lt;workdir&gt;/META-INF/com/google/android/updater-script 文件夹中编辑 updater-script 文件。添加下列行来更新启动分区（内核及 init.rc）。&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;将&lt;workdir&gt;文件夹压缩为 update.zip 文件。请注意！切勿将&lt;workdir&gt;文件夹本身包括在内。&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;将 update.zip 文件复制到目标手机的 SD 卡根文件夹下。&lt;/p&gt;&#10;&lt;/li&gt;&#10;&lt;/ul&gt;</description></item><item><title>转设置 Android 手机以使用 ARMStreamline 进行性能分析（一）</title><link>https://spin6lock.github.io/2013/10/31/%E8%BD%AC%E8%AE%BE%E7%BD%AEAndroid%E6%89%8B%E6%9C%BA%E4%BB%A5%E4%BD%BF%E7%94%A8ARMStreamline%E8%BF%9B%E8%A1%8C%E6%80%A7%E8%83%BD%E5%88%86%E6%9E%90-%E4%B8%80.html</link><pubDate>Thu, 31 Oct 2013 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2013/10/31/%E8%BD%AC%E8%AE%BE%E7%BD%AEAndroid%E6%89%8B%E6%9C%BA%E4%BB%A5%E4%BD%BF%E7%94%A8ARMStreamline%E8%BF%9B%E8%A1%8C%E6%80%A7%E8%83%BD%E5%88%86%E6%9E%90-%E4%B8%80.html</guid><description>&lt;h2 id=""&gt;&#10;&lt;/h2&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;Streamline 5.7 版。Streamline 是 &lt;a href="http://www.arm.com/zh/products/tools/software-tools/ds-5/index.php"&gt;ARM Development Studio 5&lt;/a&gt; 的一个组成模块。因此，可通过下载 &lt;a href="http://www.arm.com/zh/products/tools/software-tools/ds-5/ds-5-downloads.php"&gt;ARM DS-5&lt;/a&gt; 专业版、基础版或免费的 DS-5 公众版（针对 Android 系统）来获得它。&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;li&gt;目标 ARM 设备，HTC Sensation 4G&#10;&lt;ul class="bbc"&gt;&#10;- [Qualcomm Snapdragon ](http://www.arm.com/zh/markets/mobile/qualcomm-snapdragon-chipset.php)1.2-GHz 双核处理器，ARMv7 架构&#10;- Android 2.3.4 版&#10;- Linux 内核 2.6.35.13 版&#10;&lt;ul&gt;&#10;&lt;li&gt;&#10;&lt;p&gt;HTC 手机的内部代码。如果是 HTC sensation 4G 手机，那么内部代码是图中红框标示的 PYRAMID。内部代码是 HTC Android 手机的标识，通过它可搜索到 HTC 发布的正确 Linux 内核源代码包。&lt;/p&gt;</description></item><item><title>FreeBSD 打开 DTrace 支持</title><link>https://spin6lock.github.io/2013/10/29/FreeBSD%E6%89%93%E5%BC%80DTrace%E6%94%AF%E6%8C%81.html</link><pubDate>Tue, 29 Oct 2013 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2013/10/29/FreeBSD%E6%89%93%E5%BC%80DTrace%E6%94%AF%E6%8C%81.html</guid><description>&lt;p&gt;主要翻译自：&lt;a href="https://wiki.freebsd.org/DTrace"&gt;https://wiki.freebsd.org/DTrace&lt;/a&gt;&lt;/p&gt;&#10;&lt;p&gt;FreeBSD 跟 Linux 发行版一个比较大的差异，就是提倡源码构建。因此这里提到比较多的编译开关设置。自 2012 年 5 月后，DTrace 支持默认是打开的，因此以下步骤不再需要了。留意 uname -a 输出的日期即可。&lt;/p&gt;</description></item><item><title>压测周</title><link>https://spin6lock.github.io/2013/10/27/%E5%8E%8B%E6%B5%8B%E5%91%A8.html</link><pubDate>Sun, 27 Oct 2013 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2013/10/27/%E5%8E%8B%E6%B5%8B%E5%91%A8.html</guid><description>&lt;p&gt;本周主要工作是解决 dbd 的多线程 bug，可是失败了。&lt;/p&gt;&#10;&lt;p&gt;为了重现这个多线程的 bug，准备模拟多用户登录的情景，当多个用户需要保存数据的时候，就会跑到多线程序列化数据的部分，应该可以重现这个 bug。于是，从周一到周三，花了三天时间，用 python+gevent 写了一个模拟客户端，实现了客户端连接服务器和登录的流程。其实这个测试工具，在上一个项目里已经写了一点了，基本数据类型的解包比如整型，字符串解包已经有了。但是，我翻看代码才发现，当时没有写打包协议的实现写的过程比较流畅，用了 mixin 的方式将 rpc 协议独立出来一个 RpcMixin 类，这个类最后会被 SimulateUser 类继承，而 SimualteUser 则负责提供连接好的 socket，以及相应的 greenlet 协程、登录用户名。唯一比较严重的 bug，是启动时并发多个 greenlet 协程的时候，用了 range 而非 xrange，又手残多填了几个 0，结果 CPU 和内存都耗在了产生 range(1000000000) 这个巨大无比的整数列表上了。&lt;/p&gt;</description></item><item><title>类型系统线程安全</title><link>https://spin6lock.github.io/2013/10/20/%E7%B1%BB%E5%9E%8B%E7%B3%BB%E7%BB%9F%E7%BA%BF%E7%A8%8B%E5%AE%89%E5%85%A8.html</link><pubDate>Sun, 20 Oct 2013 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2013/10/20/%E7%B1%BB%E5%9E%8B%E7%B3%BB%E7%BB%9F%E7%BA%BF%E7%A8%8B%E5%AE%89%E5%85%A8.html</guid><description>&lt;p&gt;最近情绪有点失控，跟很欣赏的同事吵架了，真难过。有些话，可能真的只有吵架才会说出口，只好安慰自己，这未尝不是一次难得的交流。究其原因，就是一段代码由我开发，他接手维护，然后交给我继续跟进；最近频繁报 bug，他觉得在替我擦屁股，收拾代码，我也觉得我在替他擦屁股，大家心里有气，但是谁也没有说出口。多点面对面交流，多点讨论，工作压力小一点，可能就可以避免了。&lt;/p&gt;</description></item><item><title>dbd 到 mongo 的序列化问题及稳定性</title><link>https://spin6lock.github.io/2013/10/13/dbd%E5%88%B0mongo%E7%9A%84%E5%BA%8F%E5%88%97%E5%8C%96%E9%97%AE%E9%A2%98%E5%8F%8A%E7%A8%B3%E5%AE%9A%E6%80%A7.html</link><pubDate>Sun, 13 Oct 2013 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2013/10/13/dbd%E5%88%B0mongo%E7%9A%84%E5%BA%8F%E5%88%97%E5%8C%96%E9%97%AE%E9%A2%98%E5%8F%8A%E7%A8%B3%E5%AE%9A%E6%80%A7.html</guid><description>&lt;p&gt;最近工作压力有点大，情绪偶然会失控，要好好反省一下自己。&lt;/p&gt;&#10;&lt;p&gt;上周本来打算写 CSP 相关的东西，但是目前做得还不够多，积累的经验不足，就放弃了。中间找到很好的参考资料，一并放在这里。一篇是比较短的论文，可以观其大略：http://www.cs.ucf.edu/courses/cop4020/sum2009/CSP-hoare.pdf，另一个链接是 hoare 写的关于进程演算的书：https://dl.dropboxusercontent.com/u/5660734/CSPbook_2004_Hoare.rar 对于理解 CSP 这个模型的数学基础很有帮助。不过书好长，还没看完。。。&lt;/p&gt;</description></item><item><title>进程演算中的事件概念</title><link>https://spin6lock.github.io/2013/10/07/%E8%BF%9B%E7%A8%8B%E6%BC%94%E7%AE%97%E4%B8%AD%E7%9A%84%E4%BA%8B%E4%BB%B6%E6%A6%82%E5%BF%B5.html</link><pubDate>Mon, 07 Oct 2013 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2013/10/07/%E8%BF%9B%E7%A8%8B%E6%BC%94%E7%AE%97%E4%B8%AD%E7%9A%84%E4%BA%8B%E4%BB%B6%E6%A6%82%E5%BF%B5.html</guid><description>&lt;p&gt;最近将军团模块的 bug 修的差不多了，可以准备下一步的分布式改造了。只是每次想起这工程量，就有够头大的了。&lt;/p&gt;&#10;&lt;p&gt;在修改军团的时候，除了不断增补单元测试，就是思考分布式的交互。不同进程间的交互，一个 rpc 协议就是一个消息，消息间是有严格的先后顺序的，&lt;/p&gt;</description></item><item><title>青春请你归来，再伴我一会</title><link>https://spin6lock.github.io/2013/09/28/%E9%9D%92%E6%98%A5%E8%AF%B7%E4%BD%A0%E5%BD%92%E6%9D%A5-%E5%86%8D%E4%BC%B4%E6%88%91%E4%B8%80%E4%BC%9A.html</link><pubDate>Sat, 28 Sep 2013 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2013/09/28/%E9%9D%92%E6%98%A5%E8%AF%B7%E4%BD%A0%E5%BD%92%E6%9D%A5-%E5%86%8D%E4%BC%B4%E6%88%91%E4%B8%80%E4%BC%9A.html</guid><description>&lt;p&gt;加班到 12 点，走出公司的时候，发现大街上伴我同行的，只有一大帮小姐了，so sad&lt;/p&gt;&#10;&lt;p&gt;持续加班获得的效率红利已经渐渐消失，前面留下的技术债越来越成为前进的障碍。发版本的前一晚，提交频率非常高，经常有人抱怨更新后进不去游戏。客户端没有人搞单元测试，偏偏脚本又无法通过静态编译消灭一部分低级错误。于是，就变成了《唐伯虎点秋香》那一幕：&lt;/p&gt;</description></item><item><title>再堕噩梦，斩龙之旅</title><link>https://spin6lock.github.io/2013/09/15/%E5%86%8D%E5%A0%95%E5%99%A9%E6%A2%A6-%E6%96%A9%E9%BE%99%E4%B9%8B%E6%97%85.html</link><pubDate>Sun, 15 Sep 2013 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2013/09/15/%E5%86%8D%E5%A0%95%E5%99%A9%E6%A2%A6-%E6%96%A9%E9%BE%99%E4%B9%8B%E6%97%85.html</guid><description>&lt;img src="http://images.cnitblog.com/blog/90397/201309/15230418-6041b6a9e63a4f429ffeb0ccaa1a0975.jpg" alt="" /&gt;&#10;&lt;p&gt;本周继续做公会功能，有点乏味。&lt;/p&gt;&#10;&lt;p&gt;这次主要是基于上周完成的框架，进行具体功能的协议对接。原本以为对接会很简单，毕竟之前的功能模块都已经写过单元测试了，虽然覆盖率不高，好歹还是能跑通 happy path 的。实际用的时候，才发现上周设计的 api 粒度太细了。隐约记得第一次做公会，也是犯了这个错误，api 之间是十分正交，每一个完成的功能也很简单，方便测试。但是，用的时候需要调用多个 api，因此需要处理多种错误情况，而没有 goto 语句，又导致需要将同一段错误处理代码多次复制粘贴。&lt;/p&gt;</description></item><item><title>抄作业的一周</title><link>https://spin6lock.github.io/2013/09/08/%E6%8A%84%E4%BD%9C%E4%B8%9A%E7%9A%84%E4%B8%80%E5%91%A8.html</link><pubDate>Sun, 08 Sep 2013 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2013/09/08/%E6%8A%84%E4%BD%9C%E4%B8%9A%E7%9A%84%E4%B8%80%E5%91%A8.html</guid><description>&lt;p&gt;本周主要处理军团的抄袭工作。。。&lt;/p&gt;&#10;&lt;p&gt;第二次做类似公会模块的东东了，分功能的时候还算轻车熟路，只是几个管理器之间概念层次不同，组装的时候还真费神。这一块的东西，技术上倒谈不上有什么难度，但是比较繁琐，就怕某个功能点没做好，以后填坑就痛苦了。这次配合着单元测试来搞，每个功能组件都有单元测试配套，然后自己写了一点文档，说明这个模块的组成，各个功能需要实现的目标，希望以后修改会比较方便。&lt;/p&gt;</description></item><item><title>supervisor 很赞！</title><link>https://spin6lock.github.io/2013/08/29/supervisor%E5%BE%88%E8%B5%9E.html</link><pubDate>Thu, 29 Aug 2013 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2013/08/29/supervisor%E5%BE%88%E8%B5%9E.html</guid><description>&lt;p&gt;最近，公司进行了新的架构设计，原来一个区服一组进程，变成了对外只有一台服，后面 N 组多进程进行服务的模式。于是，管理进程就变成了一个头痛的问题。原来是在写代码的目录里放置各种脚本解决的，关闭脚本，开启脚本，重启脚本，更新脚本，还有一打用来看各种日志的脚本。这些脚本还是严重目录相关的，要执行某些命令，只能 cd 到指定目录执行（或者用硬连接 + 设置脚本所在目录为当前目录解决？whatever）。遇到实际部署的时候，还需要 ssh 到指定机器上，运行指定脚本，有时候还担心服务器起不来，需要人肉 ssh 过去看 status 或者 tail 日志看。&lt;/p&gt;</description></item><item><title>添加 mongodb 支持</title><link>https://spin6lock.github.io/2013/08/18/%E6%B7%BB%E5%8A%A0mongodb%E6%94%AF%E6%8C%81.html</link><pubDate>Sun, 18 Aug 2013 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2013/08/18/%E6%B7%BB%E5%8A%A0mongodb%E6%94%AF%E6%8C%81.html</guid><description>&lt;p&gt;最近花了些时间，将引擎的存储换成了 mongodb。&lt;/p&gt;&#10;&lt;p&gt;私下，我觉得现有的存储机制极为落后。现在写数据的操作交由单独的进程完成，该进程兼当数据缓冲与持续化数据的责任。此次引擎的更换，只是简单的利用 mongo 的官方 c 驱动，将数据打到 mongo 里面，代替写文件的做法而已。该进程的数据缓冲角色，还是没有变化。mongodb 的优势在于对内存的高效利用，增加一层作为中转，就会失去这个速度上的优势。&lt;/p&gt;</description></item><item><title>TheimplementationofLua5.0 阅读笔记（二）</title><link>https://spin6lock.github.io/2013/07/17/TheimplementationofLua5.0%E9%98%85%E8%AF%BB%E7%AC%94%E8%AE%B0-%E4%BA%8C.html</link><pubDate>Wed, 17 Jul 2013 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2013/07/17/TheimplementationofLua5.0%E9%98%85%E8%AF%BB%E7%AC%94%E8%AE%B0-%E4%BA%8C.html</guid><description>&lt;p&gt;6 线程和协程&lt;/p&gt;&#10;&lt;p&gt;读完这篇文章我才意识到 python 的协程到底缺了什么，这个就是 coroutine 和 semi-coroutine 的区别了。区别就是，semi-coroutine 只能返回（yield）到调用者所在位置，不能将控制权交到任意其他协程上去。具有这个特征的，都是 semi-coroutine。&lt;/p&gt;</description></item><item><title>TheImplementationofLua5.0 阅读笔记（一）</title><link>https://spin6lock.github.io/2013/07/16/TheImplementationofLua5.0%E9%98%85%E8%AF%BB%E7%AC%94%E8%AE%B0-%E4%B8%80.html</link><pubDate>Tue, 16 Jul 2013 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2013/07/16/TheImplementationofLua5.0%E9%98%85%E8%AF%BB%E7%AC%94%E8%AE%B0-%E4%B8%80.html</guid><description>&lt;p&gt;没想到 Lua 的作者理论水平这么高，这篇文章读的我顿生高屋建瓴之感。云风分享了一篇中译：&lt;a href="http://www.codingnow.com/2000/download/The%20Implementation%20of%20Lua5.0.pdf"&gt;http://www.codingnow.com/2000/download/The%20Implementation%20of%20Lua5.0.pdf&lt;/a&gt;&lt;/p&gt;&#10;&lt;p&gt;全篇的主题有 4 个：1. 基于寄存器的虚拟机；2. 用于将 table 作为数组使用的新算法；3. 闭包的实现；4. 以及协程。第二点我关注不多，会写的比较简略。&lt;/p&gt;</description></item><item><title>移动安卓端网络库开发</title><link>https://spin6lock.github.io/2013/06/29/%E7%A7%BB%E5%8A%A8%E5%AE%89%E5%8D%93%E7%AB%AF%E7%BD%91%E7%BB%9C%E5%BA%93%E5%BC%80%E5%8F%91.html</link><pubDate>Sat, 29 Jun 2013 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2013/06/29/%E7%A7%BB%E5%8A%A8%E5%AE%89%E5%8D%93%E7%AB%AF%E7%BD%91%E7%BB%9C%E5%BA%93%E5%BC%80%E5%8F%91.html</guid><description>&lt;p&gt;最近在协助客户端做网络通讯和登录流程，增进了对 Lua 的了解，捣鼓 Libevent 的静态库编译，掌握了部分 Android NDK 的开发技巧。真机调试遇到一个比较大的问题，由于资源较大，打包出来的 apk 有 100Ｍ大小，每次因为一个语法错误或者路径大小写问题，导致重新写 apk，都有种吐血的感觉。因此，想搞个热更新的框架和联机远程调试的 Lua 调试器。&lt;/p&gt;</description></item><item><title>从 lua 调用 C 函数</title><link>https://spin6lock.github.io/2013/05/26/%E4%BB%8Elua%E8%B0%83%E7%94%A8C%E5%87%BD%E6%95%B0.html</link><pubDate>Sun, 26 May 2013 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2013/05/26/%E4%BB%8Elua%E8%B0%83%E7%94%A8C%E5%87%BD%E6%95%B0.html</guid><description>&lt;p&gt;最近在进入 Lua 编程的状态，一度令我困惑的是，Lua 提供的功能少的可怜，跟自备电池的 python 相比，可说是简陋了。连 table 的打印，都需要自己实现，也因此有了一打的第三方方案。后来我想明白了，以 Lua 和 C 如此紧密的关系，只需要建立 Lua 的 binding，那么丰富而性能强大的 C 库资源完全可以为 Lua 所用，这样就不愁功能缺失了。&lt;/p&gt;</description></item><item><title>新的开始</title><link>https://spin6lock.github.io/2013/05/17/%E6%96%B0%E7%9A%84%E5%BC%80%E5%A7%8B.html</link><pubDate>Fri, 17 May 2013 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2013/05/17/%E6%96%B0%E7%9A%84%E5%BC%80%E5%A7%8B.html</guid><description>&lt;p&gt;原项目没有上线的机会了，停止开发，伤心了好久。目前转到手机开发上去了，使用开源的 cocos-2dx 引擎，貌似坑比较多啊&lt;/p&gt;</description></item><item><title>外服部署时遇到的问题</title><link>https://spin6lock.github.io/2013/04/20/%E5%A4%96%E6%9C%8D%E9%83%A8%E7%BD%B2%E6%97%B6%E9%81%87%E5%88%B0%E7%9A%84%E9%97%AE%E9%A2%98.html</link><pubDate>Sat, 20 Apr 2013 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2013/04/20/%E5%A4%96%E6%9C%8D%E9%83%A8%E7%BD%B2%E6%97%B6%E9%81%87%E5%88%B0%E7%9A%84%E9%97%AE%E9%A2%98.html</guid><description>&lt;p&gt;吐槽一下，公司的权限给的很死，部署的时候麻烦事比较多，趁手的工具需要自己手动编译，无法利用 port 安装。&lt;/p&gt;&#10;&lt;p&gt;昨天遇到一个外服部署的问题，表现为外服不能登陆，用部署工具重新发布代码后，仍然如此。于是联系运维的同学进行处理，运维的同学帮助排障时发现引擎启动报错，提示 rc/simul_efun must be loadable，认为是代码的问题。回去检查代码后，没有发现问题，而且这个文件已经很长时间没有更改了，怀疑是编译的问题。后来，手动连接外服，将验证服务器跑起来了，但是游戏服依然提示同样的错误。最后通过备份代码，然后用验证服的代码加游戏服的配置启动成功。但是，对于这个错误还是很耿耿于怀，于是找公司的前辈帮忙排错，发现发布代码的过程里漏了一个关键的步骤，补上后似乎没有问题了。&lt;/p&gt;</description></item><item><title>迅捷 FASTFWR171-3G 实战 OpenWRT</title><link>https://spin6lock.github.io/2013/04/13/%E8%BF%85%E6%8D%B7FASTFWR171-3G%E5%AE%9E%E6%88%98OpenWRT.html</link><pubDate>Sat, 13 Apr 2013 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2013/04/13/%E8%BF%85%E6%8D%B7FASTFWR171-3G%E5%AE%9E%E6%88%98OpenWRT.html</guid><description>&lt;p&gt;FAST 是 TP-LINK 的一个子品牌，所推出的 FWR171-3G 与 TP-LINK wr703n 的硬件采用相同规格，而前者要便宜 20 块，区别只在品牌、外观与软件界面。于是果断入手，然后尝试 OpenWRT。&lt;/p&gt;&#10;&lt;p&gt;上手后第一件事，就是通过官方界面进行线路测试。目前的网络连接是，通过 RJ45 接口接入光猫进行 PPPOE 拨号，然后利用 wifi 信号完成无线路由功能。遗憾的是，通过官方界面进行拨号连接时提示密码错误，无法联通。于是，去找到了 wr703n 的固件刷上，文件是 &lt;a href="http://dl.vmall.com/c0zm3y2wb9"&gt;wr703nv1_cn_3_12_11_up(110926)(Fast-FWR171-3G).bin&lt;/a&gt; 注意上传过程比较慢，上传和设备重启中不要断电或断开连接。&lt;/p&gt;</description></item><item><title>游戏服务器设计的思考</title><link>https://spin6lock.github.io/2013/04/10/%E6%B8%B8%E6%88%8F%E6%9C%8D%E5%8A%A1%E5%99%A8%E8%AE%BE%E8%AE%A1%E7%9A%84%E6%80%9D%E8%80%83.html</link><pubDate>Wed, 10 Apr 2013 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2013/04/10/%E6%B8%B8%E6%88%8F%E6%9C%8D%E5%8A%A1%E5%99%A8%E8%AE%BE%E8%AE%A1%E7%9A%84%E6%80%9D%E8%80%83.html</guid><description>&lt;p&gt;gevent 并发模型：缺点：多玩家交互的时候需要使用锁，bug 比较隐蔽。进行耗时较长的查询时有可能某些资源已经过期，也需要使用锁保护。&lt;/p&gt;&#10;&lt;p&gt;Mudos Like: 优点：游戏逻辑进程同一时间只处理一个玩家的一个请求 缺点：与玩家交互比较密集的时候需要用到异步回调，需要从磁盘读数据的时候要异步回调，搞得写函数很恶心。而且回调函数里需要把前面的检查再做一次，跟 gevent 的并发模型比较没有了优势。&lt;/p&gt;</description></item><item><title>多语言协作与二进制交互</title><link>https://spin6lock.github.io/2013/03/26/%E5%A4%9A%E8%AF%AD%E8%A8%80%E5%8D%8F%E4%BD%9C%E4%B8%8E%E4%BA%8C%E8%BF%9B%E5%88%B6%E4%BA%A4%E4%BA%92.html</link><pubDate>Tue, 26 Mar 2013 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2013/03/26/%E5%A4%9A%E8%AF%AD%E8%A8%80%E5%8D%8F%E4%BD%9C%E4%B8%8E%E4%BA%8C%E8%BF%9B%E5%88%B6%E4%BA%A4%E4%BA%92.html</guid><description>&lt;p&gt;最近刚刚完成了服务器端 rpc 协议的 python 封装，理论上说，后续的开发可以以 python 继续进行了。只是代码热更新还没好，项目进度又吃紧，暂时先放下了。利用 rpc 协议连接不同进程，各个进程就可以自由选择语言去开发，不局限于 C、LPC 了。让项目能够充分利用各个语言的优势，在不同的场景下选择特长语言进行开发，这图景不错。&lt;/p&gt;</description></item><item><title>从一段代码里看 FreeBSD 与 Linux 内存分配的不同</title><link>https://spin6lock.github.io/2013/02/23/%E4%BB%8E%E4%B8%80%E6%AE%B5%E4%BB%A3%E7%A0%81%E9%87%8C%E7%9C%8BFreeBSD%E4%B8%8ELinux%E5%86%85%E5%AD%98%E5%88%86%E9%85%8D%E7%9A%84%E4%B8%8D%E5%90%8C.html</link><pubDate>Sat, 23 Feb 2013 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2013/02/23/%E4%BB%8E%E4%B8%80%E6%AE%B5%E4%BB%A3%E7%A0%81%E9%87%8C%E7%9C%8BFreeBSD%E4%B8%8ELinux%E5%86%85%E5%AD%98%E5%88%86%E9%85%8D%E7%9A%84%E4%B8%8D%E5%90%8C.html</guid><description>&lt;p&gt;唉，拖延症无以复加了。&lt;/p&gt;&#10;&lt;p&gt;最近，公司移植服务器端游戏引擎到 Linux 上的时候，遇上了段错误。问题代码大略如下：&lt;/p&gt;&#10;&lt;div class="td-code td-code--untitled" id="td-code-e375809c-fence-0" data-td-code data-td-code-auto-id&#10; data-td-language="" data-td-line-count="7"&gt;&#10; &lt;div class="td-code__viewport" id="td-code-e375809c-fence-0-viewport" data-td-code-viewport&gt;&lt;pre tabindex="0"&gt;&lt;code&gt;char *arr = malloc(len);&#10;...&#10;if (IsInvalid(arr[0])){&#10; arr++;&#10;}&#10;...&#10;free(arr);&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&#10;&lt;/div&gt;&#10;&lt;p&gt;很明显，对操作系统分配的内存块进行了指针操作后，再扔回到 free 函数进行释放，是会导致异常行为的。但是，该引擎的代码已经有较长的历史了，为什么在 FreeBSD 上没有遇到问题呢？&lt;/p&gt;</description></item><item><title>存储器性能测试</title><link>https://spin6lock.github.io/2013/01/23/%E5%AD%98%E5%82%A8%E5%99%A8%E6%80%A7%E8%83%BD%E6%B5%8B%E8%AF%95.html</link><pubDate>Wed, 23 Jan 2013 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2013/01/23/%E5%AD%98%E5%82%A8%E5%99%A8%E6%80%A7%E8%83%BD%E6%B5%8B%E8%AF%95.html</guid><description>&lt;img title="Xeon E5620" src="http://images.cnitblog.com/blog/90397/201301/10173657-887f5131eb5f4b2eadd5c8e928991dd6.png" alt="Xeon E5620" /&gt;&#10;&lt;p&gt;Xeon E5620&lt;/p&gt;&#10;&lt;img title="E7500" src="http://images.cnitblog.com/blog/90397/201301/10173913-6f9281a5a57640db8587da6fdf13050d.png" alt="E7500" /&gt;&#10;&lt;p&gt;E7500&lt;/p&gt;&#10;&lt;img src="http://images.cnitblog.com/blog/90397/201301/10173942-4cb3a0c4ec094a52ab707ba3a9280200.png" alt="" /&gt;&#10;&lt;p&gt;In virtual machine, E7500&lt;/p&gt;&#10;&lt;p&gt;最近做了个存储器性能测试，结果如上图。z 轴表示速度，单位是 MB/s, x 轴和 y 轴一个表示步长，即两次访问数据之间的距离；另一个是读写的数据总量，单位是字节。源代码可以通过 &lt;a href="http://csapp.cs.cmu.edu/public/1e/public/mountain.tar"&gt;http://csapp.cs.cmu.edu/public/1e/public/mountain.tar&lt;/a&gt; 获取。&lt;/p&gt;</description></item><item><title>欢送 2012</title><link>https://spin6lock.github.io/2012/12/31/%E6%AC%A2%E9%80%812012.html</link><pubDate>Mon, 31 Dec 2012 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2012/12/31/%E6%AC%A2%E9%80%812012.html</guid><description>&lt;p&gt;新年快乐！2012 年就要过去了，本月看代码为主，少动手了，分享两篇文章给大家：&lt;/p&gt;&#10;&lt;p&gt;第一篇是 varnish 作者 Poul henning 写的，题为 &lt;a href="https://www.varnish-cache.org/trac/wiki/ArchitectNotes"&gt;Notes from the Architect&lt;/a&gt;，作者的观点可以总结为三点：&lt;/p&gt;</description></item><item><title>tig 支持中文搜索</title><link>https://spin6lock.github.io/2012/11/29/tig%E6%94%AF%E6%8C%81%E4%B8%AD%E6%96%87%E6%90%9C%E7%B4%A2.html</link><pubDate>Thu, 29 Nov 2012 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2012/11/29/tig%E6%94%AF%E6%8C%81%E4%B8%AD%E6%96%87%E6%90%9C%E7%B4%A2.html</guid><description>&lt;p&gt;tig 是一个基于 ncurses 库的 git log、status 的浏览器，看 log 的时候非常方便，可以非常简单的查看每次 log 的 diff，同时方便的切换到其他视角例如 diff、blame、tree 等等。但是，tig 有一个问题，不支持搜索中文。&lt;/p&gt;</description></item><item><title>LPC 及 MudOS 简介 ( 一 )</title><link>https://spin6lock.github.io/2012/08/19/LPC%E5%8F%8AMudOS%E7%AE%80%E4%BB%8B%28%E4%B8%80%29.html</link><pubDate>Sun, 19 Aug 2012 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2012/08/19/LPC%E5%8F%8AMudOS%E7%AE%80%E4%BB%8B%28%E4%B8%80%29.html</guid><description>&lt;p&gt;天下盛境这个项目让我萌生退意了，拖延了一个多月，没想到公司居然先解散了。接着是面试，入职新公司，回头看来，还是感慨人算不如天算阿。&lt;/p&gt;&#10;&lt;p&gt;新公司也是游戏行业的，初看了下项目的架构，与以前的有较大差别，是一套脱胎于 MudOS 的异步 IO、多进程的游戏架构。于是最近在研究 Mudos 的相关知识。刚刚入门，挑了最简单的 Lil Mudlib 进行学习，Mudos 的版本为 v22.2b14，既能够成功跑起来接受玩家的链接，又不会有复杂的功能阻碍理解，正好动手边改边学。&lt;/p&gt;</description></item><item><title>大面积断线原因分析</title><link>https://spin6lock.github.io/2012/06/15/%E5%A4%A7%E9%9D%A2%E7%A7%AF%E6%96%AD%E7%BA%BF%E5%8E%9F%E5%9B%A0%E5%88%86%E6%9E%90.html</link><pubDate>Fri, 15 Jun 2012 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2012/06/15/%E5%A4%A7%E9%9D%A2%E7%A7%AF%E6%96%AD%E7%BA%BF%E5%8E%9F%E5%9B%A0%E5%88%86%E6%9E%90.html</guid><description>&lt;p&gt;昨天，在台服上运行的服务器爆发了大面积断线。从时间点上看，跟一个副本活动高度重合，因此，今天早上就紧急屏蔽了该活动模块。&lt;/p&gt;&#10;&lt;p&gt;拿到 log 进行分析，看到的异常大部分是从战斗副本返回主城时发生的。副本活动产生的异常倒是没有看到，而且这个副本在国内也经历过几个运营商实际运营的测试，出现问题的机会应该比较少。&lt;/p&gt;</description></item><item><title>断线与资源释放</title><link>https://spin6lock.github.io/2012/06/14/%E6%96%AD%E7%BA%BF%E4%B8%8E%E8%B5%84%E6%BA%90%E9%87%8A%E6%94%BE.html</link><pubDate>Thu, 14 Jun 2012 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2012/06/14/%E6%96%AD%E7%BA%BF%E4%B8%8E%E8%B5%84%E6%BA%90%E9%87%8A%E6%94%BE.html</guid><description>&lt;p&gt;断线先不释放资源，待刚刚收到的请求完成后，再统一回收资源&lt;/p&gt;&#10;&lt;p&gt;开发框架应该提供一套通用的日志监控接口和资源分配接口，以确定资源的消耗情况，确定性能热点。&lt;/p&gt;</description></item><item><title>RPC 的思考</title><link>https://spin6lock.github.io/2012/06/12/RPC%E7%9A%84%E6%80%9D%E8%80%83.html</link><pubDate>Tue, 12 Jun 2012 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2012/06/12/RPC%E7%9A%84%E6%80%9D%E8%80%83.html</guid><description>&lt;h1 id="基于-google-protobuf-的-rpc-框架介绍系列文章"&gt;基于 google protobuf 的 rpc 框架介绍系列文章&#10;&lt;/h1&gt;&#10;&lt;h1 id="目前基于消息包的消息收发"&gt;目前，基于消息包的消息收发&#10;&lt;/h1&gt;&#10;&lt;p&gt;步骤：确定前端需要的相关信息&lt;/p&gt;&#10;&lt;p&gt;定义交互步骤&lt;/p&gt;</description></item><item><title>【翻译】HowwemakeGitHubfast( 我们如何让 github 更快 )</title><link>https://spin6lock.github.io/2012/05/20/%E7%BF%BB%E8%AF%91-HowwemakeGitHubfast%28%E6%88%91%E4%BB%AC%E5%A6%82%E4%BD%95%E8%AE%A9github%E6%9B%B4%E5%BF%AB%29.html</link><pubDate>Sun, 20 May 2012 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2012/05/20/%E7%BF%BB%E8%AF%91-HowwemakeGitHubfast%28%E6%88%91%E4%BB%AC%E5%A6%82%E4%BD%95%E8%AE%A9github%E6%9B%B4%E5%BF%AB%29.html</guid><description>&lt;p&gt;译者注：我是一名开源爱好者，十分喜爱 github，github 也是一个乐于分享的站点。这篇文章介绍了 github 为应对更高访问量而搭建的架构，虽然已经是 09 年的文章，仍有一定的参考价值，因此翻译此文分享给大家&lt;/p&gt;</description></item><item><title>tricks: 如何把 sqlalchemy 的数据转化为 json 格式</title><link>https://spin6lock.github.io/2012/02/22/tricks_%E5%A6%82%E4%BD%95%E6%8A%8Asqlalchemy%E7%9A%84%E6%95%B0%E6%8D%AE%E8%BD%AC%E5%8C%96%E4%B8%BAjson%E6%A0%BC%E5%BC%8F.html</link><pubDate>Wed, 22 Feb 2012 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2012/02/22/tricks_%E5%A6%82%E4%BD%95%E6%8A%8Asqlalchemy%E7%9A%84%E6%95%B0%E6%8D%AE%E8%BD%AC%E5%8C%96%E4%B8%BAjson%E6%A0%BC%E5%BC%8F.html</guid><description>&lt;p&gt;sqlalchemy 最恶心的对象，就是通过 execute 得到的结果，那是 rowproxy 列表。为了优化，rowproxy 使用了 &lt;strong&gt;slot&lt;/strong&gt;，使其失去了动态性，而又经常要转换成 json 格式，于是可以这样：&lt;/p&gt;</description></item><item><title>项目总结</title><link>https://spin6lock.github.io/2012/02/15/%E9%A1%B9%E7%9B%AE%E6%80%BB%E7%BB%93.html</link><pubDate>Wed, 15 Feb 2012 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2012/02/15/%E9%A1%B9%E7%9B%AE%E6%80%BB%E7%BB%93.html</guid><description>&lt;p&gt;入职一年有余了。&lt;/p&gt;&#10;&lt;p&gt;收获&lt;/p&gt;&#10;&lt;p&gt;　　第一次参加实战项目，也是第一次参加多人协作的项目，感觉很新鲜。回头看，学校应该多开展这样的训练。多人协作跟个人开发最大的不同，是需要大量阅读他人的项目代码，在实现功能的时候，也需要不断的进行妥协。要阅读一个新项目的代码，从最初的版本 checkout 进行阅读往往是比较好的选择，可以比较清晰的看到项目的架构思想，把握模块开发的惯用法。另外，首先阅读核心工具库帮助很大，一是能够很清晰看到老大的功力（笑），二是对于阅读他人的新模块，尽快投入开发，能够有较大帮助。&lt;/p&gt;</description></item><item><title>智能去除选定区域</title><link>https://spin6lock.github.io/2011/12/23/%E6%99%BA%E8%83%BD%E5%8E%BB%E9%99%A4%E9%80%89%E5%AE%9A%E5%8C%BA%E5%9F%9F.html</link><pubDate>Fri, 23 Dec 2011 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2011/12/23/%E6%99%BA%E8%83%BD%E5%8E%BB%E9%99%A4%E9%80%89%E5%AE%9A%E5%8C%BA%E5%9F%9F.html</guid><description>&lt;p&gt;这篇文章缘起于这篇博客：http://xiaoxia.org/2011/12/03/shocked-by-gimp-filter-smart-remove-selection/&lt;/p&gt;</description></item><item><title>分享三个好用的装饰器</title><link>https://spin6lock.github.io/2011/12/20/%E5%88%86%E4%BA%AB%E4%B8%89%E4%B8%AA%E5%A5%BD%E7%94%A8%E7%9A%84%E8%A3%85%E9%A5%B0%E5%99%A8.html</link><pubDate>Tue, 20 Dec 2011 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2011/12/20/%E5%88%86%E4%BA%AB%E4%B8%89%E4%B8%AA%E5%A5%BD%E7%94%A8%E7%9A%84%E8%A3%85%E9%A5%B0%E5%99%A8.html</guid><description>&lt;div class="td-code td-code--untitled" id="td-code-a018982a-fence-0" data-td-code data-td-code-auto-id&#10; data-td-language="" data-td-line-count="1"&gt;&#10; &lt;div class="td-code__viewport" id="td-code-a018982a-fence-0-viewport" data-td-code-viewport&gt;&lt;pre tabindex="0"&gt;&lt;code&gt;1 def log_wrapper(func):2 @functools.wraps(func)3 def log_func_name(self, *args, **kws):4 logger.debug(&amp;#34; 调用函数 [%s]&amp;#34;, func.func_name)5 logger.debug(&amp;#34; 参数为 :%s, %s&amp;#34;, [arg.__unicode__() for arg in args], kws)6 result = func(self, *args, **kws)7 logger.debug(&amp;#34; 返回的结果是 :%s&amp;#34;, result.__str__())8 return result9 return log_func_name&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&#10;&lt;/div&gt;&#10;&lt;p&gt;这个用于缓存计算量比较大或者需要 IO 的情况，用的时候只要 @Memorized(10) 这样就行了，不用更改原代码的逻辑，看起来比较干净清晰&lt;/p&gt;</description></item><item><title>根据 pythonprotobuf 自动生成 protobuf 包收发接口</title><link>https://spin6lock.github.io/2011/11/07/%E6%A0%B9%E6%8D%AEpythonprotobuf%E8%87%AA%E5%8A%A8%E7%94%9F%E6%88%90protobuf%E5%8C%85%E6%94%B6%E5%8F%91%E6%8E%A5%E5%8F%A3.html</link><pubDate>Mon, 07 Nov 2011 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2011/11/07/%E6%A0%B9%E6%8D%AEpythonprotobuf%E8%87%AA%E5%8A%A8%E7%94%9F%E6%88%90protobuf%E5%8C%85%E6%94%B6%E5%8F%91%E6%8E%A5%E5%8F%A3.html</guid><description>&lt;p&gt;利用 protobuf 进行串行化和反串行化处理，封装出来的 rpc 服务很好用。但是有个缺点，就是测试时，一些很简单的接口都要重新实现一次，程序体内就一些简单的赋值语句。写了个代码生成器，用来生成 protobuf 对应的请求函数和回应函数，请求函数根据 req 的内容，生成赋值函数体；回应函数只是负责把服务器返回的包进行打印。&lt;/p&gt;</description></item><item><title>台电 k6 你立功了</title><link>https://spin6lock.github.io/2011/09/21/%E5%8F%B0%E7%94%B5k6%E4%BD%A0%E7%AB%8B%E5%8A%9F%E4%BA%86.html</link><pubDate>Wed, 21 Sep 2011 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2011/09/21/%E5%8F%B0%E7%94%B5k6%E4%BD%A0%E7%AB%8B%E5%8A%9F%E4%BA%86.html</guid><description>&lt;p&gt;等了一年，还是停留在 v2.11 的固件上，英文就一渣排版。只能自己动手了&lt;/p&gt;&#10;&lt;p&gt;写了个英文排版的，两种排版方式，一是按 &lt;a href="http://zh.wikipedia.org/wiki/%E8%87%AA%E5%8A%A8%E6%8D%A2%E8%A1%8C#.E6.9C.80.E5.B0.8F.E7.A0.B4.E6.8D.9F.E5.BA.A6"&gt; 最小破损度 &lt;/a&gt; 进行排版，最小破损度追求的是文章排版的整齐性，也就是行尾空格数目尽可能相等。这样外观上就会比较平整，当然，行尾的空格可以移到行内，使得每行刚好满足给定宽度。另一种是按 &lt;a href="http://zh.wikipedia.org/wiki/%E8%87%AA%E5%8A%A8%E6%8D%A2%E8%A1%8C#.E6.9C.80.E5.B0.8F.E9.95.BF.E5.BA.A6"&gt; 最小行数 &lt;/a&gt; 进行排版。这种排版相当直观，就是把原文一个词一个词地放入一行中，当不能再放入时，就进行换行。&lt;/p&gt;</description></item><item><title>python 实现的简单的 epub2txt</title><link>https://spin6lock.github.io/2011/09/13/python%E5%AE%9E%E7%8E%B0%E7%9A%84%E7%AE%80%E5%8D%95%E7%9A%84epub2txt.html</link><pubDate>Tue, 13 Sep 2011 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2011/09/13/python%E5%AE%9E%E7%8E%B0%E7%9A%84%E7%AE%80%E5%8D%95%E7%9A%84epub2txt.html</guid><description>&lt;p&gt;等了 1 年，还是没等到台电 k6 的固件更新，好失望。&lt;/p&gt;&#10;&lt;p&gt;由于 k6 不支持 epub 的目录跳转、内嵌字体，且每次阅读均需要重新解压 epub，既浪费电又浪费时间，因此干脆转成 txt 算了。&lt;/p&gt;</description></item><item><title>vim 定制配色方案</title><link>https://spin6lock.github.io/2011/07/30/vim%E5%AE%9A%E5%88%B6%E9%85%8D%E8%89%B2%E6%96%B9%E6%A1%88.html</link><pubDate>Sat, 30 Jul 2011 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2011/07/30/vim%E5%AE%9A%E5%88%B6%E9%85%8D%E8%89%B2%E6%96%B9%E6%A1%88.html</guid><description>&lt;p&gt;个人一直比较喜欢内置的 desert 配色，无奈安装了 pyflakes 之后语法错误的地方老是看不清楚，纠结了很久。在 muzuiget 的指点下，有所进展。可以参考他写的 &lt;a href="http://qixinglu.com/archives/tools_for_terminal_vim_color_scheme"&gt;《Vim 终端配色转换工具》&lt;/a&gt;。但是转换色彩之后，还是无法转到自定义的颜色方案。&lt;/p&gt;</description></item><item><title>ubuntu 下访问 E72</title><link>https://spin6lock.github.io/2011/07/16/ubuntu%E4%B8%8B%E8%AE%BF%E9%97%AEE72.html</link><pubDate>Sat, 16 Jul 2011 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2011/07/16/ubuntu%E4%B8%8B%E8%AE%BF%E9%97%AEE72.html</guid><description>&lt;p&gt;由于家里的电脑没有蓝牙，每次传送文件都十分麻烦，像我这种懒人又不甘心去找数据线，只能够在 wifi 上打主意了。&lt;/p&gt;&#10;&lt;p&gt;E72 采用的是 s60v3 版 FP2 的系统，虽然是 sb 系统，不过比较实用。要完成这次跨系统文件传输的任务，还需要一个&lt;/p&gt;</description></item><item><title>python 实现的最近最少使用算法</title><link>https://spin6lock.github.io/2011/07/12/python%E5%AE%9E%E7%8E%B0%E7%9A%84%E6%9C%80%E8%BF%91%E6%9C%80%E5%B0%91%E4%BD%BF%E7%94%A8%E7%AE%97%E6%B3%95.html</link><pubDate>Tue, 12 Jul 2011 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2011/07/12/python%E5%AE%9E%E7%8E%B0%E7%9A%84%E6%9C%80%E8%BF%91%E6%9C%80%E5%B0%91%E4%BD%BF%E7%94%A8%E7%AE%97%E6%B3%95.html</guid><description>&lt;p&gt;LFU(Least Frequently Used，最少使用 ) 是一种缓存管理算法，其过期策略为替换出缓存中最少使用项。若各项使用次数相等，则参考 LRU(Least Recently Used，最近最少使用 ) 进行替换。&lt;/p&gt;</description></item><item><title>GreaseMonkey 渐进</title><link>https://spin6lock.github.io/2011/06/28/GreaseMonkey%E6%B8%90%E8%BF%9B.html</link><pubDate>Tue, 28 Jun 2011 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2011/06/28/GreaseMonkey%E6%B8%90%E8%BF%9B.html</guid><description>&lt;p&gt;此段代码是从 document 中取出所有标签为 div 的节点，放入 zPara 数组中，然后通过 for 循环统一改变其背景色和前景色。&lt;/p&gt;</description></item><item><title>新浪微博显示原创图片</title><link>https://spin6lock.github.io/2011/06/28/%E6%96%B0%E6%B5%AA%E5%BE%AE%E5%8D%9A%E6%98%BE%E7%A4%BA%E5%8E%9F%E5%88%9B%E5%9B%BE%E7%89%87.html</link><pubDate>Tue, 28 Jun 2011 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2011/06/28/%E6%96%B0%E6%B5%AA%E5%BE%AE%E5%8D%9A%E6%98%BE%E7%A4%BA%E5%8E%9F%E5%88%9B%E5%9B%BE%E7%89%87.html</guid><description>&lt;p&gt;鉴于我跟室友都比较渴求这个功能，尤其是观察美女时用，特别写了这个 userscript：&lt;/p&gt;&#10;&lt;p&gt;&lt;a href="http://userscripts.org/scripts/show/105670"&gt;http://userscripts.org/scripts/show/105670&lt;/a&gt;&lt;/p&gt;</description></item><item><title>如何组织文件</title><link>https://spin6lock.github.io/2011/03/17/%E5%A6%82%E4%BD%95%E7%BB%84%E7%BB%87%E6%96%87%E4%BB%B6.html</link><pubDate>Thu, 17 Mar 2011 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2011/03/17/%E5%A6%82%E4%BD%95%E7%BB%84%E7%BB%87%E6%96%87%E4%BB%B6.html</guid><description>&lt;p&gt;最近想入手个 1T 的移动硬盘，但是想到如何组织文件，就觉得十分头痛。&lt;/p&gt;&#10;&lt;p&gt;自我总结下文件组织的经历：&lt;/p&gt;&#10;&lt;p&gt;Windows&lt;/p&gt;&#10;&lt;p&gt;windows 天然的不稳定性，每每让我胆战心惊，很可能忽然在周末跪低，然后父亲大人就把 C 盘格式化了。因此，历史经验表明，C 盘是不能放资料的。惯常的组织方法是：&lt;/p&gt;</description></item><item><title>在 cygwin 上安装 gevent</title><link>https://spin6lock.github.io/2011/02/18/%E5%9C%A8cygwin%E4%B8%8A%E5%AE%89%E8%A3%85gevent.html</link><pubDate>Fri, 18 Feb 2011 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2011/02/18/%E5%9C%A8cygwin%E4%B8%8A%E5%AE%89%E8%A3%85gevent.html</guid><description>&lt;p&gt;由于公司点餐要用 QQ，只能寄身于 WinXP 下做开发。但是 win 下各种不能折腾很不爽，幸而有 Cygwin&lt;/p&gt;&#10;&lt;p&gt;然而，使用 easy_install 居然安装不了 Cygwin，弹出一大堆 core.c 的错误，一直没搞懂。只好与 win 的丑陋的命令行相伴，还设置了 PATH 指向 cygwin 的 bin，为的就是能顺利 ls。&lt;/p&gt;</description></item><item><title>使用 python 对 txt 格式的小说进行处理</title><link>https://spin6lock.github.io/2011/02/04/%E4%BD%BF%E7%94%A8python%E5%AF%B9txt%E6%A0%BC%E5%BC%8F%E7%9A%84%E5%B0%8F%E8%AF%B4%E8%BF%9B%E8%A1%8C%E5%A4%84%E7%90%86.html</link><pubDate>Fri, 04 Feb 2011 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2011/02/04/%E4%BD%BF%E7%94%A8python%E5%AF%B9txt%E6%A0%BC%E5%BC%8F%E7%9A%84%E5%B0%8F%E8%AF%B4%E8%BF%9B%E8%A1%8C%E5%A4%84%E7%90%86.html</guid><description>&lt;p&gt;vim 的确是神器，可惜 sed 与 vim 不完全通用。这篇文章受&lt;a href="http://hi.baidu.com/%C8%CB%BC%E4%CA%C0%E5%D0%D2%A3%D3%CE/blog/item/51f5ec1db41cffe51bd57630.html"&gt;《&lt;/p&gt;&#10;&lt;meta http-equiv="content-type" content="text/html; charset=utf-8" /&gt;&#10;用 vim 对 txt 格式的小说重新排版》&lt;/a&gt;的启发，在此致谢！&#10;&lt;p&gt;经常下载 txt 的电子书，格式却不合心意，只好自己再处理。首要的就是处理段内换行。&lt;/p&gt;</description></item><item><title>RLE 游程长度编码</title><link>https://spin6lock.github.io/2011/01/16/RLE%E6%B8%B8%E7%A8%8B%E9%95%BF%E5%BA%A6%E7%BC%96%E7%A0%81.html</link><pubDate>Sun, 16 Jan 2011 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2011/01/16/RLE%E6%B8%B8%E7%A8%8B%E9%95%BF%E5%BA%A6%E7%BC%96%E7%A0%81.html</guid><description>&lt;p&gt;昨天看心情好，就花了两个小时写了个 RLE 的 demo，可是 p7zip 帮我删了。。。晚上再写，用 gcc rle.c -o rle.c 脑抽啊我&lt;/p&gt;&#10;&lt;p&gt;今天不死心，再写了一个！【&lt;a href="http://files.cnblogs.com/Lifehacker/rleFile.7z"&gt;RLE 压缩 &lt;/a&gt;】&lt;/p&gt;&#10;&lt;p&gt;RLE 是基于这样一种思路：如果整个文件由 A 构成，那么我们只需要用 A 次数去表示该文件就可以了。 为了表示序列开始，需要一个标识符，我选择了 0xff。这样，每个序列就表示为 0xff 字符 次数。 当单个字符出现次数少于 3 的时候，压缩就得不偿失，因此对小于 3 个字符的不处理而直接输出。&lt;/p&gt;</description></item><item><title>SICP 与函数式编程</title><link>https://spin6lock.github.io/2011/01/05/SICP%E4%B8%8E%E5%87%BD%E6%95%B0%E5%BC%8F%E7%BC%96%E7%A8%8B.html</link><pubDate>Wed, 05 Jan 2011 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2011/01/05/SICP%E4%B8%8E%E5%87%BD%E6%95%B0%E5%BC%8F%E7%BC%96%E7%A8%8B.html</guid><description>&lt;p&gt;马马虎虎地看完了第四章跟第五章，终于可以为 SICP 这本书画上一个句号。&lt;/p&gt;&#10;&lt;p&gt;似乎 GCD 跟 fibonacci 这两个程序在每门语言里都会被实现一遍。这应该是涉及到递归的定义吧，对于函数式编程来说，递归是深刻而基础的，循环可以没有，递归不可或缺。特别是 fibonacci 的双递归，一方面考验了编程使用者的技巧，另一方面考验了这门编程语言的实现。（参见 &lt;a href="http://zh.wikipedia.org/zh-cn/%E7%BC%96%E8%AF%91%E5%99%A8%E9%80%92%E5%BD%92%E6%B5%8B%E8%AF%95"&gt; 维基百科 &lt;/a&gt;）&lt;/p&gt;</description></item><item><title>视频数据编解码技术</title><link>https://spin6lock.github.io/2010/12/29/%E8%A7%86%E9%A2%91%E6%95%B0%E6%8D%AE%E7%BC%96%E8%A7%A3%E7%A0%81%E6%8A%80%E6%9C%AF.html</link><pubDate>Wed, 29 Dec 2010 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2010/12/29/%E8%A7%86%E9%A2%91%E6%95%B0%E6%8D%AE%E7%BC%96%E8%A7%A3%E7%A0%81%E6%8A%80%E6%9C%AF.html</guid><description>&lt;p&gt;我真的很难专心持续做一件事情呢，最近因为课程需要写了篇文章应付，博诸君一笑&lt;/p&gt;&#10;&lt;p&gt;** 视频编码与文件格式的常见误区 **&lt;/p&gt;&#10;&lt;p&gt;常见的视频编码&lt;/p&gt;&#10;&lt;p&gt;MPEG2&lt;/p&gt;&#10;&lt;p&gt;MPEG-2 是 MPEG 工作组于 1994 年发布的视频和音频压缩国际标准。MPEG-2 通常用来为广播信号提供视频和音频编码，包括卫星电视、有线电视等。MPEG-2 经过少量修改后，也成为 DVD 产品的核心技术。MPEG-2 的系统描述部分（第 1 部分）定义了传输流，它用来一套在非可靠介质上传输数字视频信号和音频信号的机制，主要用在广播电视领域。MPEG-2 的第二部分即视频部分和 MPEG-1 类似，但是它提供对隔行扫描视频显示模式的支持（隔行扫描广泛应用在广播电视领域）。MPEG-2 视频并没有对低位速率（小于 1Mbps）进行优化，在 3Mbit/s 及以上位速率情况下，MPEG-2 明显优于 MPEG-1。MPEG-2 向后兼容，也即是说，所有符合标准的 MPEG-2 解码器也能够正常播放 MPEG-1 视频流。MPEG-2 技术也应用在了 HDTV 传输系统中。MPEG-2 的第三部分定义了音频压缩标准。该部分改进了 MPEG-1 的音频压缩，支持两通道以上的音频。MPEG-2 音频压缩部分也保持了向后兼容的特点。MPEG-2 的第七部分定义了不能向后兼容的音频压缩。该部分提供了更强的音频功能。通常我们所说的 MPEG-2AAC 指的就是这一部分。&lt;/p&gt;</description></item><item><title>C 程序设计语言答案 chapter3</title><link>https://spin6lock.github.io/2010/12/10/C%E7%A8%8B%E5%BA%8F%E8%AE%BE%E8%AE%A1%E8%AF%AD%E8%A8%80%E7%AD%94%E6%A1%88chapter3.html</link><pubDate>Fri, 10 Dec 2010 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2010/12/10/C%E7%A8%8B%E5%BA%8F%E8%AE%BE%E8%AE%A1%E8%AF%AD%E8%A8%80%E7%AD%94%E6%A1%88chapter3.html</guid><description>&lt;p&gt;&lt;a href="http://files.cnblogs.com/Lifehacker/ch3.7z"&gt; 第三章答案 &lt;/a&gt; 主要围绕 itoa 做文章，加深对整数类型的理解和字符串数组的操作。&lt;/p&gt;&#10;&lt;p&gt;第三章貌似是一个转折点，前面的练习更加像一些玩具，后面的会更有挑战性。&lt;/p&gt;</description></item><item><title>C 程序设计语言答案 chapter2</title><link>https://spin6lock.github.io/2010/11/30/C%E7%A8%8B%E5%BA%8F%E8%AE%BE%E8%AE%A1%E8%AF%AD%E8%A8%80%E7%AD%94%E6%A1%88chapter2.html</link><pubDate>Tue, 30 Nov 2010 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2010/11/30/C%E7%A8%8B%E5%BA%8F%E8%AE%BE%E8%AE%A1%E8%AF%AD%E8%A8%80%E7%AD%94%E6%A1%88chapter2.html</guid><description>&lt;p&gt;时不时练习一下还是蛮过瘾的，不过后面的习题应该会挺有难度吧，期待 ing&lt;/p&gt;&#10;&lt;p&gt;&lt;a href="http://files.cnblogs.com/Lifehacker/ch2.7z"&gt; 第二章答案 &lt;/a&gt;&lt;/p&gt;</description></item><item><title>C 程序设计语言答案 chapter1</title><link>https://spin6lock.github.io/2010/11/09/C%E7%A8%8B%E5%BA%8F%E8%AE%BE%E8%AE%A1%E8%AF%AD%E8%A8%80%E7%AD%94%E6%A1%88chapter1.html</link><pubDate>Tue, 09 Nov 2010 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2010/11/09/C%E7%A8%8B%E5%BA%8F%E8%AE%BE%E8%AE%A1%E8%AF%AD%E8%A8%80%E7%AD%94%E6%A1%88chapter1.html</guid><description>&lt;p&gt;最近面试屡屡受挫，搞得颇为狼狈。断断续续地看完了 K＆R 的 C Bible，刚把第一章的习题完成了。不得不说，这本薄薄的小书习题很有质量。对于指针的运用很有启发，给了我很多的灵感。看完很想说：原来 C 语言还可以这样用！&lt;/p&gt;</description></item><item><title>ubuntu 下 svn 上传到 googlecode</title><link>https://spin6lock.github.io/2010/10/19/ubuntu%E4%B8%8Bsvn%E4%B8%8A%E4%BC%A0%E5%88%B0googlecode.html</link><pubDate>Tue, 19 Oct 2010 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2010/10/19/ubuntu%E4%B8%8Bsvn%E4%B8%8A%E4%BC%A0%E5%88%B0googlecode.html</guid><description>&lt;p&gt;在 Google code 上也混迹了一段时间，提交 patch 和 issue 都试过了，可惜一直没找到哥们给个 commitor 当当。今天特地去挖了个坑，试试 owner 的滋味。&lt;/p&gt;&#10;&lt;ol&gt;&#10;&lt;li&gt;在 source 下的 checkout 里，可以很清晰地看到需要填写的命令。可是 ubuntu 的 svn 有点诡异，以 ownership checkout 一个 project，居然也不需要输入密码，搞了我很长时间。&lt;/li&gt;&#10;&lt;li&gt;更纠结的还在后头，svn add 添加完文件，svn commit 进行提交，发现首先要输入的是一个 Gnome keyring(null) 的密码，我输了很多遍 google code 的密码和邮箱密码，都不对，原来那是本机用户的密码。&lt;/li&gt;&#10;&lt;li&gt;接下来 google code 的服务器就会问你要帐号，若是 gmail 账户的话直接输入用户名即可，不用添加 @gmail。&lt;/li&gt;&#10;&lt;li&gt;接下来输入的是 google code 的密码。可以在 &lt;a href="http://code.google.com/hosting/settings"&gt;http://code.google.com/hosting/settings&lt;/a&gt; 里找到，这个密码十分复杂的说，在命令行下输入相当有难度。&lt;/li&gt;&#10;&lt;/ol&gt;</description></item><item><title>操作系统逻辑地址与物理地址的转换</title><link>https://spin6lock.github.io/2010/10/12/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E9%80%BB%E8%BE%91%E5%9C%B0%E5%9D%80%E4%B8%8E%E7%89%A9%E7%90%86%E5%9C%B0%E5%9D%80%E7%9A%84%E8%BD%AC%E6%8D%A2.html</link><pubDate>Tue, 12 Oct 2010 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2010/10/12/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F%E9%80%BB%E8%BE%91%E5%9C%B0%E5%9D%80%E4%B8%8E%E7%89%A9%E7%90%86%E5%9C%B0%E5%9D%80%E7%9A%84%E8%BD%AC%E6%8D%A2.html</guid><description>&lt;p&gt;逻辑地址 / 页面大小 = 页号&#10;逻辑地址 mod 页面大小 = 页内偏移&#10;通过页号查找页表得到对应的物理区块&#10;物理地址 = 物理区块 x 页大小 + 页内偏移&lt;/p&gt;&#10;&lt;p&gt;页号也可以通过位映射的方法实现，例如页表只有 4 项，则只需逻辑地址的前两位就可以确定页号。&lt;/p&gt;</description></item><item><title>入手台电 K6</title><link>https://spin6lock.github.io/2010/10/07/%E5%85%A5%E6%89%8B%E5%8F%B0%E7%94%B5K6.html</link><pubDate>Thu, 07 Oct 2010 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2010/10/07/%E5%85%A5%E6%89%8B%E5%8F%B0%E7%94%B5K6.html</guid><description>&lt;p&gt;最近入手了电纸书，折腾了好久，感觉有点浪费时间阿，这时间和钱拿去买书读书该多好&lt;/p&gt;&#10;&lt;p&gt;期间遇到一个问题，6 寸屏幕的电纸书看 pdf 相当痛苦，幸好新固件有 pdf 重排。但换行依然不知所谓不明就里不能人道于是需要自己处理下，网上流行一个 &lt;a href="http://bbs.mobread.com/thread-872-1-1.html"&gt;wps 处理法 &lt;/a&gt;，大意就是将 txt 文本粘贴进 wps 的 6 寸模板里，然后另存为 pdf。这样可以设置自己喜爱的字体，的确是不错的选择。此外还有通过虚拟打印机打印成 pdf 的。&lt;/p&gt;</description></item><item><title>archlinux 安装 quick-init 导致根目录可读的修复</title><link>https://spin6lock.github.io/2010/09/17/archlinux%E5%AE%89%E8%A3%85quick-init%E5%AF%BC%E8%87%B4%E6%A0%B9%E7%9B%AE%E5%BD%95%E5%8F%AF%E8%AF%BB%E7%9A%84%E4%BF%AE%E5%A4%8D.html</link><pubDate>Fri, 17 Sep 2010 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2010/09/17/archlinux%E5%AE%89%E8%A3%85quick-init%E5%AF%BC%E8%87%B4%E6%A0%B9%E7%9B%AE%E5%BD%95%E5%8F%AF%E8%AF%BB%E7%9A%84%E4%BF%AE%E5%A4%8D.html</guid><description>&lt;p&gt;不得不说，Arch Linux 真的非常快！搭积木式的构建方式可以给我一种掌控感。后来听说 quick-init 可以 4 秒启动，禁不住去试试，结果。。。失败了，只好卸载之，结果根文件系统变成只读，无法上网。。。&lt;/p&gt;</description></item><item><title>virtualbox 安装 gentoo</title><link>https://spin6lock.github.io/2010/09/14/virtualbox%E5%AE%89%E8%A3%85gentoo.html</link><pubDate>Tue, 14 Sep 2010 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2010/09/14/virtualbox%E5%AE%89%E8%A3%85gentoo.html</guid><description>&lt;p&gt;一直想尝试一下 fvwm，又不想搞坏现在的 ubuntu，顺便就搞个 gentoo 玩玩。&lt;/p&gt;&#10;&lt;p&gt;基本的安装顺序照官方的 guidebook 就可以了，但配置内核的时候要注意如下选项：&lt;/p&gt;&#10;&lt;div class="td-code td-code--untitled" id="td-code-cd1de94f-fence-0" data-td-code data-td-code-auto-id&#10; data-td-language="" data-td-line-count="34"&gt;&#10; &lt;div class="td-code__viewport" id="td-code-cd1de94f-fence-0-viewport" data-td-code-viewport&gt;&lt;pre tabindex="0"&gt;&lt;code&gt;Processor type and features ---&amp;gt;&#10; [*] Tickless System (Dynamic Ticks)&#10; [ ] High Resolution Timer Support&#10; [ ] Symmetric multi-processing support&#10; Subarchitecture Type (PC-compatible) ---&amp;gt;&#10; [ ] Machine Check Exception&#10;Power management and ACPI options ---&amp;gt;&#10; [*] Power Management support&#10; [ ] Suspend to RAM and standby&#10; [ ] Hibernation (aka &amp;#39;suspend to disk&amp;#39;)&#10; [*] ACPI (Advanced Configuration and Power Interface) Support ---&amp;gt;&#10;Device Drivers ---&amp;gt;&#10; &amp;lt; &amp;gt; ATA/ATAPI/MFM/RLL support&#10; &amp;lt;*&amp;gt; Serial ATA and Parallel ATA drivers&#10; &amp;lt;*&amp;gt; AHCI SATA Support&#10; [*] ATA SFF support&#10; &amp;lt;*&amp;gt; Intel ESB, ICH, PIIX3, PIIX4 PATA/SATA support&#10; [*] Network device support ---&amp;gt;&#10; [*] Ethernet (10 or 100Mbit) ---&amp;gt;&#10; [*] EISA, VLB, PCI and on board controllers&#10; &amp;lt;M&amp;gt; AMD PCnet32 PCI support&#10; [*] Ethernet (1000 Mbit) ---&amp;gt;&#10; &amp;lt;M&amp;gt; Intel(R) PRO/1000 Gigabit Ethernet support&#10; [ ] Ethernet (10000 Mbit) ---&amp;gt;&#10; Graphics support ---&amp;gt;&#10; &amp;lt;*&amp;gt; Direct Rendering Manager (XFree86 4.1.0 and higher DRI support) ---&amp;gt;&#10; &amp;lt; &amp;gt; all options can be empty&#10; &amp;lt;M&amp;gt; Sound card support ---&amp;gt;&#10; &amp;lt;M&amp;gt; Advanced Linux Sound Architecture ---&amp;gt;&#10; [*] PCI sound Devices ---&amp;gt;&#10; &amp;lt;M&amp;gt; Intel/SiS/nVidia/AMD/ALi AC97 Controller&#10; Input device support ---&amp;gt;&#10; [*] Mice ---&amp;gt;&#10; &amp;lt;*&amp;gt; PS/2 mouse&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&#10;&lt;/div&gt;&#10;&lt;p&gt;按以上配置的时候就可以得到 virtualbox-friendly 的 kernel 了&lt;/p&gt;</description></item><item><title>Ubuntu 下利用 expect 脚本自动登录 ssh 作代理</title><link>https://spin6lock.github.io/2010/09/05/Ubuntu%E4%B8%8B%E5%88%A9%E7%94%A8expect%E8%84%9A%E6%9C%AC%E8%87%AA%E5%8A%A8%E7%99%BB%E5%BD%95ssh%E4%BD%9C%E4%BB%A3%E7%90%86.html</link><pubDate>Sun, 05 Sep 2010 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2010/09/05/Ubuntu%E4%B8%8B%E5%88%A9%E7%94%A8expect%E8%84%9A%E6%9C%AC%E8%87%AA%E5%8A%A8%E7%99%BB%E5%BD%95ssh%E4%BD%9C%E4%BB%A3%E7%90%86.html</guid><description>&lt;p&gt;这类文章网上已经有很多了，实在不想再重复，可惜一直没有一个双击就连上 ssh 的，要不写个 GUI？putty 很搞，还是弹出一个命令行出来填用户名密码，那我干脆直接在 terminal 搞定啦。&lt;/p&gt;</description></item><item><title>着迷 twittering</title><link>https://spin6lock.github.io/2010/09/04/%E7%9D%80%E8%BF%B7twittering.html</link><pubDate>Sat, 04 Sep 2010 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2010/09/04/%E7%9D%80%E8%BF%B7twittering.html</guid><description>&lt;p&gt;似乎最近迷上了翻过伟大的长城这项体育活动，而且还是为翻墙而翻墙那一种。。。&lt;/p&gt;&#10;&lt;p&gt;继 twip 之后，又迷上了 gtap 这个 twitter api proxy。这个代理架设在 gae 上，用的还是我熟悉的 python 语言，非常亲切。当然，那坨 Django 的代码也不是我暂时能够捣鼓出来的，hack 的时候用了点拙劣的手法。&lt;/p&gt;</description></item><item><title>python-twitter 与第三方 api 协作</title><link>https://spin6lock.github.io/2010/08/25/python-twitter%E4%B8%8E%E7%AC%AC%E4%B8%89%E6%96%B9api%E5%8D%8F%E4%BD%9C.html</link><pubDate>Wed, 25 Aug 2010 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2010/08/25/python-twitter%E4%B8%8E%E7%AC%AC%E4%B8%89%E6%96%B9api%E5%8D%8F%E4%BD%9C.html</guid><description>&lt;p&gt;上回讲到搭建了 twip 作为 twitter api proxy，那当然要好好地利用一下。正好最近做了一个 twitter 的机器人，每次都要翻代理上推实在麻烦，另外一个问题是 twitter 对 http basic authorization 的限制逐渐收紧，现在的 api 限制为 60 per hour，稍后会再次缩减到 45，而 oauth 则相反，准备在 150/h 的基础上逐渐推到 1500/h（&lt;a href="https://groups.google.com/group/twitter-development-talk/browse_thread/thread/a1076d83d70d0450"&gt;via&lt;/a&gt;）。因此，利用 twip 的 oauth 特性进行中转会是相当不错的选择。&lt;/p&gt;</description></item><item><title>Oauth 与 twip 杂感</title><link>https://spin6lock.github.io/2010/08/22/Oauth%E4%B8%8Etwip%E6%9D%82%E6%84%9F.html</link><pubDate>Sun, 22 Aug 2010 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2010/08/22/Oauth%E4%B8%8Etwip%E6%9D%82%E6%84%9F.html</guid><description>&lt;p&gt;今天帮忙搭建 twip 了，主要参考了 &lt;a href="http://yht.in/archives/90"&gt;http://yht.in/archives/90&lt;/a&gt; 这篇文章。&lt;/p&gt;&#10;&lt;p&gt;twip 的主要原理，就是通过一台在墙外而国内又可以访问的独立主机作为跳板，国内用户首先连接到该独立主机上，然后再通过主机与 twitter 交换数据。为了提高安全性，twitter 今年 6 月份停止了 http basic authorize，取而代之的是 Oauth 的认证。用户的登录过程由 twitter 完成，最后 twitter 将用户的认证结果和授权告诉应用。得益于 twitter api 的简洁，以及标准的数据交互方式（可选择 xml、json 和 atom 其中一种），大量的第三方应用如雨后春笋般涌现出来，极大地丰富了 twitter 的表现形式（我终于可以手机上推啦 XD）。&lt;/p&gt;</description></item><item><title>sshtunnel 翻过伟大的长城</title><link>https://spin6lock.github.io/2010/08/19/sshtunnel%E7%BF%BB%E8%BF%87%E4%BC%9F%E5%A4%A7%E7%9A%84%E9%95%BF%E5%9F%8E.html</link><pubDate>Thu, 19 Aug 2010 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2010/08/19/sshtunnel%E7%BF%BB%E8%BF%87%E4%BC%9F%E5%A4%A7%E7%9A%84%E9%95%BF%E5%9F%8E.html</guid><description>&lt;p&gt;项目进入到一个稳定期，就等词库的扩张了。我打算在 twitter 上架设一个 twitter 机器人，搞搞新意思。看了下 twitter api 的文档，发现 python 的 twitter 库还真不少，看中的有两款：python-twitter 和&lt;/p&gt;</description></item><item><title>python 中文编码笔记</title><link>https://spin6lock.github.io/2010/08/10/python%E4%B8%AD%E6%96%87%E7%BC%96%E7%A0%81%E7%AC%94%E8%AE%B0.html</link><pubDate>Tue, 10 Aug 2010 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2010/08/10/python%E4%B8%AD%E6%96%87%E7%BC%96%E7%A0%81%E7%AC%94%E8%AE%B0.html</guid><description>&lt;p&gt;最近碰了很多钉子。。。&lt;/p&gt;&#10;&lt;p&gt;不得不说，python2.6 相较于之前发布的版本，就编码方面来说，有明显的进步。本机使用的是 python2.6，同样的代码根本没有遇到问题。到了服务器上部署时，一台服务器的 python2.5 和另一台服务器的 python2.4，都折磨得我苦不堪言。&lt;/p&gt;</description></item><item><title>分布式有感</title><link>https://spin6lock.github.io/2010/08/03/%E5%88%86%E5%B8%83%E5%BC%8F%E6%9C%89%E6%84%9F.html</link><pubDate>Tue, 03 Aug 2010 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2010/08/03/%E5%88%86%E5%B8%83%E5%BC%8F%E6%9C%89%E6%84%9F.html</guid><description>&lt;p&gt;最近有点疲于奔命的感觉，孤军作战不是好事阿。&lt;/p&gt;&#10;&lt;p&gt;以前学分布式计算原理与应用，一直对老师和教材有不满。教材虽然写的中规中矩，可是对 java 的偏向性无疑是一个败笔。书中的 Java 代码起个 helloworld 的作用还可以，真要用起来总觉得生涩无比，整天就在流里面转来转去。实验方面，socket 的相关代码没有 c 的清晰，要不是 string 类封装了一些应手的函数，真不知道有什么优点。RMI 看上去很美好，只是这种美好是建立在实验的基础上的。要真的应用起来，单单异常处理就会要命，网络的不确定性太多了，不是随便架起一层就能抹平的。&lt;/p&gt;</description></item><item><title>CrossSiteRequestForgeries 跨站伪请求</title><link>https://spin6lock.github.io/2010/07/09/CrossSiteRequestForgeries%E8%B7%A8%E7%AB%99%E4%BC%AA%E8%AF%B7%E6%B1%82.html</link><pubDate>Fri, 09 Jul 2010 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2010/07/09/CrossSiteRequestForgeries%E8%B7%A8%E7%AB%99%E4%BC%AA%E8%AF%B7%E6%B1%82.html</guid><description>&lt;p&gt;今天看 Django 的 tutorial，里面提到了这样一种跨站攻击：&lt;/p&gt;&#10;&lt;p&gt;假设有客户 Bob 在浏览论坛页面（Bob 真可怜～～～），Alice 发布了一个很热的帖子，里面有&lt;/p&gt;</description></item><item><title>chrome 关于 404 的错误处理</title><link>https://spin6lock.github.io/2010/07/03/chrome%E5%85%B3%E4%BA%8E404%E7%9A%84%E9%94%99%E8%AF%AF%E5%A4%84%E7%90%86.html</link><pubDate>Sat, 03 Jul 2010 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2010/07/03/chrome%E5%85%B3%E4%BA%8E404%E7%9A%84%E9%94%99%E8%AF%AF%E5%A4%84%E7%90%86.html</guid><description/></item><item><title>web.py+gae= 我的第一个留言板【二】</title><link>https://spin6lock.github.io/2010/06/30/web.py+gae=%E6%88%91%E7%9A%84%E7%AC%AC%E4%B8%80%E4%B8%AA%E7%95%99%E8%A8%80%E6%9D%BF-%E4%BA%8C.html</link><pubDate>Wed, 30 Jun 2010 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2010/06/30/web.py+gae=%E6%88%91%E7%9A%84%E7%AC%AC%E4%B8%80%E4%B8%AA%E7%95%99%E8%A8%80%E6%9D%BF-%E4%BA%8C.html</guid><description>&lt;p&gt;下面接着说说 google application engine 和 webpy 配套的问题。在我完成留言板的时候，这方面的资料还是很少，中文资料更少，希望 webpy 社区能够壮大啊。&lt;/p&gt;&#10;&lt;p&gt;gae 据说很有 Django 的风格，也是内置 Django 的，而 web.py 则需要自备。因此，在应用目录中应该放入 web.py 解压后得到的 web 目录。否则会导致 Import error: no module named web&lt;/p&gt;</description></item><item><title>web.py+gae= 我的第一个留言板【一】</title><link>https://spin6lock.github.io/2010/06/30/web.py+gae=%E6%88%91%E7%9A%84%E7%AC%AC%E4%B8%80%E4%B8%AA%E7%95%99%E8%A8%80%E6%9D%BF-%E4%B8%80.html</link><pubDate>Wed, 30 Jun 2010 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2010/06/30/web.py+gae=%E6%88%91%E7%9A%84%E7%AC%AC%E4%B8%80%E4%B8%AA%E7%95%99%E8%A8%80%E6%9D%BF-%E4%B8%80.html</guid><description>&lt;p&gt;最近体验了一把 web.py 开发的便捷。&lt;/p&gt;&#10;&lt;p&gt;建议在看 web.py 的 cookbook 之前，对 http 协议的 get 方法和 post 方法先了解一下，html 最好也要有基本的知识。&lt;/p&gt;&#10;&lt;p&gt;web.py 的工作流程，一般是从 URL 映射开始，然后把请求分派给不同的处理类处理，处理类比较像一个粘合层，负责从数据层拿数据，以及告诉 render 如何形成最后的页面效果。同时，它也负责控制整个交互的过程。数据层封装了数据库相关的操作，有了它，可以很方便的更换不同的数据库。当然，在具体的字段属性上，可能会有一定的差异，需要注意一下。&lt;/p&gt;</description></item><item><title>Datagramsocketwithconnection-orientedinJava</title><link>https://spin6lock.github.io/2010/06/22/Datagramsocketwithconnection-orientedinJava.html</link><pubDate>Tue, 22 Jun 2010 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2010/06/22/Datagramsocketwithconnection-orientedinJava.html</guid><description>&lt;p&gt;数据报通常采用 udp 协议进行传输，UDP 相较于 TCP 协议能够节省带宽，相应的获得较高速度，但不能保证包的安全抵达和顺序不变。&lt;/p&gt;&#10;&lt;p&gt;Java 关于 datagram 提供有 connect 方法，该方法绑定了远端的 IP 地址和端口号，即该 socket 以后只能向绑定目标主机发送数据或接受数据。&lt;/p&gt;</description></item><item><title>thetruthaboutsessions 择译</title><link>https://spin6lock.github.io/2010/06/20/thetruthaboutsessions%E6%8B%A9%E8%AF%91.html</link><pubDate>Sun, 20 Jun 2010 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2010/06/20/thetruthaboutsessions%E6%8B%A9%E8%AF%91.html</guid><description>&lt;p&gt;cookie&lt;/p&gt;&#10;&lt;p&gt;get parameter&lt;/p&gt;&#10;&lt;p&gt;cookie+fingerprint generated by user agent&lt;/p&gt;</description></item><item><title>web.py0.3 版本 tutorial 示例</title><link>https://spin6lock.github.io/2010/06/18/web.py0.3%E7%89%88%E6%9C%ACtutorial%E7%A4%BA%E4%BE%8B.html</link><pubDate>Fri, 18 Jun 2010 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2010/06/18/web.py0.3%E7%89%88%E6%9C%ACtutorial%E7%A4%BA%E4%BE%8B.html</guid><description>&lt;p&gt;我承认我看中文了。。。中文安装指南导向的是 web.py 0.2 版本的 tutorial 翻译，版本有点旧，且 0.3 与 0.2 的 tutorial 不兼容。&lt;/p&gt;&#10;&lt;p&gt;首先是下载压缩包，然后解压，最后 sudo ./setup.py （我用的是 ubuntu ）&lt;/p&gt;&#10;&lt;p&gt;示例代码如下，主要是 run 方法的方式有点不同。&lt;/p&gt;</description></item><item><title>apache-tomcat-6.0.26 的 cgi 配置过程</title><link>https://spin6lock.github.io/2010/05/24/apache-tomcat-6.0.26%E7%9A%84cgi%E9%85%8D%E7%BD%AE%E8%BF%87%E7%A8%8B.html</link><pubDate>Mon, 24 May 2010 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2010/05/24/apache-tomcat-6.0.26%E7%9A%84cgi%E9%85%8D%E7%BD%AE%E8%BF%87%E7%A8%8B.html</guid><description>&lt;p&gt;这东西折磨我太久了，写篇笔记。&lt;/p&gt;&#10;&lt;p&gt;Apache 的目录很好认，我下的是 zip 绿色版，解压开就看见 running 这个说明文件了，建议大家读读。&lt;/p&gt;&#10;&lt;p&gt;conf 目录是放置配置文件的，bin 则是可执行文件的位置，只需双击 startup.bat，即可启动 Apache。&lt;/p&gt;</description></item><item><title>MatlabCell 功能</title><link>https://spin6lock.github.io/2010/05/15/MatlabCell%E5%8A%9F%E8%83%BD.html</link><pubDate>Sat, 15 May 2010 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2010/05/15/MatlabCell%E5%8A%9F%E8%83%BD.html</guid><description>&lt;p&gt;　　最近完成模式分类的作业，需要大量使用 matlab, 期间发现了一个问题，是 matlab 代码的复用程度。&lt;/p&gt;&#10;&lt;p&gt;　　在面向过程编程里， 基本的复用单位是函数，程序的复杂度籍此下放到函数的接口上。设计好函数间的接口，基本上就成功了一半。在面向对象编程里， 基本的复用单位是对象，对象使得数据具有了一定程度的自维护。而在 matlab 里， 我很长时间都没有找到方向，因为我搞不清楚复用的单位是什么。&lt;/p&gt;</description></item><item><title>浅论函数式语言的环境，兼谈闭包</title><link>https://spin6lock.github.io/2010/05/03/%E6%B5%85%E8%AE%BA%E5%87%BD%E6%95%B0%E5%BC%8F%E8%AF%AD%E8%A8%80%E7%9A%84%E7%8E%AF%E5%A2%83-%E5%85%BC%E8%B0%88%E9%97%AD%E5%8C%85.html</link><pubDate>Mon, 03 May 2010 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2010/05/03/%E6%B5%85%E8%AE%BA%E5%87%BD%E6%95%B0%E5%BC%8F%E8%AF%AD%E8%A8%80%E7%9A%84%E7%8E%AF%E5%A2%83-%E5%85%BC%E8%B0%88%E9%97%AD%E5%8C%85.html</guid><description>&lt;p&gt;函数式语言与命令式语言的一个根本不同，就是下面这个两个数交换的例子居然是正确的：&lt;/p&gt;&#10;&lt;div class="td-code td-code--untitled" id="td-code-fd4253e6-fence-0" data-td-code data-td-code-auto-id&#10; data-td-language="" data-td-line-count="4"&gt;&#10; &lt;div class="td-code__viewport" id="td-code-fd4253e6-fence-0-viewport" data-td-code-viewport&gt;&lt;pre tabindex="0"&gt;&lt;code&gt;a=1&#10;b=2&#10;a,b=b,a&#10;print a ,b&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&#10;&lt;/div&gt;&#10;&lt;p&gt;输出 2 1&lt;/p&gt;&#10;&lt;p&gt;究其原因，是环境造成的。什么是环境呢？通俗点讲，你可以将环境看成是一个栈，栈单元的内容就是各个变量的值。可见，上述 a 和 b 赋值时的环境均是 a=1，b=2。再看一个 lisp 的例子：&lt;/p&gt;</description></item><item><title>最近要跟函数式语言干一仗！</title><link>https://spin6lock.github.io/2010/05/01/%E6%9C%80%E8%BF%91%E8%A6%81%E8%B7%9F%E5%87%BD%E6%95%B0%E5%BC%8F%E8%AF%AD%E8%A8%80%E5%B9%B2%E4%B8%80%E4%BB%97.html</link><pubDate>Sat, 01 May 2010 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2010/05/01/%E6%9C%80%E8%BF%91%E8%A6%81%E8%B7%9F%E5%87%BD%E6%95%B0%E5%BC%8F%E8%AF%AD%E8%A8%80%E5%B9%B2%E4%B8%80%E4%BB%97.html</guid><description>&lt;p&gt;本来打算先征服 ML（meta language）的，结果可耻地失败了，并且归结为译者水平太低。&lt;/p&gt;&#10;&lt;p&gt;然后拿了本《Lisp 语言》回来看，语言很平实，的确比较适合我，可惜作者马希文教授已经作古了，天妒英才啊。&lt;/p&gt;</description></item><item><title>RBF、K-NN 与 Decisiontree</title><link>https://spin6lock.github.io/2010/03/24/RBF-K-NN%E4%B8%8EDecisiontree.html</link><pubDate>Wed, 24 Mar 2010 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2010/03/24/RBF-K-NN%E4%B8%8EDecisiontree.html</guid><description>&lt;p&gt;要做一个 classifier，的确不易。面对需要训练的 classifier，是否 training error 越少越好呢？显然不是，因为虽然 training error 降低了，但 test error 不见得就会降低，实际表现为一个拐点。如下图：&lt;/p&gt;</description></item><item><title>java 路径设置</title><link>https://spin6lock.github.io/2010/03/16/java%E8%B7%AF%E5%BE%84%E8%AE%BE%E7%BD%AE.html</link><pubDate>Tue, 16 Mar 2010 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2010/03/16/java%E8%B7%AF%E5%BE%84%E8%AE%BE%E7%BD%AE.html</guid><description>&lt;p&gt;这个问题简直是痛中之痛，为什么如此现代，标榜人性化的 java 居然会让我等在环境变量的设置上反复煎熬？！&lt;/p&gt;&#10;&lt;p&gt;在 path 变量中 （没有则新建），添加&lt;/p&gt;&#10;&lt;p&gt;新建 CLASSPATH 变量 , 添加&lt;/p&gt;&#10;&lt;p&gt;文件名保存为 Hello.java，当前目录进入命令行，输入命令：&lt;/p&gt;</description></item><item><title>同步与异步</title><link>https://spin6lock.github.io/2010/03/09/%E5%90%8C%E6%AD%A5%E4%B8%8E%E5%BC%82%E6%AD%A5.html</link><pubDate>Tue, 09 Mar 2010 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2010/03/09/%E5%90%8C%E6%AD%A5%E4%B8%8E%E5%BC%82%E6%AD%A5.html</guid><description/></item><item><title>最长公共子序列 --- 从动态规划说起</title><link>https://spin6lock.github.io/2010/03/09/%E6%9C%80%E9%95%BF%E5%85%AC%E5%85%B1%E5%AD%90%E5%BA%8F%E5%88%97-%E4%BB%8E%E5%8A%A8%E6%80%81%E8%A7%84%E5%88%92%E8%AF%B4%E8%B5%B7.html</link><pubDate>Tue, 09 Mar 2010 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2010/03/09/%E6%9C%80%E9%95%BF%E5%85%AC%E5%85%B1%E5%AD%90%E5%BA%8F%E5%88%97-%E4%BB%8E%E5%8A%A8%E6%80%81%E8%A7%84%E5%88%92%E8%AF%B4%E8%B5%B7.html</guid><description>&lt;p&gt;我比较不长记性，你要我马上写一个动态规划给你是比较有难度的。在我眼里，动态规划就是一个优化程序的手段，适合于有大量重复子计算问题的时候用，原理就跟缓冲有点像，把需要重复计算的东西都放进内存里，需要的时候通过索引之类的东西直接查询，节省重新计算的时间。&lt;/p&gt;</description></item><item><title>JavaScript 中的闭包</title><link>https://spin6lock.github.io/2010/03/08/JavaScript%E4%B8%AD%E7%9A%84%E9%97%AD%E5%8C%85.html</link><pubDate>Mon, 08 Mar 2010 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2010/03/08/JavaScript%E4%B8%AD%E7%9A%84%E9%97%AD%E5%8C%85.html</guid><description>&lt;p&gt;一看到闭包这个词，我就会想起线性代数中的封闭空间，也就是说，这个空间中的所有向量，无论经过何种运算，最终结果还是会落在该空间中。那么 JavaScript 中会不会也是类似的概念呢？&lt;/p&gt;</description></item><item><title>StandardML 语言（一）</title><link>https://spin6lock.github.io/2010/02/06/StandardML%E8%AF%AD%E8%A8%80-%E4%B8%80.html</link><pubDate>Sat, 06 Feb 2010 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2010/02/06/StandardML%E8%AF%AD%E8%A8%80-%E4%B8%80.html</guid><description>&lt;p&gt;在 Windows 平台下推荐使用 Moscow ML 解释器，主要是安装比较方便，其他有 Standard ML of New Jersey, 安装后需要设置环境变量（即 bin 目录所在位置）。&lt;/p&gt;&#10;&lt;p&gt;要引用系统模块，请使用 load &amp;ldquo;module&amp;rdquo;, 例如：&lt;/p&gt;&#10;&lt;p&gt;-load &amp;ldquo;Math&amp;rdquo;;&lt;/p&gt;</description></item><item><title>初探 Git</title><link>https://spin6lock.github.io/2010/02/05/%E5%88%9D%E6%8E%A2Git.html</link><pubDate>Fri, 05 Feb 2010 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2010/02/05/%E5%88%9D%E6%8E%A2Git.html</guid><description>&lt;p&gt;今天闷着头看了半天 git，终于明白了 git 的基本工作原理。想提高你对 git 的认识，请移玉步到 &lt;a href="http://progit.org/book/zh"&gt;http://progit.org/book/zh&lt;/a&gt;，中文翻译很不错，感谢先行的兄弟们！&lt;/p&gt;&#10;&lt;p&gt;以前项目组进行版本管理的时候，采用的是 tortoiseSVN，正如某君所说，SVN 并非一无是处，但是总有又痛又痒的感觉。学习 SVN，我有了和其他人进行版本协作的经验，不过发生合并冲突的机会还是比较少的（一般每个人负责一个单元），常用的操作就是 checkout 然后 coding。不得不说，由于和服务器的交换速度太慢，且小文件居多，每次 checkout 和 commit 都非常痛苦。那时候就幻想，为什么版本管理不能放在本地呢&lt;/p&gt;</description></item><item><title>Linux 超级块</title><link>https://spin6lock.github.io/2010/02/03/Linux%E8%B6%85%E7%BA%A7%E5%9D%97.html</link><pubDate>Wed, 03 Feb 2010 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2010/02/03/Linux%E8%B6%85%E7%BA%A7%E5%9D%97.html</guid><description>&lt;p&gt;Linux 超级块的结构&lt;/p&gt;</description></item><item><title>嵌入式系统概念笔记</title><link>https://spin6lock.github.io/2010/02/03/%E5%B5%8C%E5%85%A5%E5%BC%8F%E7%B3%BB%E7%BB%9F%E6%A6%82%E5%BF%B5%E7%AC%94%E8%AE%B0.html</link><pubDate>Wed, 03 Feb 2010 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2010/02/03/%E5%B5%8C%E5%85%A5%E5%BC%8F%E7%B3%BB%E7%BB%9F%E6%A6%82%E5%BF%B5%E7%AC%94%E8%AE%B0.html</guid><description/></item><item><title>linux 进程信息</title><link>https://spin6lock.github.io/2009/11/03/linux%E8%BF%9B%E7%A8%8B%E4%BF%A1%E6%81%AF.html</link><pubDate>Tue, 03 Nov 2009 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2009/11/03/linux%E8%BF%9B%E7%A8%8B%E4%BF%A1%E6%81%AF.html</guid><description/></item><item><title>watchdog</title><link>https://spin6lock.github.io/2009/11/03/watchdog.html</link><pubDate>Tue, 03 Nov 2009 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2009/11/03/watchdog.html</guid><description/></item><item><title>copyonwrite</title><link>https://spin6lock.github.io/2009/10/31/copyonwrite.html</link><pubDate>Sat, 31 Oct 2009 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2009/10/31/copyonwrite.html</guid><description/></item><item><title>反转分页表（Invertedpagetables)</title><link>https://spin6lock.github.io/2009/09/29/%E5%8F%8D%E8%BD%AC%E5%88%86%E9%A1%B5%E8%A1%A8-Invertedpagetables%29.html</link><pubDate>Tue, 29 Sep 2009 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2009/09/29/%E5%8F%8D%E8%BD%AC%E5%88%86%E9%A1%B5%E8%A1%A8-Invertedpagetables%29.html</guid><description/></item><item><title>银行家算法（Thebanker'salgorithm)</title><link>https://spin6lock.github.io/2009/09/28/%E9%93%B6%E8%A1%8C%E5%AE%B6%E7%AE%97%E6%B3%95-Thebanker%27salgorithm%29.html</link><pubDate>Mon, 28 Sep 2009 00:00:00 +0800</pubDate><guid>https://spin6lock.github.io/2009/09/28/%E9%93%B6%E8%A1%8C%E5%AE%B6%E7%AE%97%E6%B3%95-Thebanker%27salgorithm%29.html</guid><description>&lt;ol&gt;&#10;&lt;li&gt;已被进程占用 1. 进程资源需求最大值 1. 系统可用资源 1. 有 A、B 两进程，当前可用资源无法满足任一进程的需要，但 A 在运行时暂时释放了所占用的资源，使得 B 得以结束，从而释放更多资源，使得 A 顺利结束。1. 有 A、B、C 三个进程，当前资源可以满足 A 的运行需要，因此此时 A 并没有陷入死锁。&lt;/li&gt;&#10;&lt;/ol&gt;</description></item></channel></rss>