从受损的 git 仓库里恢复代码

背景:Windows 上的 Virtualbox 虚拟机。Ubuntu 14.04.1 LTS,3.13 内核。ext4 文件系统。

作死:前几天一直在该虚拟机上开发网站,做了 N 多 commit,以为 git push 了,但事实上 push 失败了。

悬疑:今天妹子 git pull 了一下,发现没有任何更新,然后说我这几天都没干活。

悲剧:登录到虚拟机里一看,项目目录里有几个刚写的文件变成了 0 字节的空文件。(ext4 这么稳定,一定是母机里万恶的 NTFS 和 Virtualbox 惹的祸)
.git 目录里好多文件也变成了 0 字节的空文件。git 提示仓库已损坏。

$ git status
error: object file .git/objects/71/cbcbbc9d06a74f2fd8ea9109b81b88086f1430 is empty
error: object file .git/objects/71/cbcbbc9d06a74f2fd8ea9109b81b88086f1430 is empty
fatal: loose object 71cbcbbc9d06a74f2fd8ea9109b81b88086f1430 (stored in .git/objects/71/cbcbbc9d06a74f2fd8ea9109b81b88086f1430) is corrupt
$ git fsck
error: object file .git/objects/00/837a7e1f8afb8da8609369f7acf95fe9b7fc5b is empty
error: object file .git/objects/00/837a7e1f8afb8da8609369f7acf95fe9b7fc5b is empty
fatal: loose object 00837a7e1f8afb8da8609369f7acf95fe9b7fc5b (stored in .git/objects/00/837a7e1f8afb8da8609369f7acf95fe9b7fc5b) is corrupt

几天来写的代码是不是这样就灰飞烟灭了呢?我们知道,当你删除一个东西的时候,你只是删除了这个东西在当前三维空间中的引用,而这个东西的本体仍然存在于四维时空之中。穿越大法,走起!

继续阅读“从受损的 git 仓库里恢复代码”

大话同步/异步、阻塞/非阻塞

好多人搞不清这两组概念之间的区别。我们拿小明下载文件打个比方。

  1. 同步阻塞:小明一直盯着下载进度条,到 100% 的时候就完成。
  2. 同步非阻塞:小明提交下载任务后就去干别的,每过一段时间就去瞄一眼进度条,看到 100% 就完成。
  3. 异步阻塞:小明换了个有下载完成通知功能的软件,下载完成就“叮”一声。不过小明仍然一直等待“叮”的声音(看起来很傻,不是吗)
  4. 异步非阻塞:仍然是那个会“叮”一声的下载软件,小明提交下载任务后就去干别的,听到“叮”的一声就知道完成了。

也就是说,同步/异步是下载软件的通知方式,或者说 API 被调用者的通知方式。阻塞/非阻塞则是小明的等待方式,或者说 API 调用者的等待方式。

继续阅读“大话同步/异步、阻塞/非阻塞”

释放被文件系统吃掉的 5% 磁盘空间

使用 ext 文件系统存储数据的同学也许发现,200 G 的分区只能用 190 G,2000 GB 的分区只能用 1900 GB。这 5% 磁盘空间到哪里去了?有的同学认为这是 1000 进制与 1024 进制的区别,但事实并非如此。

$ df /mnt/sdb/
Filesystem      1K-blocks       Used Available Use% Mounted on
/dev/sdb       1922860936 1839798972         0 100% /mnt/sdb

上面这块标称 2 T 的磁盘可用空间为 0,看起来是满了。试着创建一个目录,发现没有空间了。

$ mkdir hello
mkdir: cannot create directory `hello': No space left on device

但 sudo mkdir hello 竟然能成功!这是怎么回事呢?答案在 ext 文件系统的 “预留空间” 里。

继续阅读“释放被文件系统吃掉的 5% 磁盘空间”

一个抗污染 DNS 的搭建

DNS 服务是互联网的重要基础服务,不过它的重要性往往被低估。例如,2013年8月,.cn 根域名服务器遭到 DDoS 攻击,导致 .cn 域名无法访问;2014年1月21日,根域名服务器遭到某著名防火墙污染,导致所有国际域名无法访问。很多国际知名网站在中国大陆无法访问,部分原因就是遭受了 DNS 污染,也就是对域名返回了错误的 IP 地址。

要搭建一个抗污染的 DNS,并不是使用 VPN 解析所有域名这么简单。主要有两个问题:

  1. 国内很多大型网站会被解析到其他运营商的 IP 甚至国外 IP,访问很慢。
  2. VPN 容易遭到间歇丢包等干扰,不稳定。

继续阅读“一个抗污染 DNS 的搭建”

编写高性能软件的几个技巧

随着计算机处理能力的提高和软件复杂程度的上升,性能往往并不是衡量软件的最重要标准。但有时我们确实需要把计算机的性能榨干。尤其是做研究的时候,为了让性能指标超过对手,不仅要优化算法(渐进复杂度),还要优化实现(复杂度中的常数)。本文试图总结一些规律,望与大家讨论:

不要使用开源软件

开源软件往往考虑的是一个通用问题,因此有很多几乎永远也用不到的配置参数和条件判断;开源软件对代码可读性、可维护性的要求往往高于对性能的要求,因此一般不使用所谓的“奇技淫巧”。

继续阅读“编写高性能软件的几个技巧”

让 Chrome 走 ssh 代理

有时要远程访问路由器 Web 控制面板等只能从服务器所在网络访问的网站。在服务器上用 links 显然是不靠谱的。我们可以在本机与服务器间用 ssh 打通隧道,让本地浏览器通过隧道访问受限的网站。

首先用 ssh -D 在本机与服务器间建立 socks5 隧道:(60000 是一个任意的大于 1024、小于 65536 的整数)

ssh -C2qTnN -D 60000 user@remote-host

然后就是让 Chrome 通过 socks5 隧道访问了。Chrome 插件 ProxySwitchy 由于 Chrome 不再支持 NPAPI 已经不 work,而 ProxySwitchySharp 有时也不 work。网上有些文章说 chrome –proxy-server 就行,事实上在你开着另外一个 Chrome 实例时是不 work 的,因为 Chrome 会自动寻找已经打开的实例。

比较靠谱的办法是,开 Incognito 匿名模式,并使用不存在的 Chrome 用户数据目录,断绝其寻找已打开实例的可能。用完之后,最好把新建的用户数据目录(下例中是 C:\Temp\Chrome)删除。注意,下面的 socks5 不可替换为 http,这是不同的协议。

PS C:\Program Files (x86)\Google\Chrome\Application> .\chrome.exe --proxy-server="socks5://127.0.0.1:60000" -incognito -user-data-dir=C:\Temp\Chrome

Win Vista/7/8 的 VirtualStore

用过 Windows Vista/7/8 的同学可能有这样的经历:用 32 位程序(比如 cygwin)修改 C 盘下的某个文件后,再从 Windows 资源管理器里看,竟然是修改前的版本!难道文件系统还对不同的程序有不同的视图?您说对了,自从 Vista 引入了 UAC 和 VirtualStore,不要相信 32 位程序在 C 盘里做的改动。

Windows Vista 引入更强的安全机制后,一些重要的系统目录就不是谁都能修改了。这些目录包括 C 盘根目录,Program Files,Program Files (x86),Windows,注册表的 HKEY_LOCAL_MACHINE 等。但一些老的应用程序仍然假定这些目录是可写的,如果系统 API 简单返回访问拒绝,则这些程序都不能运行了。

因此,Vista 提供了 VirtualStore,对非管理员权限运行的 32 位程序,只要对这些目录有写操作,就会把被修改或添加的文件复制一份到这个用户的 VirtualStore。以这个用户身份运行的 32 位程序看到的这个路径就是 VirtualStore 里的对应文件,原始路径上的文件再怎么修改,它已经全然不知了。

继续阅读“Win Vista/7/8 的 VirtualStore”

让 OpenVPN 默认不走 VPN

LUG VPN 的一些用户希望仅对某些特定 IP 使用 VPN,而 OpenVPN 默认是全部走 VPN。也许是我的搜索能力太差,竟然没有 Google 到靠谱的答案。没有耐心的读者可直接看我的解决方案:

$ echo "script-security 2" >>/etc/openvpn/client.conf
$ echo "up /usr/local/bin/remove-ovpn-defroute" >>/etc/openvpn/client.conf

$ cat /usr/local/bin/remove-ovpn-defroute
#!/bin/sh
(
    sleep 2 # wait for routing table to be flushed
    ip route del 0.0.0.0/1 dev tun0
    ip route del 128.0.0.0/1 dev tun0
) &
exit 0

继续阅读“让 OpenVPN 默认不走 VPN”

万通驿馆的无线网络认证

万通驿馆的无线网络是需要用户名密码进行认证的。在 Windows 上,只要连接上 “Vantone Inn” 这个接入点,就会弹出浏览器窗口,显示用户认证界面。访问任意 HTTP网址,也会跳转到认证界面。认证成功后,无线网络就畅通无阻了。今日某同学问我,这个接入点怎么这么NB,能强制电脑弹出窗口,莫非是病毒?

这个问题我也不知道,于是就抓了抓包,然后 Google 了一把。为了便于理解,我们先不讨论自动弹出浏览器,先想想如何实现“访问任意 HTTP 网址都会跳转到认证界面”。
继续阅读“万通驿馆的无线网络认证”