一、简述面向对象中__new__和__init__区别
__init__是初始化方法,创建对象后,就立刻被默认调用了,可接收参数.
1、__new__至少要有一个参数cls,代表当前类,此参数在实例化时由Python解释器自动识别
2、__new__必须要有返回值,返回实例化出来的实例,这点在自己实现__new__时要特别注意,可以return父类(通过super(当前类名, cls))__new__出来的实例,或者直接是object的__new__出来的实例
3、__init__有一个参数self,就是这个__new__返回的实例,__init__在__new__的基础上可以完成一些其它初始化的动作,__init__不需要返回值
4、如果__new__创建的是当前类的实例,会自动调用__init__函数,通过return语句里面调用的__new__函数的第一个参数是cls来保证是当前类实例,如果是其他类的类名,;那么实际创建返回的就是其他类的实例,其实就不会调用当前类的__init__函数,也不会调用其他类的__init__函数。
class A: def __init__(self): print("这是__init__方法", self) def __new__(cls): print("这是cls的id", id(cls)) print("这是__new__方法", object.__new__(cls)) return object.__new__(cls) A() print("这是类A的ID", id(A)) """ 这是cls的id 22720808 这是__new__方法 <__main__.A object at 0x7fed0b563198> 这是__init__方法 <__main__.A object at 0x7fed0b563198> 这是类A的ID 22720808 """
二、简述with方法打开处理文件帮我们做了什么?
f = open("./1.txt", "wb") try: f.write("hello world") except: pass finally: f.close()
打开文件在进行读写的时候可能会出现一些异常状况,如果按照常规的f.open
写法,我们需要try,except,finally,做异常判断,并且文件最终不管遇到什么情况,都要执行finally f.close()关闭文件,with方法帮我们实现了finally中f.close
三、简述Django的ORM
ORM,全拼Object-Relation Mapping,意为对象-关系映射
实现了数据模型与数据库的解耦,通过简单的配置就可以轻松更换数据库,而不需要修改代码只需要面向对象编程,orm操作本质上会根据对接的数据库引擎,翻译成对应的sql语句,所有使用Django开发的项目无需关心程序底层使用的是MySQL、Oracle、sqlite....,如果数据库迁移,只需要更换Django的数据库引擎即可
ORM优点:
1.ORM框架降低了学习门槛,一个对sql语句并不熟悉的开发人员也可以很容易通过简易的ORM框架Api进行数据库的操作。
3.一定程度上提高了程序的响应速度。
ORM缺点:
ORM框架的弊端也很明显,框架会自动生成Sql语句,所有场景的sql语句都是同一套模板,难以自动针对场景对sql语句进行良好的优化,某种场景下很容易生成执行很慢的sql语句。如果让DBA看到这样的执行sql,必定引来抓狂崩溃。
ORM框架只是为了满足绝大多数的场景而生的,特殊需要优化sql的场景下,我们完全可以直接使用驱动手动执行sql或使用ORM框架内提供的sql语句api进行自定义sql语句。
四、举例说明异常模块中try except else finally的相关意义
try..except..else没有捕获到异常,执行else语句
try..except..finally不管是否捕获到异常,都执行finally语句
try: num = 100 print(num) except NameError as errorMsg: print("产生错误了:%s" % errorMsg) else: print("没有捕获到异常,则执行该语句") try: num = 100 print(num) except NameError as errorMsg: print("产生错误了:%s" % errorMsg) finally: print("不管是否捕获到异常,都执行该句")
---------------------------------
100
没有捕获到异常,则执行该语句
100
不管是否捕获到异常,都执行该句
五、提高python运行效率的方法
1、使用生成器,因为可以节约大量内存
2、循环代码优化,避免过多重复代码的执行
3、核心模块用Cython PyPy等,提高效率
4、多进程、多线程、协程
5、多个if elif条件判断,可以把最有可能先发生的条件放到前面写,这样可以减少程序判断的次数,提高效率
六、分别从前端、后端、数据库阐述web项目的性能优化
前端优化:
1、减少http请求、例如制作精灵图
2、html和CSS放在页面上部,javascript放在页面下面,因为js加载比HTML和Css加载慢,所以要优先加载html和css,以防页面显示不全,性能差,也影响用户体验差
后端优化:
1、缓存存储读写次数高,变化少的数据,比如网站首页的信息、商品的信息等。应用程序读取数据时,一般是先从缓存中读取,如果读取不到或数据已失效,再访问磁盘数据库,并将数据再次写入缓存。
2、异步方式,如果有耗时操作,可以采用异步,比如celery
3、代码优化,避免循环和判断次数太多,如果多个if else判断,优先判断最有可能先发生的情况
数据库优化:
1、如有条件,数据可以存放于redis,读取速度快
2、建立索引、外键等
七、举例sort和sorted对列表排序
sort在原列表修改,修改原列表,sorted不修改原列表
list = [0,-1,3,-10,5,9] list.sort(reverse=False) print("list.sort在list基础上修改,无返回值",list) #list.sort在list基础上修改,无返回值 [-10, -1, 0, 3, 5, 9] list = [0,-1,3,-10,5,9] res = sorted(list,reverse=False) print("sorted有返回值是新的list",list) #sorted有返回值是新的list [0, -1, 3, -10, 5, 9] print("返回值",res) #返回值 [-10, -1, 0, 3, 5, 9]
八、用两种方法去重空格 拼接(join) 替换(replace)
str = 'hello world ha ha' list= str.split(" ") #按空格切割 res1 = "".join(list) print(res1) res2 = str.replace(" ","") print(res2) #helloworldhaha
九、python垃圾回收机制
python垃圾回收主要以引用计数为主,标记-清除和分代清除为辅的机制,其中标记-清除和分代回收主要是为了处理循环引用的难题。
十、HTTP请求中get和post区别
1、GET请求是通过URL直接请求数据,数据信息可以在URL中直接看到,比如浏览器访问;而POST请求是放在请求头中的,我们是无法直接看到的;
2、GET提交有数据大小的限制,一般是不超过1024个字节,而这种说法也不完全准确,HTTP协议并没有设定URL字节长度的上限,而是浏览器做了些处理,所以长度依据浏览器的不同有所不同;POST请求在HTTP协议中也没有做说明,一般来说是没有设置限制的,但是实际上浏览器也有默认值。总体来说,少量的数据使用GET,大量的数据使用POST。
3、GET请求因为数据参数是暴露在URL中的,所以安全性比较低,比如密码是不能暴露的,就不能使用GET请求;POST请求中,请求参数信息是放在请求头的,所以安全性较高,可以使用。在实际中,涉及到登录操作的时候,尽量使用HTTPS请求,安全性更好。
十一、python中生成随机整数、随机小数、0--1之间小数方法
随机整数:random.randint(a,b),生成区间内的整数
随机小数:习惯用numpy库,利用np.random.randn(5)生成5个随机小数
0-1随机小数:random.random(),括号中不传参
十二、数据表student有id,name,score,city字段,其中name中的名字可有重复,需要消除重复行,请写sql语句
select distinct name from student
十三、s = "ajldjlajfdljfddd",去重并从小到大排序输出"adfjl"
s = "ajldjlajfdljfddd" s_set = set(s) #转集合 s_list = list(s_set) #转列表 s = sorted(s_list) #列表排序 res = "".join(s) #拼接 print(res) #adfjl
十四、[[1,2],[3,4],[5,6]]一行代码展开该列表,得出[1,2,3,4,5,6]
list1 = [[1,2],[3,4],[5,6]] list = [j for i in list1 for j in i] print(list) #[1, 2, 3, 4, 5, 6]
list2 = [[1,2],[3,4],[5,6]] import numpy as np list = np.array(list2).flatten().tolist() print(list) #[1, 2, 3, 4, 5, 6]
十五、举例说明zip()函数用法
zip()函数在运算时,会以一个或多个序列(可迭代对象)做为参数,返回一个元组的列表。同时将这些序列中并排的元素配对。
zip()参数可以接受任何类型的序列,同时也可以有两个以上的参数;当传入参数的长度不同时,zip能自动以最短序列长度为准进行截取,获得元组。
a = [1,2] b = [3,4] res = [i for i in zip(a,b)] print(res) #[(1, 3), (2, 4)] a = (1,2) b = (3,4) res = [i for i in zip(a,b)] print(res) #[(1, 3), (2, 4)] a = "ab" b = "xyz" res = [i for i in zip(a,b)] print(res) #[('a', 'x'), ('b', 'y')]
十六、求三个方法打印结果
def fn(k,v,dic={}):
dic[k]=v
print(dic)
fn("one",1)直接将键值对传给字典;
fn("two",2)因为字典在内存中是可变数据类型,所以指向同一个地址,传了新的额参数后,会相当于给字典增加键值对
fn("three",3,{})因为传了一个新字典,所以不再是原先默认参数的字典
def fn(k,v,dic={}): dic[k]=v print(dic) fn("one",1) #{"one":1} fn("two",2) #{'one': 1, 'two': 2} fn("three",3,{}) #{'three': 3}
十七、简述同源策略
同源策略需要同时满足以下三点要求:
1)协议相同
2)域名相同
3)端口相同
http:www.test.com与https:www.test.com 不同源——协议不同
http:www.test.com与http:www.admin.com 不同源——域名不同
http:www.test.com与http:www.test.com:8081 不同源——端口不同
只要不满足其中任意一个要求,就不符合同源策略,就会出现“跨域”
十八、IOError、AttributeError、ImportError、IndentationError、IndexError、KeyError、SyntaxError、NameError分别代表什么异常
IOError:输入输出异常
AttributeError:试图访问一个对象没有的属性
ImportError:无法引入模块或包,基本是路径问题
IndentationError:语法错误,代码没有正确的对齐
IndexError:下标索引超出序列边界
KeyError:试图访问你字典里不存在的键
SyntaxError:Python代码逻辑语法出错,不能执行
NameError:使用一个还未赋予对象的变量
十九、python字典和json字符串相互转化方法
json.dumps()字典转json字符串,json.loads()json转字典
import json dic = {"name":"zs"} res = json.dumps(dic) print(res,type(res)) #{"name": "zs"} <class 'str'> ret = json.loads(res) print(ret,type(ret)) #{'name': 'zs'} <class 'dict'>
二十、列举3条以上PEP8编码规范
1、顶级定义之间空两行,比如函数或者类定义。
2、方法定义、类定义与第一个方法之间,都应该空一行
3、三引号进行注释
4、使用Pycharm、Eclipse一般使用4个空格来缩进代码