疑难杂症汇总

一、简述面向对象中__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进行数据库的操作。

2.提高了开发效率,ORM使我们减少很多繁琐重复的工作量,让我们的注意力集中在实现业务上。

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个空格来缩进代码

原文地址:https://www.cnblogs.com/maplethefox/p/11439030.html