Python
数据类型
- list和- tuple的区别?- tuple不可变, list可变 
- dict和- set的区别?- set就是没有value的dict 
- list可以做- dict的- key吗?为什么?- 不可以, dict的key必须是可hash的, 不可以随意更改, 否则经过散列函数后, 会得到不同的散列地址. 
- tuple可以做- dict的- key吗?为什么?- 如果tuple内部的元素都是不可变的, 那么可以做为key. 
 如果tuple内部中有可变元素, 那么不可以做为key.
- dict是无序的还是有序的?- 3.6以上是有序的, 但是日常还是按照无序结构来记忆. 
数据处理
- 什么encode(编码)? - 将字符串转变为二进制序列的是编码encode. 
- 解码时有时候遇到错误字符怎么处理? - my_bytes.decode("utf-8", errors='ignore') 
- 字符串和时间格式的互相转换 - datetime.strptime(your_string, "%Y-%m-%d") - your_time.strftime("%Y-%m-%d") 
- 扩展: 时间戳和字符串之间的转变 - timestamp <-> datetime <-> str 
- 如何度列表进行组合排序 - [].sort(key=lambda x: (x[0], x[1])) - 自定义排序 - [].sort(key=func) 
 
概念题
- 什么是值?什么是引用? - 值就是数据内容, 引用就是数据地址. 
- 可变对象和不可变对象的区别? - 可变对象存的是引用, 不可变对象存的是值. - 例外 - b = [1,2] 
 t = (1, b, 3)
 t[1].append(3)
 t (1, [1, 2, 3], 3)
 
- 深拷贝和浅拷贝的区别? - 浅拷贝只复制最外层的对象. 
 深拷贝会递归地复制嵌套对象, 返回一个全新的对象.
- 函数中 - *args,- **kwargs分别代表什么?- *args代表不定长的参数列表, args其实是个tuple 
 **kwargs代表不定长的键值对参数, kwargs其实是个dict
- 变量有哪些类型 - 内置变量(bulit-in)
- 全局变量 - 模板B从模块A中导入全局变量a, 那么在模块B中a是否是全局变量? - 不是 
 
- 自由变量 - 对于foo来说, a是一个局部变量, 对于inner来说, a是自由变量 - def foo(): 
 a = 1
 def inner():
 pass
- 局部变量
 
- 什么是装饰器? - 为被装饰的函数提供特殊功能的函数 - 装饰器的原理是什么? - 闭包 - 什么是闭包? - 闭包就是通过自由变量延申了作用域的函数 
 
 
- 什么是递归函数? - 在函数体当中调用了自身, 那么你就是递归函数 - 手写一个斐波那契函数
 
- 什么是面向对象编程? - 通过封装, 多态, 继承三个思想来完成代码复用, 本质就是隐藏实现的细节, 只关注对外暴露的接口. - Python是怎么体现封装的? - 通过类来实现对事物的抽象归类 
 例: math
- Python是怎么实现多态? - 通过继承, 子类可以覆盖父类的方法来实现多态. 
- 类在继承过程中, 遇到多继承的情况, 如何解决菱形继承? - 在__init__方法中使用super函数来指定MRO顺序 
- 什么是单例模式? - 单例模式就是当前类在本次程序运行过程中实例化一次. 我们每次实例化一个类都得到了一个新对象, 但是单例模式只会得到一个实例对象 - 如何实现单例模式? - 重写__new__方法 
- 单例模式有什么应用? - 能实现懒加载, 只有在使用时才会创建实例, 比如线程池, 缓存和内存对象 
 在处理资源时避免了冲突, 比如logger模块
 
- 迭代器和可迭代对象有什么区别? - 可迭代对象可以简单认为是可以遍历的对象. 而迭代器只有在调用时才返回一个元素. 
 像list这样的可迭代对象会把元素全部加载进内存中, 如果当前列表比较大, 会占用大量内存, 迭代器只有调用才返回一个元素, 减少了内存资源的占用.
- 迭代器和生成器有什么区别? - 生成器是特殊的迭代器, 迭代器提供了数据的惰性返回, 而生成器提供了指令的惰性执行. 
 
多线程和多进程
- 什么是多线程?什么是多进程?两者有什么区别? - 线程是操作系统进行运算调度的最小单位 
 进程是操作系统进行资源分配的最小单位- 进程下可以有多个子进程, 子进程下又可以有多个线程, 每个线程又可以有多个子线程. - 两者有什么区别? - 对linux来说, 没有什么太大的区别. - 进程有自己的独立地址空间 
 多线程可以共享进程资源, 多进程之间的通信更为复杂, 需要以ipc的方式进行.
 多进程间一般不互相影响, 多线程一条线程的崩溃可能会导致所有线程出问题.
 
- 什么是计算密集型? 什么是IO密集型? - 网络请求, 数据库查询, 文件读写这些需要等待的任务都是IO密集型 
 CPU进行计算属于计算密集型
- Python在计算密集型中使用多线程几乎没有提升性能, 为什么? - 因为全局解释器锁的存在, 单核上只能同时有一个线程在运行python的字节码 
- 什么是全局解释器锁(GIL) - 在一个进程下, 只允许一个线程执行Python的字节码 
- 如何绕过全局解释器锁 - 将多线程改为多进程 
 将计算密集型任务交给C扩展
 使用Apache, Spark等分布式计算引擎
- 进程间如何进行通信 - 共享内存
- 文件
- 消息队列
- socket
- 信号量
 
- 线程间如何进行通信 - 共享变量(global)
- 共享内存
- 文件
- 消息队列
- socket
- 信号量
 
- 什么是协程? - 本质就是用户态的线程, 由客户端对事件进行调度而不是操作系统 
- 什么是异步? - 不等待结果的返回, 返回期物后继续执行其他事件, 待期物完成后继续执行未完成的事件. 
- 协程的原理? - 维护了一个事件循环队列, 然后循环访问事件来完成异步的消息维护.
- 协程的原理就是生成器的原理, 可以暂时地保存当前上下文, 待执行后恢复
 
- 实现一个多线程demo
- 实现一个多进程demo
- 使用asyncio异步程序demo
网络通信
- 从浏览器中敲下url到页面展示发生了什么?
- 五层协议有哪五层? - 应用层 - HTTP 
- 运输层 - TCP/UDP 
- 网络层 - IP 
- 数据链路层
- 物理层
 
- 什么是TCP/IP? - 表示的是HTTP, ftp等应用协议, TCP, UDP等运输层协议, IP网络层协议的协议族 
- TCP/IP三次握手
- TCP/IP四次挥手
- HTTP和HTTPS有什么区别? - 在HTTP的基础上增加了SSL, 可以认证用户和服务器, 保证了传输数据的安全 - 了解: HTTPS的验证过程
 
- 什么是中间人攻击 - 插入到客户端和服务端的通信, 对服务端伪装成客户端, 对客户端伪装成服务端, 拦截之间通信产生的报文 
Mysql数据库
概念题
- 事务的特性有哪些? - 原子性
- 一致性
- 隔离性
- 持久性
 
- 事务的使用场景? - 银行转账. 
 日常开发中, 最常见的是在不使用外键的情况下, 两张表有关联关系, 所以在插入的API接口中使用了事务.
- 数据库的字符问题 - 要选择utf-8mb4 - 为什么不使用utf-8 - mysql中的utf-8字符集并不全 
 
- 常见的数据类型 - 数字 - int, bigint, float, double, decimal 
- 字符类型 - char, varchar, text 
- 时间类型 - datetime, timestamp 
- 计算金额的时候应该使用哪个类型, 为什么? - 用decimal, 因为decimal背后存的是字符串, 不会产生精度问题. 而float和double会. 
- char和- varchar的区别?- char是固定长度, varchar是不固定长度的, 可以节约空间. 
- 如何在mysql中转换float的精度? - FORMAT(0.33333, 2) - 0.33 
 
- 可以在任意字段上创建主键/索引吗? - 不可以, 索引对字段的最大长度是有要求的, 不可以超过767bytes, 也就是最大长度为191 - 什么样的字段适合创建索引? 为什么? - 与业务无关的字段, 最好是自增ID, 避免记录经常发生修改 
 因为索引是一个有序结构, 需要重新排序, 如果频繁修改字段, 会造成性能损耗.
- 你是怎么建索引的? - 表比较大的时候, 尽量使用主键, 少建索引.
- 读的情况比较频繁, 对常用的字段建立索引.
 
 
- 索引的原理? - B+数 - 在字段A和字段B上创建联合索引, 搜索字段B的时候可以命中索引吗? 为什么? - 如果是两个字段的联合索引会命中, 因为mysql做了相应的优化. 
 如果是多个字段的联合索引遵循左缀查询规则.
 
- 如何优化mysql查询? - 加索引 - 加索引, 同步避免使用不会命中索引的查询语句 - 哪些语句不会命中索引呢? - not in 
 !=
 between
 like "%a%" // 不会命中索引
 like "a%" // 会命中索引
 
- 加缓存 - mysql默认开启查询缓存
- 用redis做缓存 - 把一段时间不会更新的查询持久化 
 
 
操作题
- CRUD操作
- 集合操作
- 分组查询
Redis数据库
概念题
- 什么是redis? - 一种非关系型数据库, 以键对值的方式进行远程存储 
- redis有哪些数九结构 - String
- Hash
- List
- Set
- Zset
 
- 什么是分布式锁? - 在分布式系统中需要对某些资源加锁 - 如何通过redis实现分布式锁? - SET 资源名称 random_value 过期时间 - 为什么使用random_value - 避免了其他进程或者线程在释放锁的时候, 错误地释放了穷他进程和线程的锁 
- 为什么要有过期时间 - 防止死锁 
 
 
操作题
- 各种数据类型的CRUD操作 - zset只用知道加分, 移除, 添加即可 
爬虫
概念题
- 在requests中params和data参数的区别? - 一般GET使用params, params最终会被拼接到url上 
 一般POST使用data, 但是也可以携带params
- 什么是动态页面? - 通过ajax在不刷新页面的情况下即可进行新内容的交互和渲染 - 什么是ajax? - asynchronousJavaScript-XML, 本质是一个js模块. 
- 什么JSON? - 将js对象和String类型互相转换. 
 
- Scrapy有哪些组件 - Spiders - 写爬虫业务逻辑的地方 
- Engine - 调度事件 
- Schedule - 调度任务 
- Downloader - 实际去发送请求的组件 
- item pipeline - 处理爬虫爬取到的结果 
 - 在spiders和engine之间有爬虫中间件 
 在downloader和engine之间有下载器中间件
- Scrapy中一个请求执行的流程
- Scrapy如何传递参数 - 通过meta对象 
- 有写过Scrapy中间件吗? - 有写过, 写过UA中间, 代理中间件, 重试中间件, 还有在schedule层的去重组件 - 讲一下去重组件 - scrapy自带的去重模块是在schedule层的, 在请求没发送之前就创建了指纹, 而且是根据url, method, body来进行去重的, 有时候没有办法满足业务需求, 比如按日期进行过滤, 所以重写了去重组件. 
- 讲一下重试中间件 - scrapy自带的重试中间件是通过特定的异常来进行重试的, 但是有时候遇到返回的状态码是200, 但是内容却是错误的, 所以重写了重试中间件来自己操作重试. 
 
- 什么是分布式爬虫? - 本质就是多台服务器共同完成一件爬取任务, 这里我使用scrapy-redis来完成, 主要是拆分了生产者和消费者. 
- 什么是selenium? - 通过浏览器驱动的方式来操作浏览器的行为 - 什么场景下使用? - 有的网站需要登陆, 当前账号很重要. 避免对方监控用户行为封禁账号, 比如浏览网页的鼠标事件还有selenium本身的驱动指纹. - 在实际使用中, 遇到了哪些驱动指纹? - 在爬x宝搜索页的时候会遇到滑动验证码, 如果当前navigator.webdriver这个属性为True, 则会被反爬 
- 如何解决该问题? - 在浏览器驱动配置中设置disable-blink-features=AutomationControlled 
- 还有其他浏览器驱动指纹吗? - navigator.plugins
- navigator.languages
- navigator.userAgent
 
 
 
- 有JS逆向的相关经验吗? - 有逆向X多多的经验 - 说说逆向的过程 - 先定位到请求接口, 然后打开chrome开发者工具, 设置好断点, 然后通过分析调用栈来找到具体的加密函数. 之后在该函数调用前后调用后进行断点, 找齐所有需要的参数, 最后讲加密函数抠出来, 并通过nodejs封装成一个服务调用 - 你是怎么把加密函数抠出来的? - 直接获取整个加密函数所在的JS文件,然后生成该加密数据所在的对象, 通过对象调用方法的形式完成最终的加密. 
 期间会遇到一些window和document对象环境缺失的问题, 缺什么补什么即可.
- 遇到混淆变量名的情况你是怎么处理的? - 把还原函数抠出来, 通过正则和eval还原原始变量. 
- 在逆向中遇到了什么困难? 又是怎么解决的? - X多多的验证了鼠标事件, 需要自己去生成对应的鼠标事件. 
 通过Python写了一个生成函数, 然后将鼠标轨迹做为参数传递给nodejs服务- nodejs用的哪个库来起服务的? - express 
 
 
 
操作题
爬虫操作题不关键, 主要还是css选择器, 比如模糊匹配
- css选择器的CRUD操作
- Scrapy项目的细节
- selenium的窗口操作
- selenium事件和原型链操作
Django
概念题
- 什么是MTV模型 - M是model, T是template, V是view 
 用户的请求由视图层来处理, 如果涉及到查表操作, 则通过模型层的orm来和数据库进行交互, 最终将结果传递到模板层生成html页面后返回至客户端.
- 模型创建完毕后需要执行哪些步骤 - 先在设置中激活应用. 
 然后通过makemigrations命令来进行本地同步
 最后通过migrate命令正式与数据库进行同步- 如何解决同步冲突? - 首先查看本地的migrations文件, 如果没有问题, 排查数据表中的migrate记录. 
- 如果我不想使用django的模型迁移我该怎么做? - 在模型层中的Meta中设置managed=False 
- 如何指定数据表 - 在模型层中的Meta中设置db_table 
- 如何指定数据库 - 在设置中配置DATABASES, 在model对象中使用using参数指定数据库 
- 模型层中有哪些常用的Field? - CharField - 对应的是mysql中的varchar, 所以要指定长度 
- TextField
- DecimalField
- DateTimeField
 
- 模型在继承的时候需要注意什么? - 如果父类不想创建表, 需要将该类指定为抽象类, 在Meta中设置abstract=True - 子类最好自己重写Meta嵌套类 
 多继承中子类在显式地声明主键字段
- 视图层如何进行URL匹配 - django提供了两种方式 
 一种直接匹配, 匹配到的值会做为参数传递到视图层中
 另一种遇到特殊情况, 可以使用re_path正则匹配url
- 如何获取GET和POST中的参数 - GET使用request.GET 
 POST使用request.POST
- 如何返回JSON数据格式 - 有自带的JsonResponse 
- 什么是restful api? - URL用来定位资源, method用来表示操作 - 具体有哪些method方法, 分别表示什么操作? - GET 查询
- POST 添加
- PUT 更新
- DELETE 删除
 
- 有哪些常见的状态码 - status_code, 分别代表什么意思- 200 表示成功
- 302 表示重定向
- 403 表示服务器拒绝响应, 一般是身份验证失败
- 500 表示服务器内部错误
 
 
- 有用过 - djangorestframework这个第三方应用么?- 有用到, 主要拿来解即模型对象序列化的反序列化的问题, 但是我现在主要些API返回JSON数据,所以用的少了. 
- 用什么方式部署django? - uwsgi 和 nginx - 对nginx了解到什么程度? - 只拿来做代理转发, 没有研究过底层原理. 
 
- 如何进行分页 - 指定LIMIT开始的位置 
 select * from xxx limit , page_size;- 如果遇到表比较大的情况, 怎么分页 - 根据主键id进行分页 
 select from table where 表达式 limit (page_numpage_size), page_size;
 
- 遇到跨域问题, 怎么解决? - 在返回头中设置响应的属性, 比如Access-Control-Allow-Origin - 在哪里设置的返回头? - 在django中的response对象返回头中可以设置.
- 也可以在nginx中设置返回头.
 
 
 
操作题
- 如何在django中使用事务 - from django.db import transaction 
 ...
- 如何进行分页 - select from table where 表达式 limit (page_numpage_size), page_size; 
- orm的CRUD操作
JavaScript
js做为辅助语言一般被问到的概率不大
- JS一般怎么生成一个对象 - 直接声明 
 或者通过构造函数new一个
- JS中的call和apply是什么意思? - call和apply只是传入参数的区别, 两者都是将当前函数绑定到特定的而对象上 
- 什么是Promise? - Promise是一个对象, 代表了一个异步操作最终完成的结果, 也就是期物. - 对于成功和失败结果, JS是怎么处理的? - 会分流处理, 成功的结果会走fullfill的流程, 失败的结果会走reject流程. 
 
- JS中的异步是怎么实现的? - 把操作封装成事件丢进一个无限循环的消息队列当中, 每一个事件关联着处理这个事件的回调函数. 
- JS你用的什么框架? - 本地环境用的nodejs, 浏览器环境用的jquery 
Linux命令
数据结构
- 链表
- 队列和栈
- hashmap
- 树和堆了解即可
算法题
排序是最关键的
 
                             
                            
此处评论已关闭