4
28
2015
15

再见,莫名其妙的知乎!

没想到会这样决定不再在知乎上产生新内容。虽然网站体验做得很差劲,其实知乎里有些人还是很不错的。

做出此决定的原因是知乎新实行的「不透明的审查制度」。

我在一个回答下边做出了可能会令某些人心里产生不适的内容:

更讽刺的是提问者叫 @不求人666 233

提问者名为「不求人666」,却提出了一个非常容易找到答案的问题,所以我才那么说。你若是见到亲友手上拿着钱包,却翻箱倒框地寻找,也是会大笑的是吧?

但是知乎认为这是「不友善行为」。什么叫「不友善行为」呢,知乎关于此规范的定义如下:

轻蔑:贬低、轻视他人及其劳动成果。

对别人做出的搞笑行为大笑是贬低还是轻视呢?那如果有人提出一个很基础的问题,我叫他去好好再读一遍基础教程,他就觉得自己受到了轻视,就可以来借此限制我在知乎上的行为了?

诽谤:捏造、散布虚假事实,损害他人名誉。

难道这个叫「不求人666」的用户不叫「不求人666」?

嘲讽:以比喻、夸张、侮辱性的手法对他人或其行为进行揭露或描述,以此来激怒他人。

哪里有比喻和夸张呢?我笑点低也不行吗?小小地嘲笑一下算「侮辱性的手法」?

挑衅:以不友好的方式激怒他人,意图使对方对自己的言论作出回应,蓄意制造事端。

什么是「不友善行为」?知乎答:「就是不友好的回应」。

羞辱:贬低他人的能力、行为、生理或身份特征,让对方难堪。

有么?名字是用户自己起的。

谩骂:以不文明的语言对他人进行负面评价。

「讽刺」这个词不文明么?

歧视:针对他人的民族、种族、宗教、性取向、性别、年龄、地域、生理特征等身份或者归类的攻击。


威胁:许诺以不良的后果来迫使他人服从自己的意志。

我通过「申诉」询问知乎管理员我的评论违反了哪一条。结果是:

知乎:不友善内容是指经知乎内部确认的不友善内容

如果真违反了哪一条规范,你要扣什么东西就扣吧。可是你好歹也告诉我到底违反了啥呀?


有位民警在大街上看着一个人不顺眼,于是上前:「你违法了,我要拘留你。」

那人问:「我违反什么法了?」

民警:「根据《XXX 法》,以下行为违法:一、闯红灯;二、随地乱扔垃圾;三、打架斗殴;四、其它违法行为。哦,你违反了这里的第四点。跟我走吧!」


2015年6月11日更新:另见《哔~知乎,离开的Q&A》

Category: 未分类 | Tags: 知乎 中国特色
4
28
2015
2

为什么你不应该安装12306的证书

中华人民共和国铁道部铁路客户服务中心在其首页上说:

为保障您顺畅购票,请下载安装根证书。

真的是这样吗?

安装该根证书意味着什么?

当然意味着你在12306网站上买票时不会遇到证书错误了。但是除此之外呢?

安装之后,你的计算机系统(或者浏览器)会信任该「CA 机构」所签名的所有证书。根据安装说明,该证书不仅能签名用于标识网站的身份的证书,还能签名应用程序,即 .exe 和 .dll 文件。

这意味着,如果铁道部没有按照规范正确管理该根证书对应的私钥的话,一旦被滥用,或者被攻击盗用,那么:

  1. 攻击者可以实施中间人攻击,伪装成支付宝、网上银行、微信、网页邮箱等网站,获取你的登录和隐私信息,篡改网页内容,以你的身份提交转账和订单、与你的亲友同事聊天等。

  2. 攻击者可以为病毒和木马签名。拥有一个受系统信任的签名,恶意软件更容易在用户不知不觉间潜入。

  3. 这是一个 SHA1 签名的证书。因为其安全性比较低,各大浏览器厂商将逐渐淘汰该类证书

  4. 当然还有一些其它的用法,毕竟这个证书的权限非常大

而铁道部能按照规范正确管理该根证书对应的私钥吗?很多人连工信部(CNNIC)的根证书都不信任呢。而工信部,即使出现过下级机构违规使用证书以至于 Google 和 Mozilla 都不再信任之,至少工信部曾经得到过各操作系统和浏览器厂商的信任,不管做没做到,人家至少知道应该怎么做。而铁道部呢?根本不是干这行的,也从未在这方面做过多少努力,连正规的 HTTPS 都不知道用,你觉得如何呢?

那要怎么用12306呢?

火狐有个功能,叫「添加证书例外」。在遇到不被信任的网站证书的时候,如果你确知你没有被骗,你可以为该网站添加例外,如图所示:

为 12306 添加证书例外

添加例外之后,火狐将这个证书这个网站关联起来。也就是说,如果12306突然换证书了,你会得到错误消息;如果别的网站也使用铁道部签名的证书,你也会得到错误消息。而这些错误消息,绝大部分是在告诉你有人正在进行中间人攻击。

HTTPS 保证了端到端的数据安全性(私密性、完整性),使得你即使在公共场合上网,或者本地网络有不可信的人时也可以安心上网。请不要随意破坏这份安全。

其它链接

4
26
2015
4

鸢尾花

(点击看大图)

鸢尾 1鸢尾 2

鸢尾 3

好多年了,竟然在现实生活中见到了这么多鸢尾花。

多年前,外婆家种了那么一盆鸢尾,不过从来没有开过花。后来经历一场事故之后,那盆鸢尾和三七(问过 Google,很可能是「景天三七」)一起拿到了我家。有株三七还开过一次花,很小的五瓣尖角白花,中间还有好看的花蕊。但是鸢尾,始终不曾开过花,应该是没人照料的缘故。

后来,我去上大学了。某年四月,才得知那盆鸢尾竟然在我不在的时候悄然开花了。花很漂亮,但是五一假期回家的时候,父母刚搬过家,鸢尾已经被毫无同情心的父亲抛弃了。于是,虽然没有费心去养,可也在那么久了,而在它最美丽的时候,我却不在。只能面对130万像素的手机摄像头拍摄出来不清晰还偏色严重的照片失望。

没想到又过了好几年,竟然无意间发现了它们。只能说声好久不见了。

Category: 未分类 | Tags:
4
26
2015
2

发布两个编译好的 Haskell 程序(Arch Linux 64 位版本)

Haskell 程序一向编译起来费力,得先下个巨大的 GHC,然后从 Hackage 上下一堆包然后慢慢编译。所以我在这里把自己用的程序放出来。Arch Linux 的 Haskell 程序打包太复杂了,所以不打包了。连二进制包也懒得打。

这两个程序是 shellcheckcgrep

shellcheck 是一个 bash / POSIX sh 脚本 lint 工具。就是指出程序源码中可能出错的地方,相当于 jshint 之于 JavaScript、pylint 之于 Python(但是不含风格检查)、gcc / clang 的警告之于 C。

cgrep 就是 context-aware grep,比如搜索注释或者字符串里的东西之类的。支持解析几种编程语言。

程序是在 Arch Linux 上编译的,但其它 Linux 也许也可以使用。

下载地址:shellcheck-0.3.7.xz, cgrep-6.4.12.xz.

>>> sha1sum cgrep-6.4.12.xz shellcheck-0.3.7.xz
0588ee29a1a17c1cddc816a8193d8494db7c03cf  cgrep-6.4.12.xz
376b58d485603a7622f83f095a30bddc1da34376  shellcheck-0.3.7.xz
Category: Haskell | Tags: Haskell 下载
4
15
2015
0

在 Python 里 disconnect UDP 套接字

UDP 套接字是可以使用 connect 系统调用连接到指定的地址的。从此以后,这个套接字只会接收来自这个地址的数据,而且可以使用 send 系统调用直接发数据而不用指定地址。可以再次调用 connect 来连接到别的地方。但是在 Python 里,一旦调用 connect 之后,就再也回不到最初的能够接收从任意地址来的数据的状态了!

这是 Python 的 API 限制,没办法给 connect 方法传递到 AF_UNSPEC 地址簇(在 C 代码里写死了的)。C 里边就可以做到的(代码来自这里):

int disconnect_udp_sock(int fd) {
 struct sockaddr_in sin;        

 memset((char *)&sin, 0, sizeof(sin));
 sin.sin_family = AF_UNSPEC;
 return (connect(fd, (struct sockaddr *)&sin, sizeof(sin)));
}

不过既然是 Python 的限制,拿 ctypes 就可以绕过了嘛,有些麻烦就是了:

from ctypes import CDLL, create_string_buffer

def disconnect(sock):
  libc = CDLL("libc.so.6")
  buf = create_string_buffer(16) # sizeof struct sockaddr_in
  libc.connect(sock.fileno(), buf, 16)

AF_UNSPEC 的值是 0,所以把一个和 struct sockaddr_in 一样长的全零缓冲区传给 connect 就可以了 :-)

Category: python | Tags: Python linux 网络
4
12
2015
13

遥远

不少我喜欢的技术都在我喜欢的公司里使用呢。只是,那里没有我。

Category: 未分类 | Tags:
4
7
2015
5

疯狂的 npm(图)

以前这服务器就经常被 OOM Killer 大开杀戒,各种服务都被杀害。虽然早就通过日志和其它信息知道是 npm 惹的祸,今天才有幸看到如此疯狂的 npm(点击查看大图):

crazy npm htop screenshot

说明一下,此 npm install 是正在安装 gulp 相关的东西。在本地跑的时候倒是没发现 npm 有如此「牛力」,只是比较费时费内存而已,不知道在这服务器上是发了什么疯。

Category: Javascript | Tags: nodejs javascript npm
4
6
2015
10

GitHub 的一个小细节

这是偶然间发现的。在 GitHub 桌面版网页上,按第一下 Tab 时,会在左上角显示一个「Skip to content」的链接,并且键盘焦点就在这里:

GitHub "Skip to content"

我被这样的小小地惊艳了一下。这个链接可以用来跳过不怎么常用的导航栏上那排链接和按钮。

作为经常打字聊天和写码的人,在电脑前的大部分时间手当然是在键盘而不是鼠标上,所以使用鼠标来进行一些操作很常见。虽然我有 keynavVimFx 来辅助,但是见到 GitHub 这么贴心的细节还是挺喜欢的。

这让我想起了国内的网址,大部分都根本不考虑 accessibility。比如问答社交网站知乎。我早已不「逛」知乎了,只是收到感兴趣的邀请时去看看。因为知乎的体验实在是太差劲了。

知乎取消了所有链接在获取焦点时周围的虚线。这意味着根本没办法使用键盘导航,因为你不知道当然焦点在哪里。

知乎的提交按钮完全无法使用键盘操作。看看 GitHub,写好评论什么的,按一下 Tab 焦点就去了提交按钮上,并且有非常明显的反馈。按空格或者回车就可以提交。如果决定放弃,再按一下 Tab 就好。这两个按钮的顺序是按使用频率而不是相对位置来获取焦点的,因为提交显然比放弃用得更多。Twitter 发送新消息、Google+ 评论的提交按钮也是这样。不过 Twitter 偶尔会需要按两次 Tab 才能提交,大概是改页面的时候不小心给改坏了,过段时间会修好。Google+ 分享新信息时会比较讨厌,因为要跳过好大一堆「添加照片」什么的按钮。

类似的 accessibility 处理,国外著名网站上经常能看到很好的实践,博客上经常能看到大家在关心「少数用户」的使用便捷性。而国内很少有关注这方面的,大家都跟乔布斯一样想,「不管合不合理,我是这么设计的所以你应该这么用」。

比如验证码。不管需不需要,都是字符图。这样盲人就用不了。而国外广泛使用的 Google reCAPTCHA 就可以选择通过声音收听验证码。当然是英语的。反正这全球最大的网站之一已经消失在中国大陆人的视野之中了。我知道专门有人建立了一个 QQ 群,视力正常的人帮助盲人识别验证码用的。

这大概是发达国家与发展中国家的侧面写照的缩影了吧。

最后扔一堆链接:

Category: 用户体验 | Tags: GitHub 知乎 UX Web
4
4
2015
15

一次面试结果的反思

很久以前的事情了。现在终于不再感觉到那么累了,想写,所以才写。权当日记吧,就懒得加各种链接和排版了。

这次的面试目标是百度运维工程师。

问题:为什么 Arch Linux 中文社区源的自动打包服务是自己弄的,而不使用现成的 CI 呢?

其实原因很简单:没想到。因为 lilac 自动打包脚本是由功能更简单、自动化程序也更低的脚本进化而来的,比如 nvchecker 更新、曾经自己用过的一些辅助脚本等。

当然,即使想到了,我也不会去用的,因为需要定制的东西太多。更新检查、依赖处理、错误回报、git 仓库管理什么的。传统的 CI 不像是天生支持这些的。最接近的 OBS 大家也知道,对 Arch 的支持很差。当然我可以进行二次开发,但工作量会很大、耗时会很长,因为那是我需要从头读文档、学习、尝试的一套系统,而对于 Linux 编程、Python 编程,我已经非常熟悉了。至于可重用性?首先我要解决它的可用性,东西都做不出来了,何谈可重用性呢?

当然 CI 系统对资源的消耗也不能忽视。

这个问题挺意外的,面试的时候没想这么清楚,没答到重点。

问题:为取得网站的高可用性,防止单个服务器挂掉影响整个服务,要怎么办呢?

我的回答是通过 DNS 和 anycast fallback。哪个服务器挂掉了就不用哪个了。DNS 的更新有些慢,在 DNS 应答中返回多个 IP 地址用处不大,大部分客户端都只会尝试第一个,我见过的只有 wget 会锲而不舍地穷尽一切方案去努力。Anycast 反应会更及时一些,CloudFlare 就喜欢用这个。

但是标答是 LVS。好吧这个词我没研究过。回来上网去看了一下,Linux Virtual Server,就是在前端放个负载均衡啦。我没有想到这个。今天我终于想到我为什么没有想到这个了——LVS 还是一台服务器嘛,只是逻辑上的服务器。作为一名程序员和数学爱好者而不是电器维修工,我对各种物理上的东西没什么深刻印象,反而对各种抽象的概念情有独钟。所以我自然而然地把「单个服务器」理解成单个逻辑上的服务器了,而不是或大或小的铁盒子。也就是说,我的理解是,当这个 LVS 系统挂掉了要怎么办。

我再一次把面试官想得到的答案当成了理所当然……

问题:正在进行通讯的两台主机之间的「网线」断了,一方再发送数据,这时会发生什么?

这个问题也很不明确,存在多种可能。

最简单的,直接连接发送方的网线断掉了。内核会收到硬件传回的信息,「carrier lost」,然后相应的路由表项被删除。就跟把相应的网络设备 down 掉一样。什么都不会发生,连重试都没有。应用程序就在那儿等着。

如果是位于局域网中,情形也差不多。只是会进行 TCP 重试,然后 ARP 广播「找人」。

互联网上的话,如果还有其它线路可用,数据包会走其它线路。如果所有线程都不通了,应该会返回 ICMP 主机不可达或者网络不可达。不知道这种情况下 TCP 和应用程序会发生什么。没条件实验。学校网络课实验自然不可能搞这么「高端」的东西。

当然,这么些可能我当时也没想全。

我发现我面试的时候思考能力变得很差的样子。其实凡是被人关注的时候都会发挥失常,虽然没有严重到别人盯着就写不出代码来。这也是我在社交活动常不满意的原因吧。

 

Category: 未分类 | Tags:
3
4
2015
7

Awesome 的 GitHub 今日贡献指示器:今天你 push 了吗?

GitHub 用户页有个 calendar,花花绿绿的甚是好看。不过,经常一不小心断掉了几十天的 steak 着实可惜,特别是用了私有仓库之后,自己看,有贡献,可别人看不到那些私有贡献的呀。其实要维持 steak 也不难,一个小小的提交就足够了——只要我知道我今天还没 push 什么公开的东西的时候。

当然啦,写个脚本天天推个无意义的更新挺容易的,但那样就没有乐趣了不是吗?一天快结束的时候发封邮件提示一下自己不错,但可能已经来不及了。而且这种事情还是随意点好,太刻意了就不好玩了,所以不需要那么强的提醒。弄一个简单的指示器在 Awesome 面板上正好。

效果图(指示器在右上角):

GitHub 今日贡献指示器的 Awesome 桌面

如果这天没有贡献(公开的提交或者 issue 等),那么这只 Octocat 就会失去色彩(变成灰度图)。

代码已上传至 myawesomerc 仓库。以下是实现细节:

首先,创建一个显示图片的 widget:

-- {{{ GitHub contribution indicator
github_contributed = awful.util.getdir("config") .. "/image/github_contributed.png"
github_not_contributed = awful.util.getdir("config") .. "/image/github_not_contributed.png"
github_widget = wibox.widget.imagebox()
function update_github(has_contributions)
    if has_contributions then
        github_widget:set_image(github_contributed)
    else
        github_widget:set_image(github_not_contributed)
    end
end
update_github(false)
-- }}}

-- 在 wibox 中添加这个 widget,需要放到正确的地方:
right_layout:add(github_widget)

函数update_github是给外部脚本用的。不可在 Awesome 配置里直接发起 HTTP 请求,会阻塞的!

当然,还要准备前两行代码提到的图片。从这里下载 Octocat 的图片,并做成彩色和灰度小图:

convert -resize 48x48 -background white -alpha remove Octocat.png github_contributed.png
convert -resize 48x48 -background white -alpha remove -colorspace Gray Octocat.png github_not_contributed.png

把图片放到相应的地方。然后写个脚本来更新这个指示器的状态,也就是获取数据之后再通过 awesome-client 调用update_github函数了。

#!/bin/bash -e

github_contributed () {
  count=$(curl -sS "https://github.com/users/$USER/contributions" | grep -oP '(?<=data-count=")\d+' | tail -1)
  [[ $count -gt 0 ]]
}

get_display () {
  if [[ -n "$DISPLAY" ]]; then
    return
  fi

  pid=$(pgrep -U$UID -x awesome)
  if [[ -z "$pid" ]]; then
    echo >&2 "awesome not running?"
    exit 1
  fi

  display=$(tr '\0' '\n' < /proc/"$pid"/environ | grep -oP '(?<=^DISPLAY=).+')
  if [[ -z "$display" ]]; then
    echo >&2 "can't get DISPLAY of awesome (pid $pid)"
    exit 2
  fi

  export DISPLAY=$display
}

get_display

if github_contributed; then
  s='true'
else
  s='false'
fi

echo "update_github($s)" | awesome-client

GitHub calender 目前是个 SVG 图片,位于https://github.com/users/用户名/contributions

awesome-client 需要设置正确的DISPLAY环境变量才可以使用。这里使用pgrep取当前用户的 awesome 进程里的DISPLAY变量值。ps命令不太好用,不能同时指定多个条件。

万事俱备,只需要拿 cron 或者 systemd.timer 定时跑跑这个脚本就可以啦~


2015年3月14日更新:update_github脚本改用 Python 实现了,更好的错误处理(不会因为网络问题而认为今天没有贡献了),也改用当前日期而非 GitHub calender 的最后一个方块。更新后的脚本在 GitHub 上

Category: Linux | Tags: shell awesome github

部分静态文件存储由又拍云存储提供。 | Theme: Aeros 2.0 by TheBuckmaker.com