一般地来说,一个值,或者说一个函数,是多态的,当它可以是多种类型的。Haskell原始支持的多态分为参数多态和 ad-hoc 多态。
在文章haskell学习笔记中提到了Parametric polymorphism、higher kinded polymorphism 和 higher rank polymorphism三个概念,我们将在本文中详细探讨。
曼谷/芭提雅游记
今年去泰国跨年(避寒)了,30号到4号,一共玩了五天。
stateful constexpr
通过 stateful constexpr,我们希望实现以下功能
1 | int main () { |
通过在编译器实现副作用,可以在编译期实现容器、查看某个类是否已经被实例化、查看一个函数在决议后的地址,甚至实现反射。
我们还能看到:
- 友元的一个有趣的应用
- Argument-dependent lookup
- C++ 模板实例化规则
MIT6.824做题笔记
MIT 6.824 2018的Lab。
通过C++预处理实现if
C++的预处理机制令人诟病的一点是在不同的编译器中的表现是不同的,在boost/preprocessor/config/config.hpp列举出了非常多的case,所以在本篇文章中我们只考虑g++-7的编译结果。此外,出于便于阅读的考虑,对名字进行了简化,去掉了诸如BOOST_PP
等前缀。
Python中join不能响应信号的问题
在文章subprocess模块用法中介绍了Python中的threading.Thread.join()
时不能响应信号的问题。这个问题被Python官方标记为Bug。
Python官方的Issue指出这个Bug与Python的signal、基础线程库thread(C实现)和高级线程库threading(Python封装)都有关,下面首先概览这三个模块的实现,接着通过编译调试的方式来观赏这个Bug的具体过程。
Redis底层对象实现原理分析
我将直接根据github上的unstable分支代码分析。主要是2018年7月版本(dict实现的大部分)的和2020年8月版本(其他部分)的,所以可能会有细微差别。因为Redis的代码比较好读,并且质量很高。这里还推荐《Redis设计与实现》一书,它介绍了Redis中部分比较有趣的设计思路,可惜还有些没有覆盖到,本文中对这些有趣的设计也进行了论述。
Redis中主要包含了字符串STRING、列表LIST(双向链表)、集合SET、哈希表HASH、有序集合ZSET五种最常见的类型。在后续的版本中,还提供了bitmap、geohash、hyperloglog、stream这四种类型。
这些对象依赖于一些内部结构,包括字符串(SDS)、哈希表(dict)、链表(list)、跳表(zskiplist)、压缩双向表(ziplist)、快表等。注意出于性能原因,一个对象的实现往往根据具体的内容而选择不同的实现。列举如下:
- STRING
使用int、sds(raw)或者embstr。
下面的类型也是使用STRING的存储的:- hyperloglog
- bitmap
- HASH
使用dict或者ziplist方案。 - LIST
3.0是使用list或者ziplist的方案。
目前使用快表。 - SET
使用dict或者intset的方案。 - ZSET
视数据规模选用ziplist和skiplist+dict的方案。
下面的类型也是使用ZSET的存储的:- GEOHASH
本文中不介绍的是,它们在系列的其他文章中讲解:
- Redis基础设施
- Redis Sentinel
- Redis Cluster
- Redis AOF/RDB
最后,本文的主体部分已经完成,但后续仍然会进行修订,或者补充。
subprocess模块用法
在Python中我们可以通过os.system
来以控制台的形式运行程序,但当涉及到需要进行进程间通信时,就需要用到subprocess模块。本文原来是和multiprocessing作为一个整体来介绍的,后来进行了拆分,但内容仍然会有所重叠,并且会涉及Python的线程和进程相关机制。
Python2字符编码
字符编码
我们通常见到的字符串编码主要是三种GB2312/GBK、Unicode、UTF-8。GB2312/GBK是多字节(multibytes)编码的一种,属于“ASCII的加强版”,与之平行的由Big5、ShiftJIS之类的编码各自为政,所有这些用两个字节表示汉字的多字节编码标准统称为ANSI编码,同样的汉字在不同的ASNI编码中的表示是不同的。为了避免这个问题,Unicode应运而生,将全世界所有的字符统一编码到一个定长的结构中。Unicode解决了统一编码的问题,但带来了新的问题。第一点,Unicode和ASCII不兼容了,这是因为ASCII只有一个字节,而这一个字节肯定装不下Unicode。第二点,用Unicode传输开销变大了,这是因为很多文档二十六个字母(1个字节)就能解决了,用Unicode多了很多冗余的字节。因此UTF-8应运而生。UTF-8对Unicode进行变长编码(我们可以想象下Huffman树),通常长度在1-4字节。目前Linux系统使用的是UTF-8编码,而Windows内部则是UTF-16LE/GBK编码。
Google Kickstart 2018 Round B题解
继续写第二轮