面试题
# 编程语言概念
★ 不局限于python语言,有些概念是java等语言里的!
-1- 你都了解哪些编程语言,以及它们之间的区别?
c#、java、php、python、golong 这些高级语言的底层都是由 c/c++ 开发的!
eg: 在IDLE里输入 v=1.2, 会去执行 floatobject.h 文件的c代码
- c: c语言的执行效率高,但对代码要求比较高,很多功能都需要自己手动实现,比如,需要自己进行内存管理(内存的开辟和销毁
- java: 比较好的语言,很多企业级的应用都会选者python,市面上大多数公司都用java
- c#:很优雅的语言. 美中不足的是,需在window系统上开发,部署时需放在window Server服务器上!!要花很多钱!
- PHP:一般用于写网站/快速搭建网站.
- golang:语法和c比较接近,处理并发时比较有优势,尤其是IO并发方面!docker就是基于golong来实现的!
python 编写代码简洁,入门简单,相对于其它语言,很简短的代码能做很多事!
> 与PHP相比,PHP只是单方面的优势,python是多方面的,除了web开发,python还可以运维自动化、数据分析、爬虫等
> 与java、c#相比,pyhton写起来简洁
java、c#里没有函数式编程,写个方法都得写一个类,将方法放在里面!
像三元运算、lambda 表达式、yield关键字, python语言有,其它高级语言也有!!
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
-2- 构造方法/函数 和 析构方法/函数?
构造方法: 用于创建对象的函数!
析构方法: 用于销毁对象(释放内存)的函数!
在java中的构造函数: 函数名和类名相同
在python中的实现: __new__ __del__
应用: 在释放之前做一点操作,比如记录日志,但一般情况下我们不会动析构函数!!
1
2
3
4
5
6
2
3
4
5
6
-3- 重写和重载的区别?
重载: 在一个类里,有多个方法,它们的方法名一样,但 参数个数 or 参数类型 or 返回值不同, 这就叫重载!
重写: 子类继承父类,覆盖父类里的方法!
1
2
2
-4- 什么是接口? 接口与类的区别. Python中有接口吗?
注:此处的接口不是API哈,这里的接口是指java里的接口!
python中没有接口,在java中,接口是以interface关键字开头,内部可以定义方法,但方法中不用写具体实现
- 接口专门用于约束它实现的类!!
- python中没有接口这个概念/类型,但可以实现类似于java接口的功能. 有两个方式:
1> raise (通常会采用该方案
2> 类继承抽象类
1
2
3
4
5
6
7
2
3
4
5
6
7
-5- 关于继承,你有什么了解?
python和c++中的类可以多继承;
java、C#、php这些语言不支持类的多继承,只能顺着继承,b继承a,c继承b,变相的实现 c继承a、b.
★ 敲黑板:在其它语言中,一个类可以实现多个接口、一个类不能继承多个类!!
1
2
3
4
2
3
4
-6- 抽象类和抽象方法
它既有约束功能,又具有提供 子类继承方法的功能. python中的抽象类通过abc模块实现.
在java的抽象类里,可以有抽象方法<其内部不能写任何代码,只能写pass>和普通方法
抽象方法可以做约束(相当于java接口)、普通方法可以给子类提供功能(相当于java继承)
So, java抽象类 = java接口 + java继承
1
2
3
4
5
2
3
4
5
-7- 进程和线程的区别
进程是CPU资源分配的最小单位; 线程是计算机被CPU调度/执行的最小单位.
一个进程中可以有多个线程!
1
2
2
-8- 数据库
数据库设计题、sql语法(left join、order by等)、视图/虚拟的表、存储过程、触发器
1
-9- 在浏览器上输入 http://www.baidu.com/
发生了什么?
- dns解析: 将网址解析成IP地址
- 浏览器访问某个网站,本质上就是socket连接,浏览器是socket客户端,网站/后台是socket服务端!
请求到达框架,以Django为例.. BalaBalala..
1
2
3
2
3
-10- http和https的区别
默认端口: http 80 、https 443
- 浏览器访问某个网站,本质就是socket连接,会建立TCP连接,请求头、请求体..数据会遵循http协议规范,
http的数据是基于明文传输的!相当于数据是裸奔的,eg:你连接陌生wifi,别人就可以截获到你的数据包.
- https目的是将数据传输变成秘文.怎么做到的呢? 使用对称密钥和非对称密钥!
1
2
3
4
2
3
4
-11- get、post的区别?
注意哈,放在get中不安全,放在post中安全.这种说法是不对的!! 只要不是https,都不安全.
1
-12- 数据结构与算法
- 链表:单向、双向
- 树: 二叉树前序遍历、二叉树中序遍历、二叉树后序遍历
- 面试题
- 伪代码实现一个链表
- 对链表进行反转(逆置)
- 两个队列生成一个栈
- 前序遍历 / 中序遍历 / 后序遍历
- 冒泡排序、快速排序、二分查找
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
# DRF
-1- 手写一个带参数的装饰器, 并说说在哪用到啦?
-
"""
@auth
def login():pass
login()
"""
等同于
"""
login=auth(login)
login()
"""
- drf的APIView免除csrf token认证!
class APIView(View):
def as_view(cls, **initkwargs):
view = super().as_view(**initkwargs)
return csrf_exempt(view)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
-2- 谈谈你对面向对象的理解?!
- 面向对象中基于 继承+异常处理 来约束子类!! >> drf里有大量的raise
- 面向对象的封装
class Foo:
def __init__(self,name,age):
self.name = name
self.age = age
obj = Foo('dc',18) # 封装 > 将name和age封装到了obj这个对象里!
◎ 在drf源码里,二次封装request时,将Django的request和其它一大堆东西通过__init__都封装到了drf的request中!!
- 反射 Django和drf的dispatch中都反射执行了视图函数!
- 面向对象的继承 注意self就行!
class View:
pass
class APIView(View):
def dispatch(self):
method = getattr(self, 'get')
method()
class GenericApIView(APIView):
serilizer_class = None
def get_seriliser_class(self):
return self.serilizer_class
class ListModelMixin:
def get(self):
ser_class = self.get_seriliser_class()
print(ser_class)
class ListAPIView(ListModelMixin, GenericApIView):
pass
class UserInfoview(ListApIView):
serilizer_class = 111
def get_seriliser_class(self):
return "咩咩"
view = UserInfoview()
view.dispatch()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
-3- 你对ajax请求的了解?
- 发送ajax请求,可给予 $.ajax({})发送!
- 浏览器具有"同源策略的限制",当 "发送Ajax请求"+"出现跨域" 时,浏览器会阻止你获取数据!!
1> 注意两条件 发送Ajax请求 + 出现跨域 , 缺一不可
- <script src="https://cdm.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
跨域了,但该请求是非ajax请求,浏览器不会阻止
- $.ajax({url:'/msg/'})
发送的是ajax请求,但没跨域,浏览器不会阻止
- $.ajax({url:'http://127.0.0.1:8002/json/',type:'GET',success:function(arg){console.log(arg)}})
端口号变了,跨域了 + ajax请求, 浏览器会阻止; console.log(arg)是打印不出来的!!
2> 请求是能发过去的,那边也能正常接收和返回,但返回的被浏览器截止了,你是consle.log打印不出来的!
3> 跨域是分为简单请求(发送一次)和复杂请求(发送两次,第一option预检,第二次发生真正的请求)的.
So,常见的method/请求方法: get、post、put、delete、patch、option!
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
-4- http请求中Content-type请求头 / 请求体数据的编码方式?
json、urlencoded(默认)、formdata(上传文件专用)
- urlencoded request.body和request.POST均有值
- json request.body有值和request.POST中没有值!!
1
2
3
2
3
-5- 基于Django的fbv和cbv都能实现遵循restful规范的接口.
def user(request):
if request.method == "GET":
pass
class Userview(View):
def get(self):
pass
def post(self):
pass
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
-6- 基于drf 框架实现 restful 的 api接口开发.
- 先免除csrf认证
- 版本
- 认证
1.简述drf的认知流程!
- 权限
- 限流
1.简述drf中节流的实现原理以及过程. 匿名用户/非匿名用户 如何实现频率限制? 匿名用IP/非匿名用ID或用户名
- 解析器
- 序列化器
- 分页器
- 路由组件
- 过滤组件
- 视图组件
Q: GenericApIView视图的作用是什么?
A: 该类中写了很多类变量和方法.
相当于提供了一些规则,建议其子类使用固定的方式来进行获取数据等操作! eg:
Class Articleview(GenericAPIView):
queryset = models.User.objects.al1()
def get(self,request,*args,**kwargs):
query = self.get_queryset()
"我们自己写视图类不会直接继承GenericApIView!!因为麻烦,脱了裤子放屁 Emm"
思考: 什么时候用APIView,什么时候用视图类?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
-7- Django中的F查询, Django中如何获取空 QuerySet.
model.User.objects.all().none()
1
-8- 工作中应用drf中的功能进行项目开发! 侧重点..
第一梯队: 视图、序列化器、解析器、渲染器(response)
第二梯队: request对象的封装、版本处理、分页处理
第三梯队: 认证、权限、限流 - 因为很多公司都不会做这些,或者你接手的项目已经把这些写好了!!
1
2
3
2
3
# Flask
-1- Flask与Django有何区别?
Django是一个大而全,集成了很多组件的重武器;
Flask短小精悍,可扩展性强,有很完善的第三方组件,随着项目的开发,Flask就慢慢变成了Django.
写一个复杂的程序,用Django更方便;写一个简单的程序,用Flask更简洁!!
用户请求进来
- Django是传递这个请求,直观体现在视图函数有参数request
- Flask是基于上下文管理的机制将请求放到了某个地方,需要时再去取. (flask的session也放在那了
1
2
3
4
5
6
7
2
3
4
5
6
7
-2- 装饰器
在flask中,编写装饰器时一定要记得加上 @functools.wraps(func) -- 不加则报错 报endpoint重名的错误!
多个装饰器的执行顺序 应用场景:flask的session认证,注-@auth需写在@app.route('/index')下方
1
2
2
-3- cookie、session、jwt -- token
Flask的session是加密的形式保存在浏览器的cookie上!用它必须配置 app.secret_key
1
-4- Django的app和Flask蓝图有何区别?
没啥区别,Django里的app就是Flask里的大蓝图!都是做业务拆分的!
- Django的app是在setting中注册
- Flask的蓝图是通过 app.register_blueprint(one, url_prefix='/one') 来注册的
并且注册时可以加前缀! 这个加前缀有点像Django里的路由分发!
1
2
3
4
2
3
4
-5- 数据库连接池
数据库连接池帮我们维护了多个数据库连接 / 支持多线程
当我们想要连接数据库时,去数据库中申请一个连接,通过这个链接去操作数据库,当操作完后,再将连接刚回数据库连接池!!
使用dbutils来实现数据库连接池!! 类+模块的单例模式 实现!!
若没有数据库连接池,两种情况: 1.有1000个请求就会经历1000个连接的创建和断开,浪费资源 2.用同一个连接,并发来了,也存在问题.
☆ 老板说,写一个简单脚本,将数据库里的数据导入excel中! -- 利于pymsql就可以实现了!因为该需求不存在什么并发.
☆ 若写Flask程序,flask里没有自带ORM,需要用原生的sql,不出意外都要使用数据库连接池!!
1
2
3
4
5
6
7
2
3
4
5
6
7
-6- 说一说面向对象的上下文管理
☆ with上下文管理!! __enter__、__exit__ 数据库连接池没必要用上下文来实现,基于类实现的方案就够用了!!
1