欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

面试题流散汇总

程序员文章站 2022-04-18 08:27:00
...

1、n位数全排列 大字符串相加 SQL HTTPS 根据简历来问

2、MapReduce和Spark的主要区别在于,MapReduce使用持久存储,而Spark使用弹性分布式数据集(RDDS)。Spark之所以如此快速,原因在于它在内存中处理一切数据。没错,它还可以使用磁盘来处理未全部装入到内存中的数据。Spark已证明在数据多达PB的情况下也轻松自如。它被用于在数量只有十分之一的机器上,对100TB数据进行排序的速度比Hadoop MapReduce快3倍。

Spark与MapReduce是一种相互共生的关系。Hadoop提供了Spark所没有的功能特性,比如分布式文件系统,而Spark 为需要它的那些数据集提供了实时内存处理。完美的大数据场景正是设计人员当初预想的那样:让Hadoop和Spark在同一个团队里面协同运行。

3、Linux开发环境配置:putty、ssh、windows和linux共享用samba、mingw、codeblock、cygwin、lfs经验

4、python垃圾回收机制分析  

参考链接:https://blog.csdn.net/tab_space/article/category/5981645

经典的垃圾回收有几种,例如,引用计数回收器,标记清除回收器,重定位回收器,拷贝回收器及世代回收器等等。这里主要介绍引用计数,标记清除和世代三种,还有两种其实和世代回收器类似。

PyObject对象内存模型:

面试题流散汇总

一个PyObject必须包含ob_refcntob_typeob_refcnt是这个对象的引用计数,而ob_type则是指向_typeobject结构体的指针,它是Python内部的一种特殊对象,它是用来制定一个对象类型的类型对象,所以上图中它指向了一个PyTypeObject

在PyTypeObject中定义了大量的函数指针,这些函数指针最终都会指向某个函数,或者指向NULL。这些函数指针可以视为类型对象中所定义的操作,而这些操作直接决定着一个对象在运行时所表现出的行为。

在Python中,对象机制的核心其实非常简单,一个是引用计数,一个是类型信息。

定长对象内存模型:

面试题流散汇总

面试题流散汇总

面试题流散汇总

在Python中,List其实是一个可变长的,类似于C++中的vector的数据结构,为什么它的内存模型是定长的呢?

其实它的内存模型的字段都是元数据(meta-data),而真正存放数组数据的是ob_item指向的一个数组。

ob_sizeallocated都和PyListObject对象的内存管理有关,PyListObject所采用的内存管理策略和C++中的vector采取内存管理策略是一样的。在每一次需要申请内存的时候, PyListObject总会申请一大块内存,这是申请的总内存的大小记录在allocated中,而实际被使用了的内存的数量则记录在了ob_size中。

变长对象内存模型:

面试题流散汇总

面试题流散汇总

标记清除方法遵循垃圾检测和垃圾回收两个阶段,其简要工程如下:

1). 寻找根集(root object set,所谓的根集即是一些全局引用和函数栈中的引用。这些引用所用的对象时不可被删除的,而这个根集也是垃圾检测动作的起点。

2). 从根集出发,沿着根集中的每一个引用,如果能到达某个对象A,则称A为可达对象,可达对象时不可被删除的。这个阶段就是垃圾检测的阶段。

3). 当垃圾检测阶段结束后,所有的对象分可达对(reachable object)象和不可达对象(unreachable object)两部分,所有的可达对象都必须予以保留,而所有的不可达对象所占用的内存将被回收,这就是垃圾回收阶段。

全集的数据结构为链表,每一个PyObject中在GC的时候,头部会添加一个叫做PyGC_Head的结构:

面试题流散汇总

当generation 0的对象个数大于一定阈值时,就需要进行一次世代回收collect_generations。collect_generations函数中,Python会借第0代内存链表的越界触发了垃圾收集的机会。输入参数generation表示函数必须指定某一代,在这里我们称为”当代“;返回不可达对象的个数,回收过程描述为:

static Py_ssize_t
collect(int generation)
{
    //[1]: 初始化定义               m个可被回收,n个不可被回收

    //[2]: 将比当代处理的“代”更年轻的“代”的链表合并到当前“代”中

    //[3]: 将当代对象中的引用计数抄一份到对象的Py_GC_Head中(gc_refs = ob_refcnt)

    //[4]: 通过traverse机制更新对象中的引用计数,最终不可达对象的引用计数会被减为0,不为0即是root object

    //[5]: 初始化一个链表叫unreachable,把不可达的对象(引用计数为0)移到该链表中

    //[6]: 又初始化一个链表叫finalizers, 把链表unreachable中带有__del__的对象进一步分离到finalizers

    //[7]: 将finalizers中的对象又设置为可达对象(gc_refs=GC_REACHABLE)

    //[8]: debug信息,可以打印可回收对象

    //[9]: 通知所有弱引用到unreachable对象的对象,如果弱引用对象仍然生存则放回

    //[10]: 删除unreachable链表中的对象(垃圾),这会打破对象的循环引用

    //[11]: debug信息,可以打印不可回收对象

    //[12]: 把所有finalizers链表中的对象放到gc.garbage中

    //[13]: 返回不可达对象个数
}