1 |
|
python回文数
1 |
|
1 |
|
1 |
|
1 |
|
CPython源码分析0001
面向对象
对象可以说是Python最核心的一个概念,在Python的世界里,一切都是对象。我们知道Python是由C编写的,C并不是一个面向对象语言,而由C编写的Python确实面向对象的,那么它的对象机制是如何实现的呢?
对于人的思维,对象是可以形象描述的,但是对于计算机而言,对象是一个抽象的概念,计算机所知道的一切都是字节。关于对象,通常的说法是,对象是数据以及基于这些数据的操作的集合,在计算机中,一个对象实际就是把一片被分配的内存空间,且这片内存在更高层次可作为一个整体,这个整体就是一个对象。
在Python中,对象就是C中的结构体在堆上申请的一块内存。
对象的基石
在Python中,所有的东西都是对象,而所有的对象都拥有一些相同的内容,Python中的这些内容都是在object.h中的Pyobject中定义的。
定长对象和变长对象
Python除了Pyobject对象之外,还有一个表示这类对象的结构体pyVarObject,pyVarobject其实就是对pyobject的一个扩展。
那么站在源码的角度上分析,变长对象是在pyVarobject中添加了可变长度数据的对象,也就是ob_size,定义了所容纳元素的个数。定长对象和变长对象的区别是:定长对象的不同对象占用的内存大小是一样的,变长对象的不同对象占用的内存可能是不一样的。比如整数对象’1’和’100’占用的内存大小都是sizeof(PyIntObject),而字符串对象”me”和”you”占用的内存大小就不一样。
多态
面向对象中一个重要的特性是多态,那么Python是如何实现多态的呢?
在Python创建一个对象时,会分配内存,进行初始化,然后Python内部会使用一个PyObject变量来保存和维护这个对象,Python中的所有对象均是如此。比如创建一个PyIntObject对象(整数对象),不是通过PyIntObject 变量来保存和维护这个对象,而是通过PyObject ,正因为所有对象均如此,所以Python内部各个函数之间传递的都是一种范型指针(Pyobject),而这个指针所指的对象究竟是什么类型的,我们是不知道的,只能从指针所指对象的ob_type域动态进行判断,而正是这个域,Python实现了多态。
垃圾回收
和C或C++不同,Python选择使用语言本身负责内存的管理和维护,也就是垃圾收集机制,代替程序员进行繁重的内存管理工作,而引用计数刚好是Python垃圾收集机制的一部分。
Python通过对一个对象的引用计数来管理和维护对象在内存中的存在与否。Python中的一切皆是对象,在所有的对象中有一个ob_refcent变量,维护这对象的引用计数,从而也决定该对象的创建与消亡。
在Python中,使用Py_INCREF(op)和Py_DECREF(op)两个宏来增加和减少一个对象的引用计数,在每一个对象创建的时候,Python提供了一个Py_NewReference(op)宏来将对象的引用计数初始化为1。
当一个对象的引用计数为0时,与该对象对应的析构函数将被调用, 但是调用析构函数并不一定是调用free释放内存空间,为了避免频繁的申请、释放内存空间,Python中使用的是内存对象池,维护一定大小的内存对象池,调用析构函数时,对象占用的空间将归还到内存池中。
小整数对象
在实际的编程中,数值比较小的整数,比如1,2,等等,这些在程序中是频繁使用到的,而Python中,所有的对象都存活在系统堆上,也就是说,如果没有特殊的机制,对于小整数对象,Python将一次次的malloc在堆上申请空间,然后free,这样的操作将大大降低了运行效率。
那么如何解决呢?Python中,对小整数对象使用了对象池技术。
那么又有一个问题了,Python中的大对象和小对象如何区分呢?嗯,Python中确实有一种方法,用户可以调整大整数和小整数的分界点,从而动态的确定小整数的对象池中应该有多少个小整数对象,但是调整的方法只有自己修改源代码,然后重新编译。
大整数对象
对于小整数,小整数对象池中完全的缓存PyIntObject对象,对于其它对象,Python将提供一块内存空间,这些内存空间将由这些大整数轮流使用,也就是谁需要的时候谁使用。
比如,在Python中有一个PyIntBlock结构,维护了一块内存,其中保存了一些PyIntObject对象,维护对象的个数也可以做动态的调整。在Python运行的某个时刻,有一些内存已经被使用,而另一些内存则处于空闲状态,而这些空闲的内存必须组织起来,那样,当Python需要新的内存时,才能快速的获得所需的内存,在Python中使用一个单向链表(free_list)来管理所有的空闲内存。
主要分为两步:
如果小整数对象池机制被激活,则尝试使用小整数对象池;如果不能使用小整数对象池,则使用通用整数对象池。
面试几个点
- 眼睛有神
首先从外表颜值上,双眼不能十分萎靡无神,最后叙述问题不要语无伦次。
然后是人品和态度亲和度,自己职业经历不能撒谎,表现不要眼高手低,即使自己能力在吊,别说大话等。
很多人不理解为什么双眼无神也不行,因为双眼神情和你的眼睛大小没关系,眼神代表了你平时的精气神,平时的精气神代表了做事的一些习惯,据我经验 双眼无神要么长时间不动脑思考,要么正能量不太足,要么作息十分不规律,沉迷于临时享乐,不思进取等,都会反映到眼神,这样的人不思进取和学习能力堪忧的几率会变大。这个和每天想不停进步的人精气神是完全不一样的,跟着我你还可以学玄学。
我希望我的团队里不求你技术多大牛,技术只要态度和脑子没问题都是持续增长的,但做事习惯和内心能量问题这个我是解决不了的,我也不希望和我合作者,总是思路不清晰,学习能力太差。
- 技术栈太老的我不会考虑
最近的技术栈是你这份工作讨薪的基础和直接起点,以前端开发为例,如果你简历写 之前你一直还在用jq,bootstroop等这些基础传统框架那么我看到简历之后,会直接pass ,哪怕你写的6年工作经验,硕士毕业还是pass。
现实就是这么残酷,跟不上技术的更新换代和适应能力,势必慢慢会被淘汰。有的人会说我在学,我学习能力很快,肯定能学好,好!态度没问题,可现在对我培养你的成本来讲你性价比太低,等不起你。
因为现在流行的开发技术和框架比如 vue ,react,在15年就已经呼声很大了,文档也逐渐全面,那时候学习1.0根本不是问题。不要找借口公司产品成型不让用新技术,我无奈之类的,这并不耽搁你自己去学习和做项目甚至主动跳到要求新技术的公司。而且我在16年已经写文章强调mvvm框架家族和前端工程自动化的重要性,大家一定要重视,不要被淘汰。
- 工作比生活重要这种人生观的我不认同
认真生活 快乐工作
大家都会习惯说 认真工作 快乐生活,我反过来为什么?因为你辛苦工作难道不是为了让自己生活更富足,更有安全感吗?但想过好这一生只有活着是不够的,你一定要努力认真的去规划和计划生活,并不能只快乐的乌托邦式,你一定要时常给自己制定生活阶段目标和逐步实现它。
工作是物质来源的基础,如果你体会不到工作带给你的成就感和快乐,拿到钱的快乐,每天只感受到认真的压力,那么你的工作会长久吗,工作会高效吗?自己的生活都处理不好没条理,工作估计也奢望不了
所以一般我会和面试者聊工作和生活的问题,如果明确感受到他认为工作真比生活重要的,我会考虑考虑给不给offer。
- 有自己博客和开源贡献的 直接加分
一个不懂总结和不会总结或懒得总结的人,不会是一个有思想的人。这个时代人人写博客,文章的成本何止是低,那是相当容易,如果你只工作,闷头撸码,不做总结和记录,无异于浅尝止渴,做的量产无用功居多,不总结就得不到质的提升。
还有一点 总结写文,是你思想和知识体系的象征,是你直接的财富体现,无论质量好坏,至少你已经比大部分求职者厉害多了。所以我会优选这部分面试者,技术其次!因为他有这个意识,我还会怕他技术和解决问题的能力没长进吗?
- 十分狂妄,自视甚高的不考虑
你技术或许比我们都吊,毕竟天才和痴心技术的人才还是很多的,这是客观事实必须尊重。但你为人高调,不谦虚谨慎就是做人问题,十分不利于团队协作,我不是让你听安排,毕竟技术好的人都是有脾气的,但谁不喜欢能力又好性格又好的呢,或许吕布、项羽是你的偶像,自恃一身好武艺,却不是团队合作甚至带团队的好人选,甚至影响士气和团队气氛,他俩全都失败了。从公司层面和团队层面这种人都是让人头疼,也往往是呆不长久的。
redis-pub_sub
1 |
|