绘制豆瓣用户增长曲线

我一直天真地以为豆瓣用户主页的URL是由唯一 username 确定用户的。后来发现有些用户主页的URL里出现的是用户ID。怀着好奇,我测试了一下,发现如下信息:

  1. 豆瓣的用户ID是从 1000001 开始的(鸡贼的阿北)
  2. 第一号用户是阿北(https://www.douban.com/people/1000001/)
  3. 第二号用户是苏丝黄(不认识,难道是阿北的老婆?)
  4. 通过二分法,确定豆瓣的最大用户ID是147674899(还在不停增长中)。也就是说豆瓣注册用户已经达到了1亿4千6百万(147674899-1000000)?
  5. 如果有兴趣,想要获取豆瓣每天的实际注册人数也是很简单的事情

对于一个商业网站,用户数量和订单数量等信息都属于商业敏感数据,不应暴露在外部,否则会导致『德国坦克』问题(二战时期,德国坦克的零件刻有编号,这个编号严格按照自然数自增长,盟军缴获德国坦克后,根据零件编号推算出德国人的坦克生产能力和坦克总数)。

……

PHP 和 Python 速查手册

方便 PHP 或 Python 开发人员快速入门另一门编程语言。

使用 Vagrant 作为开发环境

初始化虚拟机环境

下载 ubuntu-15.04-amd64.box 包文件。使用离线安装的方式:

shellvagrant box add ubuntu-15.04-amd64 file:///D:\downloads\ubuntu-15.04-amd64.box

其中 D:\downloads\ubuntu-15.04-amd64.box 是下载后的 box 文件路径。

切换到项目路径下,初始化并启动 Vagrant:

shellmkdir ~/project/devstack
cd ~/project/devstack
vagrant init ubuntu-15.04-amd64

启动并登录虚拟机系统

shellvagrant up
vagrant ssh

安装软件

更新 apt 软件库:

shellsudo apt-get update -y
sudo apt-get upgrade -y

安装需要的软件包:

shellsudo apt-get install -y git ansible libmysqld-dev mysql-server mongodb-server redis-server nginx-full supervisor uwsgi uwsgi-plugin-python python-pip python-dev python-virtualenv python-mysqldb python-mongoengine python-redis python-gevent virtualenvwrapper php5 php5-fpm php5-dev libjpeg-dev

安装第三方软件:

shellsudo dpkg -i /vagrant/elasticsearch-2.0.0.deb
sudo dpkg -i /vagrant/logstash_2.0.0-1_all.deb

禁用无用的服务:

……

HTML Entities 转换问题

用 Python 给富文本编辑器的后端做一个 HTMLPurifier 组件。各种 XSS 技巧都筛了一遍。觉得万无一失了,没想到还是栽在了坑里。

HTMLPurifier 组件使用 Python HTMLParser 来实现。HTMLParser 在处理 HTML Entities 的时候和主流的浏览器不一致。主流浏览器(FireFox、Chrome、IE)都允许省略HTML Entities末尾的分号。而 HTMLParser 的unescape 函数在处理时要求必须有结尾分号,导致后端的 HTML 过滤被绕过。

……

苏宁易购代码泄漏事件的时间线

事件导火索是9月25日,在 V2EX 上有人发了一个帖子:《github 上 fork 了一个项目,有人发 PR 让我删掉,我该怎么办?》 地址:https://v2ex.com/t/223610 (同时,有人在Ruby China上发了类似的帖子,但是我并没有看到,据说已经被删除了)

该楼主说有人给他发Pull Request,要求他删除一份fork的代码。发起这个PR的 github 用户叫“ChuPeng”。 项目的原始地址是:https://github.com/gdby/NewEBuy (已被删除),代码上传时间应该是去年的12月份。 从这位名叫 gdby 的 github 用户的项目列表里可以发现,该用户并非原始代码的上传者,而是网上泄漏代码的收集者。

……

    闲游复兴岛公园

    复兴岛在杨浦区东南部,黄浦江下游,距吴淞口6公里。南起定海路桥,北近虬江口,呈月牙形,长3.42公里,中部最宽处550米。目前岛上主要分布着一些中央部属、市属企业和部队单位,也有少量居民。

    该岛原为黄浦江中一处浅滩,其东为黄浦江主航道,西为运河浅水航道。清光绪三十二年已成雏形,1915、1916年在浅滩东侧抛石筑堤,滩面淤高。1925年,在南段三角形区段再抛石围筑土堤,充以泥土,1926年7月填成陆地。1928~1930年在中段再填充泥土,1930~1934年北段填泥、围埝,终成新岛。上海浚浦局在该岛兴建体育会,供员工日常娱乐、锻炼之用。

    ……

    一个语言的诞生(Act IV)

    第四幕 虚拟机指令设计

    常见的两种物理处理器指令架构有:复杂指令集(CISC)、简单指令集(RISC)。前者的代表是 Intel x86 处理器,后者的代表有 MIPS、SPARC 和 ARM。

    CISC 指令集的指令长度不等,多种寻址方式

    一个语言的诞生(Act III)

    第三幕 垃圾回收

    看过微软 .net coreclr 的源代码后,觉得 Lua、PHP 和 Python 的垃圾回收代码与之相比简直就是个玩具。而 Hotspot JVM 的垃圾回收算法更加复杂。

    常见的垃圾回收技术能大致分成:引用计数、标记清理、标记缩并和节点复制几种。高级的技术有垃圾分代收集、渐进及并发收集、分布式垃圾收集。复杂的垃圾回收算法会根据对象的性质和内存的使用情况来选择不同的垃圾回收算法。

    ……

    一个语言的诞生(Act II)

    第二幕 对象内存布局

    那些不怎么“动态”的语言,比如C#和JAVA,一般都会把数据类型分成“值”和“引用”,值类型是分配在栈上的,引用类型是分配在堆上。而“动态”的语言,比如“PHP”和“Python”所有的数据都是动态分配在堆上的。这么做的缺点一是浪费内存,二是访问慢。浪费内存是因为PHP和Python的对象都经过重度的封装,一个简单的整型经过封装后的大小是原来的4、5倍。访问慢的原因是每次创建一个对象都要申请一次内存,而且访问对象必须通过指针,这样一搞CPU的1、2级缓存根本就没有用了嘛。

    ……

    一个语言的诞生(Act I)

    第一幕 哈希表

    哈希表是动态脚本语言的基石。动态语言中,全局变量表、全局字符串表、对象虚函数表、元数据表皆为哈希表。欲实现语言,则必先实现哈希表。

    哈希表原理很简单,不再赘述。不同语言实现的哈希表主要区别在于处理碰撞的机制不同。一种叫“Separate chaining”,PHP的哈希表使用了这种方式;另一种叫“Open addressing”,Lua的哈希表使用的是这种。前者发生碰撞会创建一个新的bucket,然后用链表将所有碰撞的bucket链接起来;而后者在现有的buckets中找到一个空的bucket来存放发生碰撞的key-value pair。我选择的是后一种方式,一方面是节约内存,另一方面还能节省GC开销。

    ……