Category Archives

12 Articles

Octave 与 MATLAB 不兼容性

GNU Octave 的目标就是制作一款类似 MATLAB 的开源数学软件,在它的 bug tracker 分类里就直接有一项: Matlab Compatibility ,维基百科里也说可以认为这就是一个“ Software Clone ”。然而事实上,通过在这学期的 Numerical Analysis 课程中使用 Octave 替代 MATLAB 的经历,发现两者不兼容的地方还是有很多的。总结起来就是,不要对 portability 抱有太大幻想,几乎所有大型 MATLAB 都需要人工修改才能 port 到 Octave 上。

Read More

Git 认证凭证管理

尽管使用 SSH 真是相当方便,但总有些时候不得不使用 HTTP/HTTPS 之类的 git 后端——时常是由于网络环境限制导致。这时每次输入用户名密码真是相当烦心。从 1.7.9 版本开始, git 提供了 credential helper 来消除这一烦恼,且现在在各个平台下都有相当合用的 helper :

Platform independent

git 自带了两个平台无关的 helper : cache 和 store ,前者在内存中缓存凭据(可以设置有效时间),后者将凭据明文储存在硬盘上,除非文件系统有启用加密,否则不推荐使用。简单提一下前者的使用方式:

git config --global credential.helper cache
git config --global credential.helper "cache --timeout=3600"

以下平台相关的 helper 推荐使用 git 1.8.3 以上版本!

Read More

About Shadowsocks

我用 shadowsocks 很长时间了,最开始是从 V2EX 的这个帖子开始:发一个自用了一年多的翻墙工具 shadowsocks 。还记得那个时候这个小工具还只是一个900行左右的自用脚本,现在已经发展成功能齐备、拥有多种语言和平台 port 的社区项目、大家族了。虽然我认为它的发展在某种意义上偏离了一开始的理念——简单的架构,任何程序员都可以自己修改协议和加密部分,从而使得拦截变得困难——现在的 shadowsocks 毫无疑问已经形成了自己的一套协议,若要享受数量庞大的 ports ,自行修改协议变得不切实际了起来;然而更加丰富的功能、更稳定的程序、更快的速度也的确是为更广泛的群体提供了一个非常方便的工具。今天就简单说一下这么长时间以来的一些使用经验,以及其他一些废话。

Read More

MySQL 的大小写敏感问题

昨晚刚刚被一个课程大作业坑了,特地写一篇博客来记录一下。提问: MySQL 是大小写敏感的么(包括关键字和标识符)?刚上过数据库系统原理课的好学生们一定会记得这句话:“ SQL 是大小写不敏感的”。而有过一些实际开发经验的人可能会说:“表名是大小写敏感的,其他不是。”很遗憾,两个答案都是错的。

Short version: it is implementation dependent.

对于 MySQL 来说,所有的关键字都遵循 SQL 标准,大小写不敏感,而表名是否敏感则依赖于一个叫做 lower_case_table_names 的设置项,它的默认值根据操作系统而不同,具体如下(文档):

  • Windows: 该值默认为1,表名在存储、查找过程中都被转化为小写,因而是完全大小写不敏感的。这与 Windows 的文件系统有关,事实上,你无法在一个大小写无关的文件系统上强制 MySQL 大小写敏感。
  • *nix: 该值默认为0,表名在存储、查找过程都严格遵照给定的大小写,即是完全敏感的。
  • Mac OSX: 该值默认为2,表名在存储时保留大小写,但在比对时全部转化为小写。这和 Mac OSX 的文件系统惯例一致。

所以,当我昨晚从(使用 Windows 的)队友手中接过一个数据库操作不在意大小写的代码时,虽然浑身不舒服,但回想起课上说过的“ SQL 大小写不敏感”(虽然我从没有试过非关键字究竟是不是大小写敏感的),就也没多想。可一跑起来却全是数据库错误,愣是过了好一会才终于怀疑起大小写的问题来……

Arduino IDE 编译生成过程

最近因为一门实训课程的缘故接触了 Arduino 开发。由于有一定的 C++ 基础,所以还是很快上手了 Arduino 提供的开发环境,简单说来就是一个 C++ 工程,所谓的“Sketch”(.ino文件)其实就是 C++ 源代码。然而其中有一点令我很困惑,并最终导致了问题的产生: Arduino IDE 是如何处理源代码中的头文件引用并最终链接整个程序的?

这个问题听上去根本不是问题:不就是和一般的 C++ 一样使用 #include 预编译指令么?顶多最终链接的时候 IDE 做一些自动处理,把用到的模块都链接起来。但如果你用过 Arduino 的 library ,你就会发现它的使用方法不符合 C++ 的规则:库是存放在 library 目录下的一个个子文件夹中的,而使用的时候却是直接 #include 某个头文件,没有指明库文件夹的名字( C++ 的头文件引用是不会递归搜索的)。

Read More

Content Security Policy 导致 bookmarklet 失效

近来发现在知乎、 Github 上我最常用的 bookmarklet (书签小工具,就是那种一句话 Javascript 书签)——饭否分享失效了。打开 Console 一看,有这样的提示:“Content Security Policy: 页面设置阻止读取一项资源:已经阻止执行内联脚本。”大概是孤陋寡闻,之前还没听说过 Content Security Policy 这玩意儿,猜测又是和 Cross-Origin Resource Sharing 有关系的什么东西,就做了一番搜索。

CSP 是一个可以限制页面中哪些 src (包括脚本、图片等等)可以被允许的实验性 HTTP Header 。这是 W3C Candidate Recommendation ,而这个是 MDN 上的相关资料。简而言之又是一个 defend by depth 的产物,可以给 XSS 防范再加上一层保险:直接禁止掉 inline script 和 inline eval ,然后给出一个允许加载的资源域的白名单,这样即使有 XSS 过滤漏洞,也无法注入站外的脚本。

但是问题就来了:用户直接在地址栏里输入的 Javascript 应该被允许么? Bookmarklet 应该被允许么? W3 文档这么说:

Enforcing a CSP policy should not interfere with the operation of user-supplied scripts such as third-party user-agent add-ons and JavaScript bookmarklets.

可事实是 Firefox ( Chrome 估计也是)没有正确实现,把 bookmarklet 也给拦截了,同时拦截掉了的还有 Lastpass 这样的插件的 JS 脚本,这也顺便解释了为什么 Lastpass 在知乎首页上无法自动填充的问题。

Github 博客上介绍这个新措施的文章里也提到了这个问题,并且给出了一个“解决方案”——直接把浏览器的 CSP 支持给禁用就好了……

我们是否需要使用框架?

几乎所有领域的编程中,都有“框架”(framework)的出现,在编程语言之上提供了又一层的抽象,实现了一些基础设施,来辅助某些开发过程。就算不是程序员,只要经常安装软件的有心人都会注意到一个叫做 .Net Framework 的重量级框架。现在估计有一半的常用 Windows 软件使用了 .Net 框架,的确大大方便了桌面软件的开发。可能是因为它的确太有用,简化了很多原来很麻烦、不优雅的工作,并且本身体量较大,不容易实现,鲜见有人重复发明轮子。但 Web 领域就不一样了,不管是前端还是后端,都有多如牛毛的各式框架供选,并且还不断有人不满意已有的框架而自己从头来过,甚至最后剥离出一个新框架。也不断有人质疑, Web (或其中某一个方面)这样“简单”的事情,需要用上框架么?或者,需要用上现成的框架么?

Read More

正确处理下载文件时HTTP头的编码问题(Content-Disposition)

最近在做项目时遇到了一个 case :需要实现一个强制下载功能(即强制弹出下载对话框,阻止浏览器尝试解析显示某些文件格式),并且文件名必须保持和用户之前上传时相同(可能包含非 ASCII 字符)。

前一个需求很容易实现:使用 HTTP Header 的 Content-Disposition: attachment 即可,还可以配合 Content-Type: application/octet-stream 来确保万无一失。而后一个需求就比较蛋疼了,牵扯到 Header 的编码问题(文件名是作为 filename 参数放在 Content-Disposition 里面的)。众所周知, HTTP Header 中的 Content-Type 可以指定内容(body)的编码,可 Header 本身的编码又该如何制定?甚至, Header 究竟是否允许非 ASCII 编码呢?

如果放任编码问题不管,那么你一定会遇到在某个系统及浏览器下下载文件时文件名乱码的情况;如果你尝试搜索解决,那么你很可能会找到一堆自相矛盾的解决方案(我可以负责任地告诉你,其中的99%都是不符合标准的 trick 罢了)。让我们来看看到底应该如何优雅完美地解决这个问题吧!

Read More

PHP中对象的引用

最近开始比较系统地学习 PHP (以阅读 PHP 官方手册为主),因此将会不定期地写一些学习笔记。水平有限,如有错误请指正。

说到 PHP 的对象,总有一句话:“ PHP 当中对象是按引用传递的,即每个包含对象的变量都持有对象的引用(reference),而不是整个对象的拷贝”。然而这里的“引用”并不是 C++ 程序员所习惯的“引用”——严格来说, PHP 的“对象的引用”其实是对象的标识符的一个拷贝

Read More