从ASC'14到ISC'15——我的超算竞赛生涯谢幕
世界上大型超算竞赛有:HPCAC-ISC、SC、ASC,叫做Student Cluster Competition(下面简称为SCC)。今年我也继何斌和fqj1994之后,一共参加过四次大赛了(ASC'14、ISC'14、ASC'15、ISC'15)。比赛期间费尽心力,ASC'14酸楚太多,ISC'14也有憋屈,没有分享其中曲折。ASC'15、ISC'15,清华大学队时隔三年重新捧杯,超算生涯圆满落幕,在此记录些琐事。
Nginx根据Accept-Language的简繁体支持
这个功能开启很久了,但直到昨天才发现遗漏了atom.xml
……
我想根据HTTP首部的Accept-Language
决定提供简体或繁体的文件。在Chrome中,chrome://settings/languages
可以设定偏好语言,浏览器会据此设置Accept-Language
首部。较好的处理方式是解析该字段,获取qvalue,根据优先级选取最恰当的语言。但仅用于支持简繁体,我想用取巧的办法:忽略优先级,只要Accept-Language
里出现了zh-Hant
、zh-TW
、zh-HK
等字样,就返回繁体,否则返回简体。
指定dynamic linker以使用高版本GCC
今天有人问怎么在没有root的不可更新老旧Linux环境里使用高版本GCC,主要困难在于GCC对glibc版本有一定要求。假设使用现成的GCC二进制包,解压到本地后执行gcc
,报错:/lib64/libc.so.6: version `GLIBC_2.14' not found
,即系统glibc的libc.so.6
中缺乏更高版本的符号(参考info '(ld) VERSION'
)。使用新符号通常表示API有更新,不过很多时候旧版本的库也能用,可能有两个原因:一是编译机器的库版本可能较新,soname版本号较高,编译出来的可执行文件也会有较高的版本要求;二是源文件因保守指定了较高的版本号,实际上旧版本也能用。
比如最近ncurses主版本号更新到6,/usr/lib/libncursesw.so.5
变成了/usr/lib/libncursesw.so.6
,导致很多可执行文件没法用了:
皈依Emacs
这应该算第三次使用Emacs了。第一次是在2009年,NOI 2009酱油后下决心好好学习Linux,Philip Xu前辈我指引了两天,发现Linux这个未知世界竟然有这么多好玩的软件。编辑器之神Vim用了一阵子了,NOIP 2009前若干天开始探索神的编辑器Emacs,使用Emacs Lisp配置,实现与Vim相似的设定效果需要多出好多代码,因此不久又回到Vim。大概2010下半年又用起Emacs,这次好好折腾了一把。当时Vim的插件生态还围绕vim.org(现在逐步转战GitHub了),Emacs倒是有个http://www.emacswiki.org,尝试了Mew、ERC、AUCTeX、haskell-mode、org-mode等好多东西。很多文件类型的解析、自动缩进支持比Vim对应物好不少,插件质量感觉也稍高。
J语言初探
先看些例子,感受一下J的魅力:
1 | +/\ i.6 NB. prefix sum of 0~5 |
DEFCON 23 CTF参赛记
8月4日
从北京出发,起飞前两小时发现机票没有买成功,立即买了一张,感谢诸位队友。到达San Francisco后与昨日航班延迟一天的队友会合,21:00多飞往Las Vegas。今年DEFCON会场从Rio迁到了Paris & Bally's。我们提前到达的在这里订了几间房间。

一次服务器BMC固件逆向经历
导出文件
访问BMC默认开启的Web管理界面http://$ip
,开启ssh
服务,之后即可以执行ssh root@$ip
,得到一个受限的管理界面,功能很少,没有系统shell。
在服务器上执行ipmitool fru
可以查找到设备型号,使用厂商提供的flash备份工具导出flash,比较慢,每秒200多KB。在BMC网页界面的BMC System Audit Log
中看到BMC的Linux系统日志:
常数空间Invert Binary Tree与仿Morris法后序遍历
今天在地铁上浪费了好多时间……呜呜……做其他事都没有效率,就利用这些时间写字了。
前几天LeetCode的Invert Binary Tree火了。名称有点糟,无法准确描述要求。
主要思路是遍历二叉树,把访问操作修改为交换左右孩子,每个节点都交换一次即可。
如果采用前序或中序遍历,则子树交换发生在遍历某棵子树之前,会引起麻烦。因此我想到了后序遍历,在遍历完子树后再交换左右孩子,重心就是如何实现常数空间复杂度的后序遍历。某些资料/问题称之为Morris post-order traversal。
jq实现原理——字节码
jq所用的DSL是一门dataflow
language,程序中编写的几乎所有结构都是filter,函数(比如def foo(f) f;
)接受filter为参数,产生filter。jq程序描述了如何把各个filter组合起来产生更复杂的filter,在执行时把输入数据(若干JSON)变换得到输出(若干JSON)。
jq独特的地方在于它的控制结构是由if和backtracking实现的。由于变量赋值后不可修改,因此迭代无法通过跳转和可变状态实现。
jq把程序编译成字节码后解释执行。字节码是栈式的(参看后缀表达式计算器、Forth),处理的值是JSON,执行时当前结果和临时变量等都存放在data
stack上,并提供了很多指令用于处理data stack。下面用
持续更新中