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 表示服务器内部错误
- 具体有哪些method方法, 分别表示什么操作?
-
有用过
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
- 树和堆了解即可
算法题
排序是最关键的
版权属于:KevinBean
本文链接:https://www.kevinbean.top/index.php/default/1669.html
转载时须注明出处及本声明