踩坑记——覆写Python中的__cmp__


最近做一个简单的排行榜功能时,不小心踩到一个Python语言上的坑,花费掉我不少时间才找出具体原因,值得记录一下。


具体功能需求是这样的,制作一个500人的积分排行榜(TOP 500),每个人的积分只增不减,分数相同时比较上榜的时间戳,先达到积分的用户排名靠前。

这种排行榜之前已经做过无数个,一般的,会先抽象出一个TopItem对象,保存用户的积分,以及姓名、UUID等相关信息。然后用一个list对象tops保存有序的500元素,并用一个dict对象cache保存一个uuid到TopItem的映射。由于Python对象的引用特性,多增加一个dict对象,并没有增加TopItem对象的副本,而是均指向同一个TopItem对象,所以内存方面也不会有什么太大的问题。

2017年上半年书单


非技术类

  • 长恨歌 王安忆
    • 一部上海百年画卷,从细节纹理描绘城市的巨变。王琦瑶的一生,和我们大多数人一样,有高光,但大部分时间是平淡和挣扎,个人的努力最终还是要屈服于历史的进程O-O

日本之行感悟


上周参加公司的旅行福利,去了一趟日本,主要行程是大阪-奈良-京都-东京。这是我第二次去日本了,上一次是去参加Tokyo Game Show(TGS),主要是在东京都内,而且自己活动的时间比较少。这次纯粹是旅行,看的更多,体会也更深一些。

探索skynet(四):服务之间的通信


《探索skynet(三):消息队列》中已经提到,skynet中每个服务都有自己的地址和消息队列。有了这个基础,理解服务之间的消息通信,就比较简单了。

skynet.call

以最常用到的skynet.call为例,它通过调用skynet.core.send(也即,lua-skynet.c中的lsend函数)–> skynet_send函数 –> skynet_context_push函数,向目标服务的消息队列中插入了一条消息。

Python内存管理模块的一个奇技淫巧


最近在读Python源码中有关内存管理的部分。Python在分配小块内存(小于256字节)时,采用了内存池,以降低对内核内存分配程序的调用频次。在内存池的设计上,采用了一个分层的设计,由上到下依次是arena、pool、block。这次我看到的这个比较费解的结构,就来自于分配内存时,对于pool的处理。

高房价在扼杀什么


这个周末,看到水木上一篇文章《被疏解了》,大意就是说一个三北博士(本科、硕士、博士都是北大的),毕业后进入中科院北京某研究所工作三年,还是由于房价太高以及子女教育问题,选择去南京了。

每隔一段时间,就会有这样的一篇热文,来控诉帝都的房价。本来我都习以为常了——一时逃离北上广,一时又逃回北上广,循环往复——但是正好最近目前住的小区里也发生了一件相关的小事,让我又有了一些新的感慨。

探索skynet(三):消息队列


skynet框架底层使用消息队列作为各个服务之间通信的工具,之前在探索skynet如何启动一个服务时也提到了创建skynet_context时会初始化一个队列,并且也笼统的提到了如何为一个服务设置callback。那么接下来就详细的看看,skynet里有关消息队列的部分是如何设计和实现的。

基础结构

skynet中有关消息队列的实现主要放在skynet_mq.c中。

skynet_mq.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
struct message_queue {
struct spinlock lock;
uint32_t handle;
int cap;
int head;
int tail;
int release;
int in_global;
int overload;
int overload_threshold;
struct skynet_message *queue;
struct message_queue *next;
};

struct global_queue {
struct message_queue *head;
struct message_queue *tail;
struct spinlock lock;
};

Python正则表达式之四:re模块


在这一篇文章里,我将总结一下Python中re模块的基本用法。

re

最最基本的用法就是re.search了,在前面的三篇文章中,我们也已经见过多次,这里就不再赘述了。

re.sub

使用正则表达式进行查找替换,正是re.sub的功能。

例如,下面这个例子,将格式化列与之间逗号的用法:

1
2
3
>>> row = "column 1,column 2, column 3"
>>> re.sub(r',\s*', ',', row)
'column 1,column 2,column 3'

下面这个例子更复杂一些,配合正则表达式中的捕获和引用特性,可以方便的转换日期格式:

1
2
3
>>> sentence = "from 12/22/1629 to 11/14/1643"
>>> re.sub(r'(\d{2})/(\d{2})/(\d{4})', r'\3-\1-\2', sentence)
'from 1629-12-22 to 1643-11-14'

re.split

一次泡脚引发的“命案”



最近闲了,晚上在家不时泡个脚,顺便捧起《寂静的春天》阅读几页,某天泡脚时发现书中知更鸟的英文是robin,得意地向Mr.Guo显摆了一番。
Mr.Guo反击说:”杀死一只知更鸟”
我:”啊?! 你说那本书吗?”
Mr.Guo:”是啊,我还没看过…后来还拍过电影”(Mr.Guo已经开始在网上搜索了)
我:”那我们先看书再看电影,好不好?”
Mr.Guo叫嚣道:”知更鸟是Mockingbird!”
我:”不是啊,这书上写的是robin!”(两人反复嚷嚷了2遍,感觉要打起来了)
Mr.Guo:”你看嘛,杀死一只知更鸟翻译的是To Kill a Mockingbird!”
我:”到底谁错了,去查大英辞典吧!”


若是点进来为了看热闹的童鞋,看到这里就可以毫不回头地走了,自封为学术帝的童鞋往下看是学术烧脑阶段。

Python正则表达式之三:贪婪


在这一篇文章里,我将总结一下正则表达式的贪婪/非贪婪特性。

贪婪

默认情况下,正则表达式将进行贪婪匹配。所谓“贪婪”,其实就是在多种长度的匹配字符串中,选择较长的那一个。例如,如下正则表达式本意是选出人物所说的话,但是却由于“贪婪”特性,出现了匹配不当:

1
2
3
>>> sentence = """You said "why?" and I say "I don't know"."""
>>> re.findall(r'"(.*)"', sentence)
['why?" and I say "I don\'t know']