导语:本人最近刚离职,抱着一腔热情踏上了漫漫求职路,现将本人面试时遇到的问题汇总一下,供大家交流学习,望不吝惜,最后打一波广告,学习Python可进群647094497,我会分享一点资料给大家,金麟岂是池中物,一入风云便化龙
流量+ python爬虫工程师
一、FastDFS的工作原理和配置
1.什么是FastDFS
FastDFS 是用 c 语言编写的一款开源的分布式文件系统。
使用 FastDFS 很容易搭建一套高性能的文件服务器集群提供文件上传、下载等服务。
FastDFS 架构包括Tracker server和Storage server。
Tracker server 作用是负载均衡和调度,通过 Tracker server在文件上传时可以根据一些策略找到
Storage server提供文件上传服务。可以将 tracker 称为追踪服务器或调度服务器。
Storage server 作用是文件存储,客户端上传的文件最终存储在 Storage 服务器上,
可以将 storage 称为存储服务器。
二、Numpy和Pandas的区别
Numpy是以矩阵为基础的数学计算模块,纯数学。Numpy只能处理数值计算
Pandas提供了一套名为DataFrame的数据结构,比较契合统计分析中的表结构,
并且提供了计算接口,可用Numpy或其它方式进行计算。
Pandas不但可以处理数值计算(基于Numpy)还可以处理其他类型的数据
三、scrapy框架中如何配置代理IP
1.需要在middlewares.py中自定义一个中间件来配置代理IP:
2.然后在settings.py中配置中间件:
四、使用request模块实现爬虫的全过程
1.发送网络请求,返回响应数据:
response = requests.get(url,headers=headers)
2.对响应数据进行解析:
response.content.deocde()
五、如何实现url地址去重
可以使用基于布隆过滤器(Bloom Filter)的存储。
布隆过滤器的基本算法思想主要是利用一个长度为M的位数组,且初始化为零,
一个元素通过K(K< 当再有数据字符串进来要存储的时候,比对该位置是否为1,如果是1就舍弃, 如果是0则继续存储。以此来达到去重的效果。 华为外包 python开发工程师 一、简述多线程、多进程、协程 1.多线程(threading): 在⼀个进程内的所有线程共享全局变量,方便在多个线程间共享数据 缺点就是,如果多个线程同时对同⼀个全局变量操作, 会出现资源竞争问题,从而数据结果会不正确,解决方法是使用互斥锁 2.多进程(multiprocessing): 进程不共享全局变量,相互独立,安全性较高 缺点是会加大系统消耗 3.协程(Coroutines): 协程是一种比线程更加轻量级的存在,一个线程也可以拥有多个协程 协程的调度完全由用户控制。协程拥有自己的寄存器上下文和栈。 协程调度切换时,将寄存器上下文和栈保存到其他地方, 在切回来的时候,恢复先前保存的寄存器上下文和栈, 直接操作栈则基本没有内核切换的开销,可以不加锁的访问全局变量, 所以上下文的切换非常快 二、异步编程 Python通过协程(coroutine)来实现异步编程 三、redis的内存淘汰机制 1.过期键删除策略: 定时删除:在设置键的过期时间的同时,创建一个定时器(timer ), 当过期时间到了后立即执行对键的删除操作。 惰性删除:放任键过期不管,但是每次从键空间中获取键时,都检查取得的键是否过期, 如果过期的话,就删除该键;如果没有过期,就返回该键。 定期删除:每隔一段时间,程序就对数据库进行一次检查,删除里面的过期键。 至于要删除多少过期键,以及要检查多少个数据库,则由算法决定。 2.内存淘汰机制: 当目前使用的内存超过了设置的最大内存,就要进行内存释放了, 当需要进行内存释放的时候,需要用某种策略对保存的的对象进行删除。 Redis有六种策略(默认的策略是volatile-lru): volatile-lru:使用LRU算法进行数据淘汰(淘汰上次使用时间最早的,且使用次数最少的key), 只淘汰设定了有效期的key ; allkeys-lru:使用LRU算法进行数据淘汰,所有的key都可以被淘汰; volatile-random:随机淘汰数据,只淘汰设定了有效期的key; allkeys-random:随机淘汰数据,所有的key都可以被淘汰; volatile-ttl:淘汰剩余有效期最短的key; no-enviction:不删除任意数据(但redis还会根据引用计数器进行释放), 这时如果内存不够时,会直接返回错误 。 四、数据库事务的ACID特性: ACID是Atomic(原子性)、Consistency(一致性)、 Isolation(隔离性)和Durability(持久性)的英文缩写。 原子性(atomicity):事务中的所有操作要么全部提交成功,要么全部失败回滚。 一致性(consistency):数据库总是从一个一致性状态转换到另一个一致性状态。 隔离性(isolation):一个事务所做的修改在提交之前对其它事务是不可见的。 持久性(durability):一旦事务提交,其所做的修改便会永久保存在数据库中。 五、简述三次握手和四次挥手: 三次握手: 1. client发送SYN(seq=x)报文 => server(client状态变为SYN_SENT) 2. server发送ACK(seq=x+1)以及SYN(seq=y)报文 =>client (server状态变为SYN_RECV) 3. client发送ACK(seq=y+1) => server (client变为ESTABLISHED,服务器收到后也变为ESTABLISHED) 四次挥手: 1. client发送FIN(seq=x) =>server (client变为FIN_WAIT_1) 2. server先回复ACK(seq=x+1) => client (server只要收到FIN报文就会变为CLOSE_WAIT, client变为FIN_WAIT_2) 3. server发送完剩余的数据报文后,再发送FIN(seq=y) =>client (server变为LAST_CHECK) 4. client发送ACK(seq=y+1) => server (client变为TIME_WAIT) server收到ACK后直接就关闭closed状态,但client要等2MSL(最大报文生存时间)才会变为closed。 client的状态转变顺序:established-->fin_wait_1->fin_wait_2->time_wait->closed server的状态转变顺序: established-->close_wait->last_ack->closed 六、正向代理和反向代理 国双科技 python开发工程师 一、简述django的一次请求的生命周期(运行上下文) 1、简略版的请求过程 2、详细版的请求过程: 总结一下:当有请求到来时,会调用WSGIServer的handle_request方法实例化WSGIRequestHandler 然后WSGIRequestHandler在实例化的同时会调用handle方法实例化ServerHandler, 并调用其run方法,ServerHandler的run方法会实例化WSGIHandler,WSGIHandler会加载中间件, 中间件会对请求进行过滤,过滤方式为: 当请求发出时候 -> 经过precess_request -> 进行路由分发,函数匹配到相关url则进行 process_view,否则请求失败->函数(viewfunction)处理完毕 ->经过precess_response返回数据 ->假如有异常则执行process_exception 简单明了:WSGIServer -> WSGIRequestHandler -> ServerHandler -> WSGIHandler -> 中间件过滤 二、对称加密和非对称加密的区别 对称加密:加密和解密使用同一个密钥 非对称加密:加密用公钥,解密用私钥 三、用过什么加密方式?哪种加密性能更好 1、MD5算法(散列): MD5用的是哈希函数,它的典型应用是对一段信息产生信息摘要,以防止被篡改。 严格来说,MD5不是一种加密算法而是摘要算法。无论是多长的输入, MD5 都会输出长度为 128bits 的一个串 (通常用 16 进制 表示为 32 个字符)。 2、SHA1算法(散列): SHA1是和MD5一样流行的消息摘要算法,然而SHA1比MD5的安全性更强。 对于长度小于 2 ^ 64 位的消息,SHA1 会产生一个160位的消息摘要。 基于 MD5、SHA1 的信息摘要特性以及不可逆 (一般而言), 可以被应用在检查文件完整性以及数字签名等场景。 3、SHA256(SHA2)算法(散列): SHA256会产生一个256位的消息摘要。 3、HMAC算法: HMAC 是密钥相关的哈希运算消息认证码,HMAC运算利用哈希算法 (MD5、SHA1 等), 以一个密钥和一个消息为输入,生成一个消息摘要作为输出。 HMAC发送方和接收方都有key进行计算,而没有这把key的第三方, 则是无法计算出正确的散列值的,这样就可以 防止数据被篡改。 4、AES/DES/3DES算法(对称): AES、DES、3DES都是对称的块加密算法,加解密的过程是可逆的。 5、RSA算法(非对称): RSA 加密算法是目前最有影响力的公钥加密算法,并且被普遍认为是目前最优秀的公钥方案 之一。 RSA 是第一个能同时用于加密和数字签名的算法,它能够抵抗到目前为止已知的所有密码攻击, 已被 ISO 推荐为公钥数据加密标准。 6、ECC算法(非对称): ECC 也是一种 非对称加密算法,主要优势是在某些情况下,它比其他的方法使用更小的密钥, 比如RSA加密算法,提供 相当的或更高等级 的安全级别。 不过一个缺点是加密和解密操作的实现比其他机制时间长。 四、restful的优缺点 restful的概念:将URL定义为每一个资源的地址,GET请求方式用来获取资源, POST请求方式用来新建资源(也可以用于更新资源), PUT请求方式用来更新资源,DELETE请求方式用来删除资源 优点:资源和行为分离,更容易理解,更加规范 缺点:用PUT和DELETE方式会增加复杂度,并没有带来什么好处 面对复杂的业务逻辑,无法抽象为资源的增删改查 五、MySQL数据库的底层架构 MySQL的底层架构如下图所示: 上图中设计的部件介绍: 1.connectors:与其他编程语言中的sql 语句进行交互 2.Management Serveices & Utilities: 系统管理和控制工具 3.Connection Pool (连接池):管理缓冲用户连接,线程处理等需要缓存的需求 4.SQL Interface (SQL接口):接受用户的SQL命令,并且返回用户需要查询的结果。 比如select from就是调用SQL Interface 5.Parser (解析器):SQL命令传递到解析器的时候会被解析器验证和解析。 6.Optimizer (查询优化器):SQL语句在查询之前会使用查询优化器对查询进行优化 (产生多种执行计划,最终数据库会选择最优化的方案去执行,尽快返会结果) 他使用的是“选取-投影-联接”策略进行查询。 7.Cache和Buffer (查询缓存):如果查询缓存有命中的查询结果,查询语句就可以直接去查询缓存中取数据。 8.Engine (存储引擎):存储引擎是MySql中具体的与文件打交道的子系统。 一条SQL语句执行的全过程: connectors交互 -> 暂存在Connection Pool中,由Management Serveices 管理 -> 转到SQL Interface -> 查询Cache中是否有匹配的结果,若有则直接返回该结果 -> 转到Parser判断SQL语句是否正确 -> 转到Optimizer选择最优的执行方案 -> 转到Engine处理,与后端的存储设备交互后获取到对应的数据返回 六、MongoDB的使用 首先需要明确MongoDB中的一些概念: 1、文档:文档是MongoDB中存储数据的基本单位,结构是一组键值对 2、集合:集合就是MongoDB中的文档组,类似于MySQL中的表格。 3、MongoDB对文档的增删改查: 增:db.集合名称.insert(document) 删:db.集合名称.remove( 改:db.集合名称.update( 查:db.集合名称.find() 八、python的垃圾回收机制 python采用的是引用计数机制为主,标记-清除和分代收集两种机制为辅的策略。 引用计数的原理:每个对象维护一个ob_ref字段,用来记录该对象当前被引用的次数, 每当新的引用指向该对象时,它的引用计数ob_ref加1, 每当该对象的引用失效时计数ob_ref减1,一旦对象的引用计数为0, 该对象立即被回收,对象占用的内存空间将被释放。 标记清除的原理:标记清除分为两个阶段:第一阶段是标记阶段,把所有的『活动对象』打上标记, 第二阶段是把那些没有标记的对象『非活动对象』进行回收。 分代收集的原理:分代回收是一种以空间换时间的操作方式, Python将内存根据对象的存活时间划分为不同的集合,每个集合称为一个代, Python将内存分为了3“代“,分别为年轻代(第0代)、中年代(第1代)、 老年代(第2代)他们对应的是3个链表,它们的垃圾收集频率与对象的存活时间的增大而减小。 新创建的对象都会分配在年轻代,年轻代链表的总数达到上限时, Python垃圾收集机制就会被触发,把那些可以被回收的对象回收掉, 而那些不会回收的对象就会被移到中年代去,依此类推, 老年代中的对象是存活时间最久的对象,甚至是存活于整个系统的生命周期内。 九、分布式架构 主要是使用Celery框架 十、网站的安全证书(SSL) 网站安全证书又叫SSL证书,是数字证书的一种。 网站通过安装SSL证书,在客户端浏览器和Web服务器之间建立一条SSL安全通道, 从而实现数据信息在客户端和服务器之间的加密传输。 可以有效防止数据信息的泄露。保证了双方传递信息的安全性, 而且用户可以通过服务器证书验证他所访问的网站是否是真实可靠。 网站所有者需要向CA(权威证书颁发机构)申请安全证书 十一、MySQL数据库存储的数据结构 常用的数据结构为B树和B+树 十二、堆和栈的区别 堆和栈的定义: 堆,队列优先,先进先出 栈,先进后出 堆和栈的区别: 1、堆栈空间分配 栈(操作系统):由操作系统自动分配释放,存放函数的参数值,局部变量的值等。 堆(操作系统):一般由程序员分配释放,若程序员不释放,程序结束时可能由OS回收, 存储的是实体 2、堆栈缓存方式 栈使用的是一级缓存,他们通常都是被调用时处于存储空间中,调用完毕立即释放。 堆则是存放在二级缓存中,生命周期由虚拟机的垃圾回收算法来决定。 所以调用这些对象的速度要相对来得低一些。 3、堆栈数据结构区别 堆(数据结构):堆可以被看成是一棵树,如:堆排序。 栈(数据结构):一种先进后出的数据结构。 十三、简述docker Docker是一个开源的应用容器引擎,基于Go语言 并遵从Apache2.0协议开源。 Docker可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中, 然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。 容器是完全使用沙箱机制,相互之间不会有任何接口(类似 iPhone 的 app), 更重要的是容器性能开销极低。 十四、如何实现单元测试 主要使用pytest进行单元测试,pytest是一个无数人推荐并在使用的Python单元测试框架, 它使用起来非常简单,只要你的方法名以 test 开头就可以, 你可以和需要测试的方法放在一起,亦或是新建一个文件来专门整理单元测试,都可以。 使用:在PyCharm中只要你将默认的单元测试驱动改成pytest, 就可以在任意test开头的方法上通过右键菜单运行或者调试这个测试案例,非常方便。 腾讯外包 Python开发工程师 一、迭代器和生成器的区别 首先要明确几个概念: 1.容器(container): 容器是一种把多个元素组织在一起的数据结构, 可以用in, not in关键字判断元素是否包含在容器中 常见的容器对象有list,set,tuples 2.可迭代对象(iterable): 只要是可以返回一个迭代器的对象都是可迭代对象 3.迭代器(iterator): 迭代器是实现了工厂模式的对象,他能在你调用next()方法的时候返回容器中的下一个值, 任何实现了__iter__和__next__方法的对象都是迭代器, __iter__返回迭代器自身,__next__返回容器中的下一个值, 如果容器中没有更多元素了,则抛出StopIteration异常 有很多关于迭代器的例子,比如itertools函数返回的都是迭代器对象。 4.生成器(generator): 生成器其实是一种特殊的迭代器,不过这种迭代器更加优雅。 它不需要再像上面的类一样写__iter__()和__next__()方法了, 只需要一个yiled关键字。 生成器一定是迭代器(反之不成立), 因此任何生成器也是以一种懒加载的模式生成值。 总结:迭代器和生成器的区别是迭代器是实现了__iter__和__next__方法的对象, 而生成器是一种特殊的迭代器,它的返回值不是通过return而是用yield 二、写一个装饰器获取函数运行时间 1、装饰器的概念: 装饰器本质上是一个Python函数。它可以让其他函数在不需要做任何代码变动的前提下增加额外功能, 装饰器的返回值也是一个函数对象。 2、代码实现: 三、返回数组中第K大的数的算法 四、MySQL聚合查询的SQL语句 五、HTTP常用的状态码 100:继续发送请求 101:转换协议 102:继续处理 200:请求成功 201:请求完成 202:请求阻塞等待 204:服务器端已经实现了请求,但是没有返回新的信息。 301:重定向到分配的URL 302:重定向到临时的URL 304:请求的资源未更新 400:非法请求 401:未授权 403:禁止 404:没有找到 500:服务器内部错误 501:服务器无法识别 502:错误网关 503:服务出错 六、压缩文件的Linux命令 tar -zcvf 打包后生成的文件名全路径 要打包的目录 七、二叉树的前序遍历、中序遍历和后序遍历