心得
今天看了下 github/awsome-go ,发现以前真的是死心眼,凡事自己死磕,而不是去看看网上成熟的解决方案。
现在有很多 awsome-xxxx 在效率优先的情况下,没必要去死磕,重复造轮子啊。
ImportError: No module named xxxxx
1 | py_module = __import__(name = module_file_path) |
在需要导入的模组的文件里加入空的 __init__.py
就好了
tornado.queuetornado.queue
tornado.queue
为了协程实现了异步生产者/消费者模式,和Python自带的queue为线程而实现的一样。Queue.get
会有一个协程专门等到队列中有数据。如果队列满了,会有专门的协程等待Queue.put
争取到空间。Queue
维护了一定数量的未完成的任务,数量从0开始,put
会增加数量,task_done
会减少数量。
tornado web应用的结构
Tornado web应用是由多个 RequestHandler
子类,一个用于将进来的请求路由到对应的处理的 Application
, 一个用来启动的 main()
组成的
setproctitle
修改进程名用的
struct
和lua类似的字节流封装
头字符:表示字节顺序,大小和对齐方式
字符 | 字节顺序 | 大小 | 对齐方式 |
---|---|---|---|
@ | 按原字节 | 按原字节 | 按原字节 |
= | 按原字节 | 标准 | 无 |
< | 小端 | 标准 | 无 |
> | 大端 | 标准 | 无 |
! | 网络(=大端) | 标准 | 无 |
格式字符
格式 | C 类型 | Python 类型 | 标准大小 | 注释 |
---|---|---|---|---|
x | 填充字节 | 无 | ||
c | char | string of length 1 | 1 | |
b | signed char | 整数 | 1 | (3) |
B | unsigned char | 整数 | 1 | (3) |
? | _Bool | bool | 1 | (1) |
h | short | 整数 | 2 | (3) |
H | unsigned short | 整数 | 2 | (3) |
i | int | 整数 | 4 | (3) |
I | unsigned int | 整数 | 4 | (3) |
l | long | 整数 | 4 | (3) |
L | unsigned long | 整数 | 4 | (3) |
q | long long | 整数 | 8 | (2), (3) |
Q | unsigned long long | 整数 | 8 | (2), (3) |
f | float | 浮点数 | 4 | (4) |
d | double | 浮点数 | 8 | (4) |
s | char[] | string | ||
p | char[] | string | ||
P | void * | 整数 | (5), (3) |
- ‘?’ 转换码对应于 C99 定义的 _Bool 类型。 如果此类型不可用,则使用 char 来模拟。 在标准模式下,它总是以一个字节表示。
2.6 新版功能.
- ‘q’ 和 ‘Q’ 只有在本地C编译器指出C long long类型行,或者在Windows上支持 __int64的时候才有效。在标准模式下一般都能用。
2.2 新版功能.
- 在使用任何整形转码的来包装非整形的时候,如果这个非整形有
__index__()
方法,那么在包装之前会调用此方法来转换参数。 如果没有__index__()
方法,或者调用__index__()
发生了 TypeError 错误, 那么就会尝试__int__()
。虽然__int__()
已经废弃,且会抛出 DeprecationWarning。
在 2.7 版更改: 2.7中非整数据的
__index__()
全新使用方法。
在 2.7 版更改: 在 2.7 版本中, 并不是所有的整形转换都使用
__int__()
方法, DeprecationWarning 只会在 float 转换的时候抛出。
- 对于 ‘f’ 和 ‘d’ 格式字符, 封包形式用的是
IEEE 754 binary32 ('f')
或者binary64 ('d')
格式, 与平台使用的浮点格式无关。
- ‘P’ 格式字符仅对本机字节顺序可用(选择为默认或使用 ‘@’ 字节顺序字符)。 字节顺序字符 ‘=’ 选择使用基于主机系统的小端或大端排序。 struct 模块不会将其解读为本机排序,因此 ‘P’ 格式将不可用。
格式字符之前可以带有整数重复计数。 例如,格式字符串 ‘4h’ 的含义与 ‘hhhh’ 完全相同。
格式之间的空白字符会被忽略;但是计数及其格式字符中不可有空白字符。
对于 ‘?’ 格式字符,返回值为 True 或 False。 在打包时将会使用参数对象的逻辑值。 以本机或标准 bool 类型表示的 0 或 1 将被打包,任何非零值在解包时将为 True。
对于 ‘s’ 格式字符, 个数会解释为字符串的尺寸, 不想其他格式字符一样转换为重复次数; 例如, ‘10s’ 表示的是一个简单的 10-字节字符串, 但是 ‘10c’ 指的是 10 字符。如果没有指定个数的话,默认就是1。为了便于封包,字符串会被截断或者用空字节来填充来适配。对于解包,还是会根据指定的字节数完美的解出字符串。作为特里,’0s’ 意味着一个单个的空的字符串(而 ‘0c’ 代表 0 个字符).
对于’p’ 格式字符对一个 “Pascal string” 编码, 意味着一个短的可变长度的字符串存储在一段指定长度的字节中。第一个字节存储的是字符串的长度,或者是255,无论如何都比255小。接下来的字节都是字符串的字节了。如果传入
pack()
的字符串太长 (比count - 1还要长), 那么只会存储字符串前面的 count-1 字节。如果字符串比 count-1 , 那么会用空字节来填充,这样一来就可以用精确的字节数。注意,对于unpack()
, ‘p’ 格式字符需要消费 count 字节,但是字符串永远都不要超过255个字符。
对于 ‘P’ 格式字符,返回值是一个 Python 整形或者长整形,这取决于在转换为整形之后返回的指针的需要的大小。 NULL 指针永远是返回 Python 整数 0。在封包指针大小的值的时候, 会用到 Python 整形或者长整形。例如: Alpha 和 Merced 处理器使用的是 64-bit 指针值,意味着会用一个 Python 长整型来持有这个指针; 其他平台使用的是 32-bit 指针,那么他会用 Python 整形。
Tornado
WebSocket的使用方式
1 | import tornado |
greenlet
轻量级协程,gevent 也是用的 greenlet
- 经常与线程 threads,或者Python内置的携程
async def
配合使用 - 多线程有并发性的问题,需要用 queue 或者 locks 来避免 race condition,deadlock 以及其他的问题。greenlet之间是有序协作的,同时只能有一个greenlet运行。可以完全控制greenlet的切换,从而解决了竞态条件问题。
- 线程需要申请系统资源,如线程栈,系统预留,而 greenlet 只需要很少的资源
greenlet().switch()
切换到这个调用 switch
的协程
Python 编码出错的问题
文件头里有
1 | #!/usr/bin/env python |
VS Code工具栏也显示的 UTF-8,那么看看控制台是否有乱码,有的话运行:chcp 65001
试试看
之前面试被问到过的MySQL引擎问题
collections库
1 | # Counter |
Counter({‘l’: 11, ‘o’: 7, ‘ ‘: 5, ‘e’: 4, ‘h’: 4, ‘d’: 3, ‘,’: 3, ‘r’: 3, ‘w’: 3})
[‘ ‘, ‘ ‘, ‘ ‘, ‘ ‘, ‘ ‘, ‘e’, ‘e’, ‘e’, ‘e’, ‘d’, ‘d’, ‘d’, ‘h’, ‘h’, ‘h’, ‘h’, ‘l’, ‘l’, ‘l’, ‘l’, ‘l’, ‘l’, ‘l’, ‘l’, ‘l’, ‘l’, ‘l’, ‘o’, ‘o’, ‘o’, ‘o’, ‘o’, ‘o’, ‘o’, ‘,’, ‘,’, ‘,’, ‘r’, ‘r’, ‘r’, ‘w’, ‘w’, ‘w’]
4
Counter({‘hello’: 3, ‘world’: 2})
1 | d = collections.defaultdict(int) |
defaultdict(<type ‘int’>, {‘a’: 2})
defaultdict(<type ‘list’>, {‘a’: [‘b’, ‘c’, ‘d’], ‘b’: [‘c’]})
1 | # OrderedDict:保留添加顺序 |
OrderedDict([(‘1’, 100), (‘3’, 3), (‘2’, 2), (‘10’, 10), (‘8’, 8)])
1 | # namedtuple(命名元组的构造器) |
<class ‘main.Person’>
Person(age=30, height=178, name=’Tom’)
30
1 | # deque 返回一个新的双向队列对象,支持线程安全,对于两端添加或者弹出,时间复杂度O(1) |
deque([], maxlen=6)
deque([‘p’, ‘y’, ‘t’, ‘h’, ‘o’, ‘n’], maxlen=6)
deque([‘y’, ‘t’, ‘h’, ‘o’, ‘n’, ‘he’], maxlen=6)
deque([‘ma’, ‘y’, ‘t’, ‘h’, ‘o’, ‘n’], maxlen=6)
装饰器
1 | #!/usr/bin/env python |
Func Main
Wrap Layer1 begin
Func Main
Wrap Layer end
Wrap Layer1 begin
Hehe
Wrap Layer end
Java注解
标记注解
1 | //有点像定义一个接口一样,只不过它多了一个@ |
元数据注解
普通使用
定义
1 | public MyAnnotation { |
使用
1 |
|
默认值
定义
1 | public MyAnnotation { |
使用
1 |
|
注解为Value
定义
1 | public MyAnnotation2 { |
使用
1 |
|
- 来源: 注解就这么简单