知识点问答
阅读目录
正文
1. 个人方面
1. 先做自我介绍
......
2. 做Python几年了?为什么选择Python?
......
3. 学历?大学什么专业?
......
4. 除了Python以外对其他语言有没有了解?
......
5. 你对Python这门语言的看法?
优点:
- 开发效率高,拥有非常丰富的第三方库。
- 可移植性——可在所有的系统平台上运行。
- 可嵌入性——可以作为脚本嵌入C或C++中
- 可扩展性——可以在部分程序中嵌入C或C++程序,加快运行效率和隐藏算法
缺点:
- 运行速度慢,但这都是相对的
- 代码不能加密,只能以明文形式存在
- 线程不能利用多CPU问题
6. 在学习Python过程中有没有令你影响深刻的事情?
......
2. Python基础部分
1. 字符串、字典、元组、列表常用方法?
- 字符串:strip()、center()、count()、find()、lower()、upper()、join()、split()、index()、replace()、endwith()、startwith()
- 字典:dict.clear()、dict.copy()、dict.get(key, default=None)、dict.has_key(key)、dict.items()、dict.keys()、dict.values()、 dict.setdefault(key, default=None)、dict.update(dict2)、pop(key[,default])
- 列表:list.append(obj)、list.extend(seq)、list.count(obj)、list.index(obj)、list.insert(index, obj)、list.pop(obj=list[-1])、 list.remove(obj)、list.reverse()、list.sort([func])
- 元组:max(tuple)、min(tuple)、len(tuple)、cmp(tuple1, tuple2)、tuple.count(obj)、tuple[1:6]
2. pep8规范?
3. 函数闭包的理解?
当一个内嵌函数引用其外部作用域的变量,我们就会得到一个闭包. 总结一下,创建一个闭包必须满足以下几点:
- 必须有一个内嵌函数
- 内嵌函数必须引用外部函数中的变量
- 外部函数的返回值必须是内嵌函数
一般情况下,函数中的局部变量仅在函数的执行期间可用
闭包的作用:闭包使得局部变量在函数外被访问成为可能。
闭包避免了使用全局变量,此外,闭包允许将函数与其所操作的某些数据(环境)关连起来。
4. Python函数的作用域?
Python 中,一个变量的作用域总是由在代码中被赋值的地方所决定的。
当 Python 遇到一个变量的话他会按照这样的顺序进行搜索:
本地作用域(Local)→当前作用域被嵌入的本地作用域(Enclosing locals)→全局/模块作用域(Global)→内置作用域(Built-in)
5. 函数传入参数时要注意什么?如: func(arg,names=[]):…
定义默认参数要牢记一点:默认参数必须指向不变对象!
6. 什么是装饰器?应用场景?
含义:装饰器本质就是函数,为其它函数添加附加功能
原则:
- 不修改被修饰函数的代码
- 不修改被修饰函数的调用方式
本质:装饰器 = 高阶函数 + 函数嵌套 + 闭包
# 二、写一个支持参数的装饰器 # 不带参数的装饰器 def myfunc(func): def wrapper(*args,**kwargs): return func(*args,**kwargs) return wrapper # 带参数的就是在不带参数的基础上多写一层函数,给内层传值用 def auth('canshu'): def myfunc(func): def wrapper(*args,**kwargs): if canshu: return func(*args,**kwargs) else: pass return wrapper
7. 生成器、迭代器和可迭代对象区别和应用?
生成器:1. 列表生成式的[ ]改为( ) 2. 函数中包含yield 3.生成器可以节省内存 4.生成器就是迭代器的一种
迭代器:可迭代对象执行obj.__iter__()得到的结果就是迭代器对象
#1、为何要有迭代器? 对于序列类型:字符串、列表、元组,我们可以使用索引的方式迭代取出其包含的元素。但对于字典、集合、文件等类型是没有索引的,若还想取出其内部包含的元素,则必须找出一种不依赖于索引的迭代方式,这就是迭代器
可迭代对象:可迭代对象指的是内置有__iter__方法的对象
8. 请一行写出 9*9 乘法表
|
1
|
print('\n'.join([' '.join(['{0}*{1}={2}'.format(x,y,x*y) for x in range(1,y+1)]) for y in range(1,10)])) |
9. 深浅拷贝?
import copy a = [1, 2, 3, 4, ['a', 'b']] # 原始对象 b = a # 赋值,传对象的引用 c = copy.copy(a) # 对象拷贝,浅拷贝 d = copy.deepcopy(a) # 对象拷贝,深拷贝 a.append(5) # 修改对象a a[4].append('c') # 修改对象a中的['a', 'b']数组对象 print('a = ', a) print('b = ', b) print('c = ', c) print('d = ', d) 输出结果: a = [1, 2, 3, 4, ['a', 'b', 'c'], 5] b = [1, 2, 3, 4, ['a', 'b', 'c'], 5] c = [1, 2, 3, 4, ['a', 'b', 'c']] d = [1, 2, 3, 4, ['a', 'b']] # a、b、d都比较好理解,说一下c浅拷贝,拷贝了初始列表中的每一个元素内存地址,固定了元素的个数,不能添加多的元素了,但是当某个元素是可变对象时,还是可以对它操作的
10. 线程、进程和协程?应用?
进程:正在进行的一个过程或者说一个任务。而负责执行任务则是cpu。进程是资源单位。
- python中的多线程无法利用多核优势,如果想要充分地使用多核CPU的资源(os.cpu_count()查看),在python中大部分情况需要使用多进程。
- 与线程不同,进程没有任何共享状态,进程修改的数据,改动仅限于该进程内。
线程:资源执行单位。
- 进程之间是竞争关系,线程之间是协作关系。
- 协程:协程是一种用户态的轻量级线程,即协程是由用户程序自己控制调度的。
# 优点: #1. 协程的切换开销更小,属于程序级别的切换,操作系统完全感知不到,因而更加轻量级 #2. 单线程内就可以实现并发的效果,最大限度地利用cpu # 缺点: #1. 协程的本质是单线程下,无法利用多核,可以是一个程序开启多个进程,每个进程内开启多个线程,每个线程内开启协程 #2. 协程指的是单个线程,因而一旦协程出现阻塞,将会阻塞整个线程
应用:IO密集型(文件IO、网络IO)使用多线程;CPU密集型(大量计算)使用多进程+协程
11. IO多路复用?
.......
12. with 上下文机制原理?
上下文管理器是可以在with语句中使用,拥有__enter__和__exit__方法的对象。
|
1
2
3
4
5
6
7
8
9
10
|
# 简化 try...finally...语句var = manager.__enter__()try: do_something(var)finally: manager.__exit__() # 简化为:with manager as var: do_something(var) |
__enter__方法首先被调用。它可以返回赋给var的值。as部分是可选的:如果它不出现,enter的返回值简单地被忽略。
with语句下的代码被执行。就像try子句,它们或者成功执行到底,或者break,continue或return,或者可以抛出异常。无论哪种情况,该块结束后,__exit__方法被调用。如果抛出异常,异常信息被传递给__exit__
13. Python内存管理?
- 在Python中,小整数[-5,257]和短小的字符,Python都会缓存这些对象,以便重复使用。
- Python维护对象的引用计数,当一个对象的引用计数为零时,Python的GC机制会自动销毁该变量,以便空出该内存地址,释放内存。
- 垃圾回收时,Python不能进行其它的任务。频繁的垃圾回收将大大降低Python的工作效率。
- Python只会在特定条件下,自动启动垃圾回收。
- 当Python运行时,会记录其中分配对象(objectallocation)和取消分配对象(objectdeallocation)的次数。当两者的差值高于某个阈值时,垃圾回收才会启动。
3. 面向对象部分
1. 三大特性以及解释?
继承:继承是一种创建新的类的方式,在python中,新建的类可以继承自一个或者多个父类。
封装:
- 第一层面:创建类和对象会分别创建二者的名称空间,我们只能用类名.或者obj.的方式去访问里面的名字,这本身就是一种封装
- 第二层面:类中把某些属性和方法隐藏起来(或者说定义成私有的),只在类的内部使用、外部无法访问,或者留下少量接口(函数)供外部访问。
多态:向不同的对象发送同一条消息,不同的对象在接收时会产生不同的行为(即方法)。也就是说,每个对象可以用自己的方式去响应共同的消息。所谓消息,就是调用函数,不同的行为就是指不同的实现,即执行不同的函数。
2. 面向对象继承时要注意什么?深度优先和广度优先是什么?
- 注意:继承时子类不会继承父类的__doc__属性,
- 深度优先:一条道找到底。
- 广度优先:左边找到倒数第二个(即使可以直接拿到倒数第一个,但是不拿,然后从右边开始找),不再继续往下找,然后从右边开始向上找,直到找到倒数第一个。
- 注意注意注意:使用super调用的所有属性,都是从MRO列表当前的位置往后找,千万不要通过看代码去找继承关系,一定要看MRO列表
3. 面向对象中的一些特殊方法都记得那些?如,__call__…
__call__:实例对象加( )会执行def __call__:... 方法里边的内容。
__del__:析构方法,当对象在内存中被释放时,自动触发执行。如当 del obj 或者应用程序运行完毕时,执行该方法里边的内容。
__enter__和__exit__:出现with语句,对象的__enter__被触发,有返回值则赋值给as声明的变量;with中代码块执行完毕时执行__exit__里边的内容。
__module__:表示当前操作的对象在那个模块 obj.__module__
__class__ :表示当前操作的对象的类是什么 obj.__class__
__doc__:类的描述信息,该描述信息无法被继承
__str__:改变对象的字符串显示 print函数 --->obj.__str__()
__repr__:改变对象的字符串显示 交互式解释器 --->obj.__repr__()
__format__:自定制格式化字符串
__slots__:一个类变量 用来限制实例可以添加的属性的数量和类型
__setitem__,__getitem,__delitem__:
class Foo: def __init__(self,name): self.name=name def __getitem__(self, item): print(self.__dict__[item]) def __setitem__(self, key, value): self.__dict__[key]=value def __delitem__(self, key): print('del obj[key]时,我执行') self.__dict__.pop(key) def __delattr__(self, item): print('del obj.key时,我执行') self.__dict__.pop(item) f1=Foo('sb') f1['age']=18 f1['age1']=19 del f1.age1 del f1['age'] f1['name']='alex' print(f1.__dict__)
__get__():调用一个属性时,触发
__set__():为一个属性赋值时,触发
__delete__():采用del删除属性时,触发
__setattr__,__delattr__,__getattr__ :
class Foo: x=1 def __init__(self,y): self.y=y def __getattr__(self, item): print('----> from getattr:你找的属性不存在') def __setattr__(self, key, value): print('----> from setattr') # self.key=value #这就无限递归了,你好好想想 # self.__dict__[key]=value #应该使用它 def __delattr__(self, item): print('----> from delattr') # del self.item #无限递归了 self.__dict__.pop(item) #__setattr__添加/修改属性会触发它的执行 f1=Foo(10) print(f1.__dict__) # 因为你重写了__setattr__,凡是赋值操作都会触发它的运行,你啥都没写,就是根本没赋值,除非你直接操作属性字典,否则永远无法赋值 f1.z=3 print(f1.__dict__) #__delattr__删除属性的时候会触发 f1.__dict__['a']=3#我们可以直接修改属性字典,来完成添加/修改属性的操作 del f1.a print(f1.__dict__) #__getattr__只有在使用点调用属性且属性不存在的时候才会触发 f1.xxxxxx
4. 如何理解元类
- 元类是类的类,是类的模板
- 元类是用来控制如何创建类的,正如类是创建对象的模板一样,而元类的主要目的是为了控制类的创建行为
- 元类的实例化的结果为我们用class定义的类,正如类的实例为对象(f1对象是Foo类的一个实例,Foo类是 type 类的一个实例)
- type是python的一个内建元类,用来直接控制生成类,python中任何class定义的类其实都是type类实例化的对象
5. __new__和 __init__ 方法?
- __new__:生成实例
- __init__:生成实例的属性
6. 单例模式 -----------
- 单例模式提供了这样一个机制,确保类有且只有一个特定类型的对象,并提供全局访问点。
- 适用情形:日志记录、数据库操作、打印机后台处理程序等,上述程序运行过程中只生成一个实例,避免对同一资源产生相互冲突的请求。
- 传送门
7. staticmethod、classmethod,property
- @property:@property + return 把公共函数变成数据属性,实例调用的调用的时候去掉小括号,像调用普通属性一样调用它。
- @staticmethod:是一种普通函数,位于类定义的命名空间中,只是名义上归属类管理,不能调用类变量、实例变量,只是类的工具包。
- @classmethod:专门供类使用的方法,类调用的时候传cls参数,同时该方法也可以被实例调用。
8. 经典类和新式类
- Python 2.x中默认都是经典类,只有显式继承了object才是新式类
- Python 3.x中默认都是新式类,不必显式的继承object
- 在多继承中,新式类采用广度优先搜索,而旧式类是采用深度优先搜索。
- 继承搜索的顺序发生了改变,经典类多继承属性搜索顺序: 先深入继承树左侧,再返回,开始找右侧;新式类多继承属性搜索顺序:先水平搜索,然后再向上移动
- 新式类对象可以直接通过__class__属性获取自身类型:type
- 新式类增加了__slots__内置属性, 可以把实例属性的种类锁定到__slots__规定的范围之中
4. 数据库部分
1. 数据库引擎?
- 数据库引擎是用于存储、处理和保护数据的核心服务。利用数据库引擎可控制访问权限并快速处理事务,从而满足企业内大多数需要处理大量数据的应用程序的要求。使用数据库引擎创建用于联机事务处理或联机分析处理数据的关系数据库。这包括创建用于存储数据的表和用于查看、管理和保护数据安全的数据库对象(如索引、视图和存储过程)。
- INNODB和BERKLEYDB(BDB)数据库引擎都是造就MYSQL灵活性的技术的直接产品,这项技术就是MYSQL+API。在使用MYSQL的时候,你所面对的每一个挑战几乎都源于ISAM和MYISAM数据库引擎不支持事务处理也不支持外来键。尽管要比ISAM和MYISAM引擎慢很多,但是INNODB和BDB包括了对事务处理和外来键的支持,这两点都是前两个引擎所没有的。如前所述,如果你的设计需要这些特性中的一者或者两者,那你就要被迫使用后两个引擎中的一个了。
2. 数据库锁?
- 当并发事务同时访问一个资源时,有可能导致数据不一致,因此需要一种机制来将数据访问顺序化,以保证数据库数据的一致性。
- 共享锁和排它锁。
- 共享锁(S)表示对数据进行读操作。因此多个事务可以同时为一个对象加共享锁。(如果试衣间的门还没被锁上,顾客都能够同时进去参观)
- 产生共享锁的sql:select * from ad_plan lock in share mode;
- 排他锁表示对数据进行写操作。如果一个事务对对象加了排他锁,其他事务就不能再给它加任何锁了。(某个顾客把试衣间从里面反锁了,其他顾客想要使用这个试衣间,就只有等待锁从里面给打开了)
- 产生排他锁的sql: select * from ad_plan for update;
3. 设计数据库:会议室预定
4. 设计数据库:员工、部门、角色;
1. 查询 “IT”部门所有人
|
1
|
select name from IT |
2. 查询 每个部门 的员工数量?
|
1
|
select count(*) from IT group by nid |
3. 查询 每个部门 年龄不等于 18的人
|
1
|
select name from IT where age != 18 |
4. 查询部门人数不满 5 的部门?
5. 数据库优化方案?
- 1.对查询进行优化,要尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引。
- 2.应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描。
- 3.应尽量避免在 where 子句中使用 != 或 <> 操作符,否则将引擎放弃使用索引而进行全表扫描。
- 4.应尽量避免在 where 子句中使用 or 来连接条件,如果一个字段有索引,一个字段没有索引,将导致引擎放弃使用索引而进行全表扫描。
- 5.in 和 not in 也要慎用,否则会导致全表扫描
6. 数据库索引以及注意点?
- 索引:使用索引可快速访问数据库表中的特定信息。索引是对数据库表中一列或多列的值进行排序的一种结构。类似于书籍的目录。
- 普通索引:仅加速查询
- 唯一索引:加速查询 + 列值唯一(可以有null)
- 主键索引:加速查询 + 列值唯一 + 表中只有一个(不可以有null)
- 组合索引:多列值组成一个索引,专门用于组合搜索,其效率大于索引合并
- 全文索引:对文本的内容进行分词,进行搜索
- 避免使用select * - count(1)或count(列) 代替 count(*) - 创建表时尽量时 char 代替 varchar - 表的字段顺序固定长度的字段优先 - 组合索引代替多个单列索引(经常使用多个条件查询时) - 尽量使用短索引 - 使用连接(JOIN)来代替子查询(Sub-Queries) - 连表时注意条件类型需一致 - 索引散列值(重复少)不适合建索引,例:性别不适合
7. 什么情况下建索引?
- 数据库表中添加索引后确实会让查询速度起飞,但前提必须是正确的使用索引来查询,如果以错误的方式使用,则即使建立索引也会不奏效。
8. 数据库索引种类?
- 普通索引:仅加速查询
- 唯一索引:加速查询 + 列值唯一(可以有null)
- 主键索引:加速查询 + 列值唯一 + 表中只有一个(不可以有null)
- 组合索引:多列值组成一个索引,专门用于组合搜索,其效率大于索引合并
- 全文索引:对文本的内容进行分词,进行搜索
- 索引合并,使用多个单列索引组合搜索
- 覆盖索引,select的数据列只用从索引中就能够取得,不必读取数据行,换句话说查询列要被所建的索引覆盖
9. delete和truncate区别?
10. 数据库中出现乱码?如何解决?
- 出现乱码时,可以使用语句 show variables like 'character%'; 来查看当前数据库的相关编码集。
- 这时只需要将下的默认编码 default-character-set=utf8 改为 default-character-set=gbk ,重新启动 MySQL 服务即可。
- 传送门
11. 执行计划和慢日志?
- 执行计划:explain + 查询SQL - 用于显示SQL执行信息参数,根据参考信息可以进行SQL优化
- 慢日志:它用来记录在MySQL中响应时间超过阀值的语句,具体指运行时间超过long_query_time值的SQL,则会被记录到慢查询日志中
- 慢日志查询:mysqldumpslow -s at -a /usr/local/var/mysql/MacBook-Pro-3-slow.log
12. 数据库读写分离?
MySQL读写分离基本原理是让master数据库处理写操作,slave数据库处理读操作。
MySQL读写分离能提高系统性能的原因在于:
- 物理服务器增加,机器处理能力提升。拿硬件换性能。
- 主从只负责各自的读和写,极大程度缓解X锁和S锁争用。
- slave可以配置myiasm引擎,提升查询性能以及节约系统开销。
- master直接写是并发的,slave通过主库发送来的binlog恢复数据是异步。
- slave可以单独设置一些参数来提升其读的性能。
- 增加冗余,提高可用性。
13. 用过什么ORM框架?
- SQLAlchemy是Python编程语言下的一款ORM框架,该框架建立在数据库API之上,使用关系对象映射进行数据库操作,简言之便是:将对象转换成SQL,然后使用数据API执行SQL并获取执行结果。
- QLAlchemy本身无法操作数据库,其必须以来pymsql等第三方插件,Dialect用于和数据API进行交流,根据配置文件的不同调用不同的数据库API,从而实现对数据库的操作。
- 传送门
14. ORM缺点和优点?
使用 orm 的好处主要是:
- 快速开发
- 可以对接多种类型数据库,当项目大了更容易管理,如果你的项目比较小,完全可以不用
- 方便的使用面向对象,语句清晰
- 防注入『这个其实不算ORM的核心,因为比如Phalcon的SQL形式写法也可以防注入』
- 方便动态构造语句,对于不同的表的相同操作采用多态实现更优雅
- 一定程度方便重构数据层『比如改表名,字段名等』
- 设置钩子函数
缺点:
- 开发者不能明确 sql 的内容,使 dba 有时候不好办,反观有限数量的裸 sql,dba 很容易 review;
- 虽然ORM对简单的数据库操作可以很好实现,但一旦涉及到关联查询,修改,就复杂了
- 本来是一行sql可以完成的代码,orm后多了很多代码,而且效率也大打折扣
- 不太容易处理复杂查询语句
- 性能较直接用SQL差
5. 前端部分
1. 前端是自己写?还是有前端开发?
......
2. 了解的前端框架?
React、Vue
3. js的面向对象有没有了解?
- Javascript是一种基于对象(object-based)的语言,你遇到的所有东西几乎都是对象。但是,它又不是一种真正的面向对象编程(OOP)语言,因为它的语法中没有class(类)。
4. js作用域?
- 在JavaScript中,用var申明的变量实际上是有作用域的。
- 如果一个变量在函数体内部申明,则该变量的作用域为整个函数体,在函数体外不可引用该变量。
- 如果两个不同的函数各自申明了同一个变量,那么该变量只在各自的函数体内起作用。换句话说,不同函数内部的同名变量互相独立,互不影响。
- 由于JavaScript的函数可以嵌套,此时,内部函数可以访问外部函数定义的变量,反过来则不行。
- 如果内部函数和外部函数的变量名重名。
- JavaScript的函数在查找变量时从自身函数定义开始,从“内”向“外”查找。如果内部函数定义了与外部函数重名的变量,则内部函数的变量将“屏蔽”外部函数的变量。
- JavaScript的函数定义有个特点,它会先扫描整个函数体的语句,把所有申明的变量“提升”到函数顶部
- JavaScript的这一怪异的“特性”,我们在函数内部定义变量时,请严格遵守“在函数内部首先申明所有变量”这一规则。最常见的做法是用一个var申明函数内部用到的所有变量
- 不在任何函数内定义的变量就具有全局作用域。实际上,JavaScript默认有一个全局对象window,全局作用域的变量实际上被绑定到window的一个属性
- JavaScript实际上只有一个全局作用域。任何变量(函数也视为变量),如果没有在当前函数作用域中找到,就会继续往上查找,最后如果在全局作用域中也没有找到,则报ReferenceError错误
- JavaScript的变量作用域实际上是函数内部,我们在for循环等语句块中是无法定义具有局部作用域的变量
5. js中的this要注意什么?
- 在函数中:this 通常是一个隐含的参数。
- 在函数外(顶级作用域中):在浏览器中this 指的是全局对象。
- 传递到eval()中的字符串:如果eval()是被直接调用的,this 指的是当前对象;如果eval()是被间接调用的,this 就是指全局对象。
6. 跨域是什么?解决方案?
- 解决两个安全域之间的信息传递,这个就叫做CDS——跨域解决方案
- 解决方案:CORS和JSONP
- CORS是一个W3C标准,全称是"跨域资源共享"(Cross-origin resource sharing)。
- 它允许浏览器向跨源服务器,发出XMLHttpRequest请求,从而克服了AJAX只能同源使用的限制。
- 整个CORS通信过程,都是浏览器自动完成,浏览器一旦发现AJAX请求跨源,就会自动添加一些附加的头信息,有时还会多出一次附加的请求,但用户不会有感觉。
- JSONP 利用img标签的src属性获取数据,只能发生get请求。
6. Web框架部分
1. Http协议
2. 列举Http请求方法?
- GET 请求指定的页面信息,并返回实体主体。
- HEAD 类似于get请求,只不过返回的响应中没有具体的内容,用于获取报头
- POST 向指定资源提交数据进行处理请求(例如提交表单或者上传文件)。数据被包含在请求体中。POST请求可能会导致新的资源的建立和/或已有资源的修改。
- PUT 从客户端向服务器传送的数据取代指定的文档的内容。
- DELETE 请求服务器删除指定的页面。
- CONNECT HTTP/1.1协议中预留给能够将连接改为管道方式的代理服务器。
- OPTIONS 允许客户端查看服务器的性能。
- TRACE 回显服务器收到的请求,主要用于测试或诊断。
3. 列举Http常用请求头?
4. 列举Http状态码?
- 200:请求成功,浏览器会把响应体内容(通常是html)显示在浏览器中;
- 302:重定向,当响应码为302时,表示服务器要求浏览器重新再发一个请求,服务器会发送一个响应头Location,它指定了新请求的URL地址;
- 304:(未修改)自从上次请求后,请求的网页未修改过。服务器返回此响应时,不会返回网页内容
- 404:请求的资源没有找到,说明客户端错误的请求了不存在的资源;
- 500:请求资源找到了,但服务器内部出现了错误;
5. Django请求生命周期?
- Django的请求生命周期是指当用户在浏览器上输入url到用户看到网页的这个时间段内,Django后台所发生的事情。
- 1.当用户在浏览器中输入url时,浏览器会生成请求头和请求体发给服务端请求头和请求体中会包含浏览器的动作(action),这个动作通常为get或者post,体现在url之中.
- 2.url经过Django中的wsgi,再经过Django的中间件,最后url到过路由映射表,在路由中一条一条进行匹配,一旦其中一条匹配成功就执行对应的视图函数,后面的路由就不再继续匹配了.
- 3. 视图函数根据客户端的请求查询相应的数据.返回给Django,然后Django把客户端想要的数据做为一个字符串返回给客户端.
- 4. 客户端浏览器接收到返回的数据,经过渲染后显示给用户.
6. 什么是wsgi?
- Web服务器网关接口。具体的来说,WSGI是一个规范,定义了Web服务器如何与Python应用程序进行交互,使得使用Python写的Web应用程序可以和Web服务器对接起来。
- 传送门
7. Django
1. Django信号作用?应用?
- Django中提供了“信号调度”,用于在框架执行操作时解耦。通俗来讲,就是一些动作发生的时候,信号允许特定的发送者去提醒一些接受者。
- 对于Django内置的信号,仅需注册指定信号,当程序执行相应操作时,自动触发注册函数:
2. 有没有用过单元测试?
- Django测试框架非常简单,首选方法是使用python标准库中的unittest模块。
- 类名为django.test.TestCase,继承于python的unittest.TestCase。
- 传送门
3. Django 中间件作用?应用?
- 在django中,中间件其实就是一个类,在请求到来和结束后,django会根据自己的规则在合适的时机执行中间件中相应的方法。
- 在django项目的settings模块中,有一个 MIDDLEWARE_CLASSES 变量,其中每一个元素就是一个中间件
- 应用:对所有请求或一部分请求做批量处理
4. Django处理并发?
5. FBV和CBV
- CBV:views.类名.as_view()
- FBV:views.函数名
6. cookie和session区别以及实现原理?
7. 你怎么理解ORM ORM相关操作
- - 操作数据库简单
- - 创建数据库 和修改数据库简单
- - 速度 比 原生SQL慢 对象和类需要转换成SQL运行
1. selected_related和prefetch_related是什么?
- prefetch_related()和select_related()的设计目的很相似,都是为了减少SQL查询的数量,但是实现的方式不一样。
- select_related()通过JOIN语句,在SQL查询内解决问题。
- prefetch_related()分别查询每个表,然后用Python处理他们之间的关系。
- 传送门
2. Q和F
- F:models.Tb1.objects.update(num=F('num')+1)
- Q:Q(Q(nid=8) | Q(nid__gt=10)) & Q(caption='root')
3. queryset的常用方法
4. 用户、部门、角色:
1. 查询年龄大于18的人
2. 查询年龄不等于18的人
3. 查询 IT部 和 运维部的所有人?
4. 查询 IT部 或 运维部的所有人?
5. 查询角色是 “管理员” 的所有人?
6. values/values_list
浙公网安备 33010602011771号