本人在网上搜集的python面试题,但是没有答案,自己搜集并回答,现分享给大家,望各路大佬提出批评纠正,完善!!!
1.代码中要修改不可变数据会出现什么问题?抛出什么异常?
代码不会正常运行,抛出TyprError异常
2.模块和包是什么?
在python中,模块是搭建程序的一种方式。每一个python代码文件都是一个模块,并可以引用其他的模块,比如对象和属性。
一个包,含许多python代码的文件夹是一个包,一个包可以包含模块和子文件夹。
3.有1、2、3、4个数字,能组成多少个互不相同且无重复数字的三位数?都是多少?
def threenum():
count = 0 # 计数
nums = [] # 初始化
for i in range(1, 5): # 百位循环
for j in range(1, 5): # 十位循环
for K in range(1, 5): # 个位循环
if (i != j) and (i != K) and (j != K): # 判断不重复的三个数
num = 100*i+10*j+K
count += 1 # 累加
if num not in nums:
nums.append(num) # 添加到数组
return count, nums
if __name__ == '__main__':
print(threenum())
-------------------------------------------------------------------------
(24, [123, 124, 132, 134, 142, 143, 213, 214, 231, 234, 241, 243, 312, 314, 321, 324, 341, 342, 412, 413, 421, 423, 431, 432])
4.输入某年某月某日,判断这一天是这一年的第几天?
方法一:
import datetime
year = int(input("请输入4位数的年份:\n"))
month = int(input("请输入月份:\n"))
day = int(input("请输入当月哪一天:\n"))
targetDay = datetime.date(year, month, day)
dayCount = targetDay - datetime.date(targetDay.year - 1, 12, 31)
print("%s是%s年的第%s天." % (targetDay, targetDay.year, dayCount))
方法二:
# 特殊情况,闰年且输入月份大于2时需考虑多加一天
# 用来输入年、月、日的,并将它们转换成数字,赋值给不同的变量
year = int(input('请输入年:\n'))
month = int(input('请输入月:\n'))
day = int(input('请输入日:\n'))
# 除了二月外,其余的上个月月底是今天的第几天
months = (0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334)
# 用月来判断,如果大于0,小于等于12,得到上个月月底是今年的第几天
if 0 < month <= 12:
sum = months[month - 1]
else:
print('填写的日期错误')
# 再加上这个月的天数,就得到了是今年的第几天
sum += day
leap = 0
# 通过判断是否是瑞年,考虑二月那一天是否加1:
# 如果是闰年,并且输入的月份大于2,就需要将天数加1,因为闰年的2月是29天
if (year % 400 == 0) or ((year % 4 == 0) and (year % 100 != 0)):
leap = 1
if (leap == 1) and (month > 2):
sum += 1
print("这是今年的第%d天" %sum)
方法三:
year = int(input("Please enter the years:"))
month = int(input("Please enter the months(1-12):"))
day = int(input("Please enter the days(1-31):"))
days = [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365]
if year % 4 == 0 and year % 100 != 0:
if month > 2:
totaldays = days[month - 1] + day + 1
else:
totaldays = days[month - 1] + day
else:
totaldays = days[month - 1] + day
print("你输入的日期是:", year, "年", month, "月", day, '日', ",是今年的第", totaldays, "天!")
5.写出常用的bootstrap的样式。
1、靠右对齐: 只需要添加样式类pull-right即可!
回到页面顶部:只需添加href="#top"即可!
2、<pre></pre>和其类.pre-scrollable(整块突出和设置滚动条)
<pre>元素一般用于显示大块的代码,并保证原有格式不变。但有时候代码太多,而且不想让其占有太大的页面篇幅,就想控制代码块的大小。Bootstrap也考虑到这一点,你只需要在pre标签上添加类名“.pre-scrollable”,就可以控制代码块区域最大高度为340px,一旦超出这个高度,就会在Y轴出现滚动条。
3、强调文章里的某个字眼:<code>btn</code>
4、有时候我们需要将表单的控件都在一行内显示,在Bootstrap框架中实现这样的表单效果是轻而易举的,你只需要添加类名“form-inline”即可。
5、文本强调样式:
.text-muted:提示,使用浅灰色(#999)
.text-primary:主要,使用蓝色(#428bca)
.text-success:成功,使用浅绿色(#3c763d)
.text-info:通知信息,使用浅蓝色(#31708f)
.text-warning:警告,使用黄色(#8a6d3b)
.text-danger:危险,使用褐色(##a94442)
6.什么是响应式布局?
一个网站能够兼容多个终端
7.请通过jQuery发送ajax请求
$.ajax({
type: 'POST',
url: "http://xxx/yyy/zzz/sendVerifyCode",
data:{
phoneNo:$(".tel").val()
},
success: function(data){
$.toast("发送成功", "text")
},
error: function(){
$.toast("发送失败", "text")
}
})
8.JavaScript与this相关的面试题
name = 'harry';
info = {
name:'alex',
age:123,
func:function(){
console.log(this.name);
}
}
info.func()
name = 'Harry';
info = {
name:'alex',
age:123,
func:function(){
console.log(this.name);
function f1(){
console.log(this.name);
}
f1()
}
}
info.func()
name = 'Harry';
info = {
name:'alex',
age:123,
func:function(){
console.log(this.name);
(function(){
console.log(this.name);
})()
}
}
info.func()
name = 'Harry';
info = {
name:'alex',
age:123,
func:function(){
console.log(this.name);
var xxx = this;
(function(){
console.log(xxx.name);
})()
}
}
info.func()
9.什么是跨域?如何解决?
当一个请求url的协议、域名、端口三者之间任意一个与当前页面url不同即为跨域
跨域解决方法:
【1】设置document.domain解决无法读取非同源网页的 Cookie问题
【2】跨文档通信 API:window.postMessage()
【3】JSONP
【4】CORS
10. 简述你对Http协议的理解?
Http协议则是一种应用层协议
http是超文本传输协议,详细的制定了万维网服务器与客户端间的数据传输的通信规则
http是一种超文本传输协议,传输的数据都是未加密的,也就是显示在明面上的,是现在互联网上应用最为广泛的一种网络协议,相对来说不太安全,但是所需成本很小。http一般的端口号为80.
11. 简述你对Https协议的理解?
https则是具有安全性的ssl加密传输协议
8. 列举常见的http请求头及作用?
Accept
Accept 头字段用于指出客户端程序(通常是浏览器)
9. 列举常见的http请求方法及作用?
HTTP请求的方法:
HTTP/1.1协议中共定义了八种方法(有时也叫“动作”),来表明Request-URL指定的资源不同的操作方式
1、OPTIONS
返回服务器针对特定资源所支持的HTTP请求方法,也可以利用向web服务器发送‘*’的请求来测试服务器的功能性
2、HEAD
向服务器索与GET请求相一致的响应,只不过响应体将不会被返回。这一方法可以再不必传输整个响应内容的情况下,就可以获取包含在响应小消息头中的元信息。
3、GET
向特定的资源发出请求。它本质就是发送一个请求来取得服务器上的某一资源。资源通过一组HTTP头和呈现数据(如HTML文本,或者图片或者视频等)返回给客户端。GET请求中,永远不会包含呈现数据。
4、POST
向指定资源提交数据进行处理请求(例如提交表单或者上传文件)。数据被包含在请求体中。POST请求可能会导致新的资源的建立和/或已有资源的修改。 Loadrunner中对应POST请求函数:web_submit_data,web_submit_form
5、PUT
向指定资源位置上传其最新内容
6、DELETE
请求服务器删除Request-URL所标识的资源
7、TRACE
回显服务器收到的请求,主要用于测试或诊断
8、CONNECT
HTTP/1.1协议中预留给能够将连接改为管道方式的代理服务器。
注意:
1)方法名称是区分大小写的,当某个请求所针对的资源不支持对应的请求方法的时候,服务器应当返回状态码405(Mothod Not Allowed);当服务器不认识或者不支持对应的请求方法时,应返回状态码501(Not Implemented)。
2)HTTP服务器至少应该实现GET和HEAD/POST方法,其他方法都是可选的,此外除上述方法,特定的HTTP服务器支持扩展自定义的方法。
10. 列举常见的http响应状态码。
```
下面常见的http状态码:
100:这个状态码是告诉客户端应该继续发送请求,这个临时响应是用来通知客户端的,部分的请求服务器已经接受,但是客户端应继续发送求请求的剩余部分,如果请求已经完成,就忽略这个响应,而且服务器会在请求完成后向客户发送一个最终的结果
200:这个是最常见的http状态码,表示服务器已经成功接受请求,并将返回客户端所请求的最终结果
202:表示服务器已经接受了请求,但是还没有处理,而且这个请求最终会不会处理还不确定
204:服务器成功处理了请求,但没有返回任何实体内容 ,可能会返回新的头部元信息
301:客户端请求的网页已经永久移动到新的位置,当链接发生变化时,返回301代码告诉客户端链接的变化,客户端保存新的链接,并向新的链接发出请求,已返回请求结果
404:请求失败,客户端请求的资源没有找到或者是不存在
500:服务器遇到未知的错误,导致无法完成客户端当前的请求。
503:服务器由于临时的服务器过载或者是维护,无法解决当前的请求,以上http状态码是服务器经常返回的状态代码,用户只能通过浏览器的状态了解服务器是否正常运行,一般除了错误的状态码,都不会看到服务器的状态码的,新SEOer你们了解到了吗?内容编辑来自51特色购SEO优化人员,想了解更过状态码的知识可以加我好友,一起相互交流学习
```
11. http中connections:keep-alive
的请求头的作用?
```
Connection 头(header) 决定当前的事务完成后,是否会关闭网络连接。如果该值是“keep-alive”,网络连接就是持久的,不会关闭,使得对同一个服务器的请求可以继续在该连接上完成
```
12. django请求生命周期?
```
1. 当用户在浏览器中输入url时,浏览器会生成请求头和请求体发给服务端
请求头和请求体中会包含浏览器的动作(action),这个动作通常为get或者post,体现在url之中.
2. url经过Django中的wsgi,再经过Django的中间件,最后url到过路由映射表,在路由中一条一条进行匹配,
一旦其中一条匹配成功就执行对应的视图函数,后面的路由就不再继续匹配了.
3. 视图函数根据客户端的请求查询相应的数据.返回给Django,然后Django把客户端想要的数据做为一个字符串返回给客户端.
4. 客户端浏览器接收到返回的数据,经过渲染后显示给用户.
```
13. 什么是wsgi?
```
WSGI是一个规范,定义了Web服务器如何与Python应用程序进行交互,使得使用Python写的Web应用程序可以和Web服务器对接起来。
```
14. 什么是MVC ?什么是MTV?
```
所谓MVC就是把Web应用分为模型(M),控制器©和视图(V)三层,他们之间以一种插件式的、松耦合的方式连接在一起:
A.模型负责业务对象与数据库的映射(ORM)
B.视图负责与用户的交互(页面)
C.控制器接受用户的输入调用模型和视图完成用户的请求
MTV模式:
Django的MTV模式本质上和MVC是一样的,也是为了各组件间保持松耦合关系,只是定义上有些许不同
Django的MTV分别是值:
M 代表模型(Model):负责业务对象和数据库的关系映射(ORM)。
T 代表模板 (Template):负责如何把页面展示给用户(html)。
V 代表视图(View):负责业务逻辑,并在适当时候调用Model和Template。
```
15. django中间件作用以及应用场景?
```
中间件是介于request与response处理之间的一道处理过程,用于在全局范围内改变Django的输入和输出。
简单的来说中间件是帮助我们在视图函数执行之前和执行之后都可以做一些额外的操作
例如:
1.Django项目中默认启用了csrf保护,每次请求时通过CSRF中间件检查请求中是否有正确token值
2.当用户在页面上发送请求时,通过自定义的认证中间件,判断用户是否已经登陆,未登陆就去登陆。
3.当有用户请求过来时,判断用户是否在白名单或者在黑名单里
```
16. django中FBV和CBV有什么区别?
```
FBV(function base views) 就是在视图里使用函数处理请求。
在之前django的学习中,我们一直使用的是这种方式,所以不再赘述。
CBV(class base views) 就是在视图里使用类处理请求。
Python是一个面向对象的编程语言,如果只用函数来开发,有很多面向对象的优点就错失了(继承、封装、多态)。所以Django在后来加入了Class-Based-View。可以让我们用类写View。这样做的优点主要下面两种:
提高了代码的复用性,可以使用面向对象的技术,比如Mixin(多继承)
可以用不同的函数针对不同的HTTP方法处理,而不是通过很多if判断,提高代码可读性
```
17. django orm中如何批量创建数据?
````
批量插入数据的时候,首先要创建一个对象的列表,然后调用bulk_create方法,一次将列表中的数据插入到数据库中。
````
18. django 如何执行原生SQL?
```
django执行原生sql
一、ORM
row()方法:只能实现查询
复制代码
d_list = models.Article.objects.raw(
'select nid, count(nid) as num,strftime("%Y-%m",create_time) as ctime from blog_article where user_id = ' +
str(user.pk) + ' group by strftime("%Y-%m",create_time)'
)
for i in d_list:
print('i', i, type(i),i.ctime, i.num)
#i Python BeautifulSoup抓取表情包并保存 <class 'blog.models.Article'> 2018-07 6
复制代码
注意:1-选择的字段必须包含主键,2-通过'app名_表名'找表,3-where条件中用户id(user.pk)必须是字符串类型
不能像在终端输入sql语句后立即返回数据,只能通过调用对象属性的方法查看。
二、cursor对象: 支持所有操作
复制代码
from django.db import connection
question_obj = models.Questions.objects.get(pk=qid)
cursor = connection.cursor()
cursor.execute(question_obj.answer)
res = cursor.fetchall() # 返回元组
for i in res:
print(i, i[1])
复制代码
```
19. django的orm如何查询id不等于5的数据。
```
models.UserInfo.objects.filter(id__gt=5) # 获取id大于5的值
models.UserInfo.objects.filter(id__gte=5) # 获取id大于等于5的值
models.UserInfo.objects.filter(id__lt=5) # 获取id小于5的值
models.UserInfo.objects.filter(id__lte=5) # 获取id小于5的值
models.UserInfo.objects.filter(id__lt=5, id__gt=1) # 获取id大于1且 小于5的值
```
20. cookie和session的区别?
```
cookie和session有着千丝万缕的联系
1、存储位置不同
cookie的数据信息存放在客户端浏览器上。
session的数据信息存放在服务器上。
2、存储容量不同
单个cookie保存的数据<=4KB,一个站点最多保存20个Cookie。
对于session来说并没有上限,但出于对服务器端的性能考虑,session内不要存放过多的东西,并且设置session删除机制。
3、存储方式不同
cookie中只能保管ASCII字符串,并需要通过编码方式存储为Unicode字符或者二进制数据。
session中能够存储任何类型的数据,包括且不限于string,integer,list,map等。
4、隐私策略不同
cookie对客户端是可见的,别有用心的人可以分析存放在本地的cookie并进行cookie欺骗,所以它是不安全的。
session存储在服务器上,对客户端是透明对,不存在敏感信息泄漏的风险。
5、有效期上不同
开发可以通过设置cookie的属性,达到使cookie长期有效的效果。
session依赖于名为JSESSIONID的cookie,而cookie JSESSIONID的过期时间默认为-1,只需关闭窗口该session就会失效,因而session不能达到长期有效的效果。
6、服务器压力不同
cookie保管在客户端,不占用服务器资源。对于并发用户十分多的网站,cookie是很好的选择。
session是保管在服务器端的,每个用户都会产生一个session。假如并发访问的用户十分多,会产生十分多的session,耗费大量的内存。
7、浏览器支持不同
假如客户端浏览器不支持cookie:
cookie是需要客户端浏览器支持的,假如客户端禁用了cookie,或者不支持cookie,则会话跟踪会失效。关于WAP上的应用,常规的cookie就派不上用场了。
运用session需要使用URL地址重写的方式。一切用到session程序的URL都要进行URL地址重写,否则session会话跟踪还会失效。
假如客户端支持cookie:
cookie既能够设为本浏览器窗口以及子窗口内有效,也能够设为一切窗口内有效。
session只能在本窗口以及子窗口内有效。
8、跨域支持上不同
cookie支持跨域名访问。
session不支持跨域名访问。
```
21. django的orm中on_delete的作用?
```
外键的删除
1、常见的使用方式(设置为null)
```
22. 描述crm有哪些功能?
````
CRM软件的基本功能包括客户管理、联系人管理、时问管理、潜在客户管理、销售管理、电话销售、营销管理、电话营销、客户服务等,有的软件还包括了呼叫中心、合作伙伴关系管理、商业智能、知识管理、电子商务等。
````
23. crm中什么是公户?什么是私户?为什么要做这个区分?
````
公户和私户的展示,公户就是所有用户都可以看到的客户,私户就是用户自己的客户
在CRM系统中, 将没有绑定销售的客户称为公户, 绑定销售的客户称为私户.
销售人员各自维护自己的客户(私户), 不可以查看或者跟进其他人的客户, 避免产生纠纷.
````
24. 请列举出CRM系统中的表。
`````
`````
25. 对数据库的数据做展示时,不同字段类型有不同的展示方法,分别是什么?
````
普通字段 -- 对象.字段名
choice字段 -- 对象.get_字段名_display
外键 -- 对象.外键字段.属性
多对多 -- 对象.自定义方法
````
26. 请详细说说你们公司销售是如何使用CRM的。
````
销售可以通过个人渠道获取客户信息, 自己录入到系统中, 或者销售主管或网络咨询师将已经录入系统的客户分配给销售.
销售需要在规定时间间隔内对客户进行跟进或回访, 将跟进信息记录到系统中, 根据不同的情况标记客户的报名意向.
当客户确定报名时需要让客户本人或者销售帮忙添加报名表.
当销售收到客户缴纳的费用时, 需要填写缴费记录, 并将费用转交财务进行审批.
````
27. CRM中有哪些技术点?
`````
技术点 作用
auth模块 认证
modelform 对表进行增删改查
分页 对数据进行分页显示
Q对象 查询条件==或==的关系
QueryDict 保留搜索条件
url的命名和反向解析 ----
事务 + 行级锁 加入私户
批量创建对象 ----
modelformset ----
`````
28. 为什么不用现成的crm而是自己去开发?
````
内部部署型CRM
基于云的CRM
开源CRM
````
29. 请简述实现权限控制的流程。
`````
在web应用中, 一个URL代表一个权限, 可以访问某一URL则说明有该权限. 该权限系统中URL被分为两种, 一种是可以做二级菜单的父权限, 一种是不能做菜单的子权限. Menu表中的数据称之为一级菜单, 二级菜单被分配给一级菜单. 子权限分配给父权限.
当用户登录成功时, 根据用户所有的角色查询出所具有的权限, 将权限信息和菜单信息存放在session中. 登录成功后跳转至其他URL时, 请求经过中间件时进行权限的校验, 根据当前访问的url和session中存放的权限信息进行正则匹配. 都匹配不成功, 则拒绝访问. 匹配成功则继续走正常的流程得到相应的响应.
页面中的可点击的按钮也是权限, 在模板渲染时使用自定义filter判断该按钮所代表的权限是否在该用户所拥有的权限中, 如果是则显示该按钮, 否则不显示.
`````
30. 列举权限有多少张表?表中都有那些字段?
`````
表 字段
菜单表Menu id、 name
权限表Permission id、 title、 url、 name、 parent_id、 menu_id
角色表Role id、 name
用户表User id、 username、 password
角色和权限关系表 id、 role_id、 permission_id
用户和角色关系表 id、 user_id、 role_id
`````
31. 为什么要把权限信息放到session中?权限信息放到session有什么优缺点?
`````
将权限和菜单的字典存放在session中是为了给不同用户存放不同的权限和菜单, 并且session可以存放在Redis中, 读取速度快.
`````
32. 权限控制到按钮级别是如何实现的?
````
session中存放着一个有关权限信息的字典, 字典的key为权限的URL别名, value为一个权限的具体信息.
自定义了一个filter, 用来判断某一个权限是否在该用户的权限字典中, 在的话返回True, 不在返回False.
模板中使用该filter来对每个要生成按钮的部分做判断, 有权限则会显示按钮, 没有权限则不显示.
````
33. 如何实现把权限粒度控制到数据行?
`````
一、models层给权限增加url的别名
二、在初始化权限中增加别名
三、中间件处理
四、模板处理
`````
1. 详细描述是jsonp实现机制?
主要是浏览器的同源同域(协议相同,域名相同及端口相同)策略需要使用跨域获取数据,故需要jsonp跨域获取数据。
2. django的orm如何通过数据自动化生成models类?
一、配置数据库
二、输入命令生成models.py中的模型类
3. django中如何设置缓存?
一.配置文件settings.py中
二.某个应用的视图文件views.py中
4. django中信号的作用?
Django signal
5. django中如何设置读写分离
修改配置文件:
创建数据库操作的路由分法类
在utils中创建db_touter.py文件
在dev.py中配置读写分离路由
1. 默写ajax基本语法,及提交json数据和文件都需要添加哪些额外参数
ajax基本语法(jquery版):
$.ajax({
url:'',#不写默认朝当前页面提交
type:'post',#不写默认提交方式为get
data:{},提交数据
dataType:'json',
success:function(args){ #异步回调函数机制
alert(args);
}
})
ajax请求的数据默认编码格式是urlencoded
提交json格式数据
需要添加参数
data:JSON.stringify({'name':'jason','age':18})
contentType:'application/json' //指定编码格式
提交文件需要添加参数
contentType:false,// 不需使用任何编码 django后端能够自动识别formdata对象
processData:false,// 告诉你的浏览器不要对你的数据进行任何处理
2.什么是序列化,截止目前为止你所接触过的序列化有哪些。
序列化主要是将数据转成一种标准的格式,便于不同编程语言之间的数据交互,比如前后端分离开发,数据交互需要使用json序列化。
后端普通序列化 前端序列化
json.dumps(data_dic) JSON.stringify(data_dic)
json.loads(data_str) JSON.parse(data_str)
django后端
from django.http import JsonResponse
return JsonReponse(info_list,safe=false,json_dumps_params={'ensure_ascii':false})
django自带的序列化组件
from django.core import serializers
user_queryset = models.User.objects.all()
res = serializers.serialize('json', user_queryset) //前面一个参数为数据格式,后面的参数必须为一个queryset对象
3.批量插入数据需要注意什么,orm批量插入数据的语法?
orm批量插入数据的语法bulk_create()语法:
book_list=[]
for i in range(10000):
book_obj=models.Book(title='第%s本书' % (i,))
book_list.append(book_obj)
models.Book.objects.bulk_create(book_list)
4.当需要展示的数据量特别多的情况下,会采取什么优化措施,你能否简要描述一下该措施的实施思路,以及该措施具体应用下的操作步骤
采取分页措施
(1)get请求可以携带数据 url?page=1
(2)queryset对象支持索引切片操作 book[page_obj.start:page_obj.end]
5.简述面相对象的三大特性及特点,其中你认为哪个特性使用频率最高,为什么。
封装,继承,多态
封装用的比较频繁,因为python中一切皆对象,我们无时不刻不在使用封装的后的结果,比如一些方法。
6. choices参数的应用场景有哪些,如何获取该字段的值
针对一些可以列举出完全的可能性字段,规范用户的输入,例如性别。
example:
class User(models.Model):
GENDER_CHOICES = (
(1,'male'),
(2,'female'),
(3,'secret'),
)
gender=models.IntegerField(choices=GENDER_CHOICES,default=3,verbose_name='性别')
# 获取该字段的值
user_obj = models.User.objects.filter(pk=1).first()
print(user_obj.get_gender_display())
7. django是什么模型的框架,简述MTV与MVC模型
django是MTV模型,本质上其实也是一个MVC模型
MTV:
M--Models
T--Templates
V--Views
MVC:
M--Models
V--Views
C--Controller
8. 多对多表关系有几种创建方式,各有什么特点?
多对多的表关系有三种创建方式
全自动:方便,ORM自动创建第三张表,可扩展性差
全手动:比较繁琐,可扩展性好,不能使用ORM提供的方法
半自动:兼顾方便与可扩展性,可扩展性好,自己创建第三张表,可以使用ORM的正反向查询但是无法使用add,set,remove,clear这四个方法
9. 什么是 ajax,请手写出 ajax 的基本语法结构及重要参数含义
"""
异步提交,局部刷新
"""
$.ajax({
url:'',//不写朝当前地址提交
type:'post',//ajax的提交方式,不写默认为get
data:{...},//提交的数据
dataType:'json',//
success:function(args){ //回调函数
alert('hello word')
}
})
10. python 的内存管理机制
(1) 垃圾回收
(2) 引用计数
(3) 内存池机制
1. choices参数的应用场景有哪些,如何获取该字段的值
针对一些可以列举出完全的可能性字段,规范用户的输入,例如性别。
example:
class User(models.Model):
GENDER_CHOICES = (
(1,'male'),
(2,'female'),
(3,'secret'),
)
gender=models.IntegerField(choices=GENDER_CHOICES,default=3,verbose_name='性别')
# 获取该字段的值
user_obj = models.User.objects.filter(pk=1).first()
print(user_obj.get_gender_display())
2. django是什么模型的框架,简述MTV与MVC模型
django是MTV模型,本质上其实也是一个MVC模型
MTV:
M--Models
T--Templates
V--Views
MVC:
M--Models
V--Views
C--Controller
3. 多对多表关系有几种创建方式,各有什么特点?
多对多的表关系有三种创建方式
全自动:方便,ORM自动创建第三张表,可扩展性差
全手动:比较繁琐,可扩展性好,不能使用ORM提供的方法
半自动:兼顾方便与可扩展性,可扩展性好,自己创建第三张表,可以使用ORM的正反向查询但是无法使用add,set,remove,clear这四个方法
4. 什么是 ajax,请手写出 ajax 的基本语法结构及重要参数含义
"""
异步提交,局部刷新
"""
$.ajax({
url:'',//不写朝当前地址提交
type:'post',//ajax的提交方式,不写默认为get
data:{...},//提交的数据
dataType:'json',//
success:function(args){ //回调函数
alert('hello word')
}
})
1.简述列举了解的编程语言及语言间的区别?
Python:轻量级、易学、自由 开放源码软件、可移植性、支持面向对象、丰富的库、规范的代码。
Java:优点:开源性,功能强大,库多
缺点:编译速度 比较慢,不完全
PHP:优点:性能很强,配合简单,稳定,容易部署。
缺点:函数命名不规范,驼峰法和下划线,传参位置不一。
C: 优点:能操纵底层,能细粒度优化性能。
缺点:1、是面向过程的,2、运行时类型检查不可用,3、不提供命名空间功能,
4、构造函数和析构函数不可用。
C#: 优点: 强大的.NET Framework托管代码集合类,较简单的语言特性。
WEB应用程序开发速度快。
缺点:底层和高性能不合适,Windows平台以外支持有限。
C++: 优点:性能比较高,可进化型。
缺点: 难学,门槛高
#第一题
编译型语言:一次性全部编译成二进制码,再去运行
解释性语言:编译- -句,运行一句
1. python
解释型简洁高效,容易上手
2. java
混合型(JVM,JIT编译器)_学习成本高,开发周期慢,web方向
3. C
编译型属于底层语言,只有面向过程没有面向对象
4. c++
编译型属于底层语言,既有面向过程也有面向对象
35. go .
编译型应用在区块链,高并发高可用,游戏方向
2. 例举python2 和python3 的区别?
Python2默认的字符编码是ASCII,默认的文件编码也是ASCII ;
python3默认的字符编码是unicode,默认的文件编码是utf-8。
在python2里,将string处理为原生的bytes类型。
python3把字符串的编码改成了unicode, 还把str和bytes做了明确区分, str就是unicode格式的字符,bytes是单纯二进制。print语句没有了,取而代之的是print()函数。
在python 2.x 中/除法整数相除的结果是一个整数,把小数部分完全忽略掉,浮点数除法会保留小数点的部分得到一个浮点数的结果。
在python 3.x 中/除法不再这么做了,对于整数之间的相除,结果也会是浮点数。
捕获异常的语法由 except exc, var 改为 except exc as var。
Python 2.x 中反引号 相当于 repr 函数的作用
Python 3.x 中去掉了 这种写法,只允许使用 repr 函数
Py3.X去除了long类型,现在只有一种整型——int,但它的行为就像2.X版本的long
在 Python 2 中 有 range ()和 xrange () ,一般使用 xrange ()创建迭代对象。
在 Python 3 中, range () 是像 xrange ()那样实现, xrange ()内置函数已经删除。
笔记:
#第二题
# python2
1. print "123"
2.range返回list
3.默认编码-- ascii
4.2种类经典类和新式类
class Car () :pass
经典类(多继承当中的搜索原则深度优先)
class. Car (object) :pass新式类(多继承当中的搜索原则广度优先)
类.mro() =>继承顺序列表
5.除法:结果是整型
6.int ,long (长整型)
7.raw_ input =>等价于python3 input
# python3
1. print ()
2.range返回的可迭代对象
3.默认编码-- utf-8
4.都是新式类
5.除法:结果是小数
6. int
7. input
3. 看代码写结果
v1 = 1 or 2
v2 = 9 and 7 or 9 and 0
1
7
笔记:逻辑运算符优先级 () > not > and > or
逻辑短路
and 全真则真,一假则假
or 一真则真,全假则假
True or 表达式 => True (单个运算符和多个运算符的情况,都可以直接判定结果)
False and 表达式 => False(单个运算符的时候可以)
布尔值为假的十种情况: bool() => False
0,0.0,False,0j,'',[],(),set(),{},None
v1 = 1 or 2
print(v1) # 1
v2 = 3 and 7 or 9 and 0
v2 = 7 or 0
v2 = 7
print(v2)
"""
数据类型:
Number(int , float , complex , bool)
容器:str list tuple set dict
复数 : 用在数据分析,人工智能中
complexvar = 3 + 4j
3 : 实数
4j: 虚数
j: 如果有一个数,他的平方等于-1 ,那么这个数就是j,科学家认为有,表达高精度类型
"""
4. 比较以下值有什么不同?
v1 = [1,2,3]
v2 = [(1),(2),(3)]
v1 = [(1,),(2,),(3,)]
逗号才是区分是否是元组的标识符
v1 = [1,2,3] # 列表[int , int , int]
v2 = [(89),(2.12),("abc")] # [int , float , str]
v3 = [(1,),(2,),(3,)] # [tuple,tuple,tuple,tuple]
res = () # 表达空元组
5. 用一行代码实现数值交换。
a = 1
b = 2
a,b = b,a
笔记:
# python 特有
a = 1
b = 2
a,b = b,a
# 通用
tmp = a
a = b
b = tmp
6. Python中单引号、双引号、三引号的区别?
python单引号 ’ 双引号 " 三引号 ‘’’ 和 “”"都是字符串且可以进行转义,
唯一的差别就是三引号 ‘’’ 和 “”"可以显示多行。
笔记:
单双引号没有区别,三引号可以支持跨行
在互相嵌套时需注意:里外不能使用相同的引号
7. is和==的区别?
is 是判断等式两边的内存地址是否相同
== 是判断等式两边的值是否相等
8. python里如何实现tuple和list的转化?
# int float complex bool str list tuple set dict
list(数据) tuple(数据)
9.如何实现字符串name= '老男孩’的反转?
使用字符串切片
s = "老男孩"
s1 = s[::-1]
print(s1)
笔记:
name[start:end:step] 语法
name[::-1]
10.两个set如何获取交集、并集、差集?
#set 函数是无序不重复的元素集合,可以进行关系测试,去除重复数据,还可以计算交集、差集、和并集
#class set([iterable]) iterable 可迭代对象
#删除重复
x=set('sixbobo')
y=set('googlebb')
print('删除重复元素',x,y)
#取交集
print(x&y)
#取并集
print(x|y)
#取差集
print(x-y)
some_list=['liubo','liuda','liuer','liusan','liusi','liubo','sixbo','sixbo']
duplicates=[]
for value in some_list:
#判断列表中A元素的个数大于1
if some_list.count(value)>1:
#并且不在变量list中
if value not in duplicates:
#添加到列表中
duplicates.append(value)
print(duplicates)
some_list01=set(['liubo','liuda','liuer','liusan','liusi','liubo','sixbo','sixbo'])
some_list02=set(['liubo','jsj','jdsj'])
#取交集
print(some_list01&some_list02)
print(some_list02.intersection((some_list01))) #intersection交集的方法
#取差集
print(some_list01-some_list02)
print(some_list02.difference(some_list02))#difference 差集
#取并集
print(some_list01|some_list02)
print(some_list02.union(some_list01))#union 并集
笔记:
交集 &
intersection
差集 -
difference
并集 |
union
对称差集 ^
symmetric_difference
11.那些情况下, y!=x- (x-y)会成立?
"""
非空集合且不为子父关系的两个集合
"""
y != x-(x-y)
x = {"a","b","c"}
y = {"b","d"}
if y != x-(x-y):
print("ok")
12. Python中如何拷贝一个对象?
一、赋值、引用
二、深拷贝deepcopy与浅拷贝copy
笔记:
# import copy
# 针对于列表的拷贝,还可以使用[:] , [::],浅拷贝的一种方式
lst1 = [1,2,3]
lst2 = lst1[:]
lst1.append(4)
print(lst2)
13.简述赋值、浅拷贝、深拷贝的区别?
赋值(=),就是创建了对象的一个新的引用,修改其中任意一个变量都会影响到另一个。
浅拷贝:创建一个新的对象,但它包含的是对原始对象中包含项的引用(如果用引用的方式修改其中一个对象,另外一个也会修改改变){1,完全切片方法;2,工厂函数,如list();3,copy模块的copy()函数}
深拷贝:创建一个新的对象,并且递归的复制它所包含的对象(修改其中一个,另外一个不会改变){copy模块的deep.deepcopy()函数}
笔记:
#赋值 : 将变量和值在内存中形成映射指向关系
#浅拷贝 : 只拷贝第一级里所有的元素 copy.copy
#深拷贝 : 为所有层级的元素都单独开辟新空间 copy.deepcopy() (地址:原不可变数据只是暂时的指向,可变的数据独立开辟新空间)
"""
可变数据: list set dict
不可变数据: int float bool complex str tuple
"""
import copy
lst1 = [1,2,3,[4,5,6]]
lst2 = copy.deepcopy(lst1)
lst1[0] = 100
print(lst1)
print(lst2)
print(id(lst1[0]))
print(id(lst2[0]))
14. pass的作用?
python中if ,for等复合语句通常是由一个语句头和语句体构成。语句体中出现的语句数量并没有限制,但是至少需要一行。
偶尔可能会需要一个语句体什么也不做(通常是标记一个你还没来得及写的代码的位置),
这个时候就需要pass了。
pass是空语句,是为了保持程序结构的完整性。
pass 不做任何事情,一般用做占位语句。
if x < 0:
pass
笔记:
# 占位
15.阅读代码写结果。
import copy
a = [1,2,3,4,5,['b','c']]
b = a
c = copy.copy(a)
d = copy.deepcopy(a)
a.append(5)
a[4].append('d')
print(b)
print(c)
print(a)
import copy
a = [1,2,4,5,['b','c']]
b = a
c = copy.copy(a)
d = copy.deepcopy(a)
a.append(5)
a[4].append('d')
# print(a) [1,2,4,5,['b','c',"d"],5]
# print(b) [1,2,4,5,['b','c',"d"],5]
# print(c) [1,2,4,5,['b','c',"d"]]
16.用Python实现9 * 9乘法表。
l=1
i=0
while l<10:
i=1
while i<=l:
if i==l:
print(i,'*',l,'=',l*i)
else:
print(i,'*',l,'=',l*i,end=' ')
i += 1
l += 1
笔记:
"""
有行又有列,脑海里瞬间想到两层循环
一层循环控制行
一层循环控制列
"""
i = 1
while i<=9:
# 这个位置写代码
j = 1
while j<= i:
# "谁"*"谁"="谁"
print("%d*%d=%2d" % (i,j,i*j),end=" ")
j+=1
# 打印换行
print()
i+=1
for i in range(1,10):
for j in range(1,i+1):
print("%d*%d=%2d" % (i,j,i*j),end=" ")
print()
17.用Python显 示一个斐波那契数列。
def fib(n):
a, b = 0, 1
while a < n:
print(a, end=' ')
a, b = b, a+b
print()
fib(1000) # 取值范围可以任意
# 输出结果如下:
# 0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987
笔记:
# 1 1 2 3 5 8 13 21 ...
# 方法一
lst = [1,1]
for i in range(10):
lst.append(lst[-1] + lst[-2])
print(lst)
# 方法二
a,b = 0,1
for i in range(10):
print(b)
a,b = b,a+b
# 方法三
def fib(n):
if n <= 2:
return 1
# 上一个值 + 上上个值
return fib(n-1) + fib(n-2)
print(fib(6))
18.如何删除列表中重复的值?
方法一 set函数
a = [1, 1, 2, 3, 3]
b = set(a)
# b = {1, 2, 3} b是集合
方法二 遍历
b = []
for i in a:
if not i in b:
b.append(i)
# b = [1, 2, 3]
笔记:
list(set(lst))
19.一个大小为100G的文件etl log.txt,要读取文件中的内容,写出具体过程代码?
fp = open("文件名","模式","编码集")
"""
fp 是迭代器
from collections import Iterator,Iterable
# 在遍历fp时,文件按照一行一行进行读取;
for i in fp:
code ...
"""
20. a= dict(ip((“a” ,“b”,",“d”,“e”),(1,2,3,4,5)))请问a是什么?
强转字典的条件:等长的二级容器,配合强转字典的两个函数 zip , enumerate
# zip 拉链
a = dict( zip( ("a","b") , [1,2] ) )
print(a)
# enumerate 枚举
a = dict( enumerate( ["a","b"] ))
a = dict( enumerate( ["a","b"] ,start = 10 ))
print(a)
21. lambda关键字的作用?
lambda函数是匿名的:所谓匿名函数,通俗地说就是没有名字的函数。lambda函数没有名字。
lambda函数有输入和输出:输入是传入到参数列表argument_list的值,输出是根据表达式expression计算得到的值。
lambda函数一般功能简单:单行expression决定了lambda函数不可能完成复杂的逻辑,只能完成非常简单的功能。由于其实现的功能一目了然,甚至不需要专门的名字来说明。
笔记:
lambda 匿名函数 : 用一句话表达只有返回值的无名函数
lambda 参数 : 返回值
22. *arg 和**kwarg作用?
1、函数调用里的*arg和**kwarg:
(1)*arg:元组或列表“出现”
**kwarg:字典“出没”
(2)分割参数
2、函数定义时传的*arg /**kwarg:
(1)接收参数
笔记:
*arg **kwarg
# *arg 普通收集参数 : 收集多余的没人要的普通实参
# **kwarg 关键字收集参数: 收集多余的没人要的关键字实参
23. 如何在函数中设置一个全局变量?
在函数的内部,通过global声明,使在函数内部中设置一个全局变量,这个全局变量可以在任意的函数中进行调用!
SOLR_URL='http://solr.org'
def tt():
global SOLR_URL
SOLR_URL=SOLR_URL+'#aa'
def aa():
if __name__=='__main__':
tt()
print(SOLR_URL)
aa() # http://solr.org#aa
笔记:
"""
global 有该全局变量,修改当前变量,没有改全局变量,定义一个全局变量;
"""
def func():
global a
a = 90
func()
print(a)
24. filter、 map、reduce的作用?
通俗的说..都是用在一堆数据(比如一个列表)上..
filter是筛选出其中满足某个条件的那些数据..字面意思是过滤..比如挑出列表中所有奇数..
map是用同样方法把所有数据都改成别的..字面意思是映射..比如把列表的每个数都换成其平方..
reduce是用某种方法依次把所有数据丢进去最后得到一个结果..字面意思是化简..比如计算一个列表所有数的和的过程,就是维持一个部分和然后依次把每个数加进去..
笔记:
"""
三目(元)运算符 True if 条件表达式 else False
filter => 过滤数据
iterable : 可迭代对象(range ,容器类型数据 , 迭代器)
filter(func,iterable) => 返回迭代器
lst = [1,2,3,4,5]
it = filter(lambda x : True if x % 2 == 0 else False , lst )
print(list(it))
"""
# map -> 处理(映射)数据
map(func,iterable) => 返回迭代器
lst = [1,2,3]
it = map(lambda x : x*3 , lst)
print(list(it))
# reduce -> 计算数据
from functools import reduce
# reduce(func,iterable) => 最后计算的值
# [5,4,8,8] => 5488
lst = [5,4,8,8]
res = reduce(lambda x,y : x*10 + y ,lst )
print(res , type(res))
25.什么是匿名函数?匿名函数有什么作用?
匿名函数顾名思义就是没有名字的函数
可以通过 use 关键字获取上下文中的环境变量,减少不必要参数的传入或导出。
减少不必要的函数暴露,提高代码的可读性
如果使用匿名函数,该函数仅仅会在被调用处使用,其他地方不会引用到。
如果不使用匿名函数,该函数可以在其他地方被引用。从可读性上讲,没有匿名函数可读性高。
笔记:
lambda 匿名函数 : 用一句话表达只有返回值的无名函数
lambda 参数 : 返回值
26. Python递归的最大层数?
最大数为998
import sys
sys.setrecursionlimit(100000)
def foo(n):
print(n)
n += 1
foo(n)
if __name__ == '__main__':
foo(1)
笔记:
官方说法1000 , 实际测试 994 ~ 1000
import sys
sys.setrecursionlimit(999999) # 修改递归的最大深度
27.什么是迭代器?什么是可迭代对象?
迭代器:
迭代器是一个对象
迭代器只能使用一次
迭代器一定是一个可迭代对象,可迭代对象不一定是一个迭代器,迭代器是一个对象class
可以被迭代要满足的要求就叫做可迭代协议。可迭代协议的定义非常简单,就是内部实现了__iter__方法。
迭代器生成的对象就是可迭代对象
笔记:
# 具有__iter__() 和 __next__()这两个方法的是迭代器
# 具有__iter__()方法就是可迭代对象
# dir(数据) 可以查看该数据的内部系统成员
# 可迭代对象 => 迭代器 把不能直接被next获取 => 可直接获取到该数据的一个过程
28.什么是生成器?
Python中提供的生成器:
1.生成器函数:常规函数定义,但是,使用yield语句而不是return语句返回结果。yield语句一次返回一个结果,在每个结果中间,挂起函数的状态,以便下次重它离开的地方继续执行
2.生成器表达式:类似于列表推导,但是,生成器返回按需产生结果的一个对象,而不是一次构建一个结果列表
生成器Generator:
本质:迭代器(所以自带了__iter__方法和__next__方法,不需要我们去实现)
特点:惰性运算,开发者自定义
笔记:
生成器的本质就是迭代器,可以自定义迭代的逻辑
创建方式两种:
(1)生成器表达式 (推导式) (i for i in range(3))
(2)生成器函数 (含有yield关键字)
29.什么是装饰器及应用场景?
概念:
1.装饰器的实现是由闭包支撑的;
2.装饰器本质上是⼀个python函数,它可以在让其他函数在不需要做任何代码的变动的前提下增加额外的功能;
3.装饰器的返回值也是⼀个函数的对象,它经常用于有切面需求的场景,实现路由传参,flask的路由传参依赖于装饰器,浏览器通过url访问到装饰器的路由,从而访问视图函数获得返回的HTML页面;
应用场景:
1.可以在外层函数加上时间计算函数,计算函数运行时间;
2.计算函数运行次数;
3.可以用在框架的路由传参上;
4.插入日志,作为函数的运行日志;
5.事务处理,可以让函数实现事务的一致性,让函数要么一起运行成功,要么一起运行失败;
6.缓存,实现缓存处理;
7.权限的校验,在函数外层套上权限校验的代码,实现权限校验;
笔记:
# 装饰器的本质就是闭包
# 在不修改原有代码的前提下,额外增加新功能就是装饰器
# 应用:登录认证,property类,框架(django,flask,@app.route("/",methdos=["GET","POST"]))
30.什么是反射及应用场景?
反射
主要是指程序可以访问、检测和修改它本身状态或行为的一种能力
应用场景
例如模块化的开发,通过反射去调用对应的字节码;动态代理设计模式也采用了反射机制,还有我们日常使用的 Spring/Hibernate 等框架
笔记:
# 通过字符串去操作类对象 或者 模块中的属性方法
hasattr getattr setattr delattr
应用: 可以配合用户的操作或者输入,调用其中的成员,api接口中
31.写一个普通的装饰器。
import datetime
def time_it(func):
def _deco(*args, **kwargs):
start = datetime.datetime.now()
print("--- Start time: %s ---" % start)
ret = func(*args, **kwargs)
end = datetime.datetime.now()
print("---- End time: %s ----" % end)
print("Function spend time: %s" % (end - start))
return ret
return _deco
笔记:
闭包:内函数使用了外函数的局部变量,外函数把内函数返回出来的过程叫做闭包
这个内函数叫做闭包函数;
特点:如果内函数使用了外函数的局部变量,那么该变量于内函数发生绑定,延长该变量的生命周期
def wrapper(func):
def inner(*args,**kwargs):
res = func(*args,**kwargs)
print("and you")
return res
return inner
@wrapper
def func():
print("i am fine 3q")
func()
32.写一个带参数的装饰器。
import time
FLAGE = False
def timeer_out(flag):
def timeer(func):
def inner(*args,**kwargs):
if flag:
start = time.time()
ret = func(*args,**kwargs)
end = time.time()
print(end - start)
return ret
else:
ret = func(*args,**kwargs)
return ret
return inner
return timeer
@timeer_out(FLAGE)
def lala():
time.sleep(0.1)
print("小垃圾")
lala()
笔记:
def outer(n):
def wrapper(func):
def inner1(*args,**kwargs):
res = func(*args,**kwargs)
print("我是大王")
return res
def inner2(*args,**kwargs):
res = func(*args,**kwargs)
print("大王叫我来巡山")
return res
if n == "alex":
return inner1
else:
return inner2
return wrapper
@outer("alex123") # outer("alex123") => wrapper =>@wrapper
def func():
print("i am fine 3q")
func()
33.求结果
def num() :
return [lambda x:i*x for i in range(4)]
print([m(2) for m in num()])
[6, 6, 6, 6]
笔记:
def num():
return [lambda x:i*x for i in range(4)]
print([m(2) for m in num()])
"""
def出现的位置是函数的定义处
函数() 出现的位置是函数的调用处
(1)调用的时候,才会把函数中的代码,从上到下执行一遍,否则不执行
(2)里面的func是一个闭包函数,延长了当前变量i的生命周期,最后一次i的值3,所以再去调用时候拿的3
"""
def num():
lst = []
for i in range(4):
def func(x):
return i*x
lst.append(func)
return lst
lst = num()
print(lst)
lst = [ m(2) for m in num() ]
lst = [ m(2) for m in lst ]
lst = [ i*x for m in lst ]
lst = [3 * 2 for m in lst]
lst = [6,6,6,6]
"""
[
<function func at 0x000001A02CA642F0>,
<function func at 0x000001A02CA64378>,
<function func at 0x000001A02CA646A8>,
<function func at 0x000001A02CA64730>
]
def func():
print(1)
for i in range(3):
print(i)
"""
34. def(a, b=[])这种写法有什么陷阱?
def func(a,b=[]):
b.append(a)
print(b)
func(1)
func(1)
func(1)
func(1)
看下结果
[1]
[1, 1]
[1, 1, 1]
[1, 1, 1, 1]
函数的第二个默认参数是一个list,当第一次执行的时候实例化了一个list,第二次执行还是用第一次执行的时候实例化的地址存储,所以三次执行的结果就是 [1, 1, 1] ,想每次执行只输出[1] ,默认参数应该设置为None。
笔记:
b身上的默认值是列表,如果使用原来默认的参数,调用func函数
会把几次调用的值都存放在同一个默认列表里
"""
默认参数:
如果调用时,用户给实参了,那么使用用户的
如果调用时,用户没给实参,那么使用默认的(早已存在内存中的这个列表)
默认值会提前在内存中驻留,在使用时,才能调取,在定义函数的时候就提前开辟了空间
"""
35. 看代码写结果
def func(a,b=[]):
b. append (a)
return b
v1 = func(1)
v2 = func(2, [10,20])
v3 = func(3)
print(v1,v2,v3)
[1, 3] [10, 20, 2] [1, 3]
笔记:
def func(a,b=[]):
b.append(a)
return b
v1 = func(1)
v2 = func(2,[10,20])
v3 = func(3)
print(v1,v2,v3) # [1,3] [10, 20, 2] [1, 3]
36.看代码写结果
def func(a,b=[]):
b.append(a)
return b
v1 = func(1)
print(v1)
v2 = func(2, [10,20])
print(v2)
v3 = func(3)
print(v3)
[1]
[10, 20, 2]
[1, 3]
笔记:
def func(a,b=[]):
b.append(a)
return b
v1 = func(1)
print(v1) # [1]
v2 = func(2,[10,20])
print(v2) # [10, 20, 2]
v3 = func(3)
print(v3) # [1, 3]
37.请编写一个函数实现将IP地址转换成一个整数。
如10.3.9.12 转换规则为:
10 00001010
3 00000011
9 00001001
12 00001100
再将以上二进制拼接起来计算十进制结果: 00001010 00000011 00001001 00001100 = ?
笔记:
# ljust 原字符串居左,填充符号
# rjust 原字符串居右,填充符号
# 方法一
ip = "10.3.9.12"
strvar = ""
for i in ip.split("."):
bin_str = str(bin(int(i)))[2:]
# 总长度是8 原字符串居右
strvar += bin_str.rjust(8,"0")
print(strvar)
# 把二进制字符串转换成十进制,默认转换时,是十进制
print(int(strvar,2))
# 方法二
ip = "10.3.9.12"
strvar = ""
for i in ip.split("."):
# format 将整型转化成二进制,不够8位的拿0补位
strvar += format(int(i) , "08b")
print(int(strvar,2))
38.请查找一个目录下的所有文件(可 能存在文件嵌套)。
用file命令查看所有文件的类型
笔记:
# 方法一 (递归写法)
import os
def getallsize(pathvar):
size = 0
lst = os.listdir(pathvar)
print(lst)
for i in lst:
pathvar2 = os.path.join(pathvar,i)
print(pathvar2)
# 判断是否是文件
if os.path.isfile(pathvar2):
size += os.path.getsize(pathvar2)
# 判断是否是文件夹
elif os.path.isdir(pathvar2):
size += getallsize(pathvar2)
print(size)
return size
# "E:\串讲基础\day2\test\1.txt"
pathvar = r"E:\串讲基础\day2\test"
res = getallsize(pathvar)
# print(res)
# 方法二
import os
# os.walk() => 生成器
pathvar = r"E:\串讲基础\day2\test"
gen = os.walk(pathvar)
for root,dirs,files in gen:
for name in files:
pathvar = os.path.join(root,name)
print(pathvar)
39.求结果
import math
print (math. f1oor(5.5))
笔记:
# floor ceil round
import math
print(math.floor(5.5))
# round n.5 奇进偶不进
print(round(4.5))
print(round(5.5))
print(round(4.52))
40.是否使用过 functools 中的函数?其作用是什么?
使用过
functools用于高阶函数:指那些作用于函数或者返回其他函数的函数。通常情况下,只要是可以被当做函数调用的对象就是这个模块的目标。
python 中提供一种用于对函数固定属性的函数
笔记:
from functools import reduce
# 在装饰器中使用,如果想要保留原来函数的属性,加上wraps
from functools import wraps
def wrapper(func):
@wraps(func)
def inner(*args,**kwargs):
res = func(*args,**kwargs)
print("and you")
return res
return inner
@wrapper
def func():
print("i am fine 3q")
func()
print(func)
# def abc():
# pass
# print(abc)
41. re的match和search区别?
1、match()函数只检测RE是不是在string的开始位置匹配,search()会扫描整个string查找匹配;
2、也就是说match()只有在0位置匹配成功的话才有返回,如果不是开始位置匹配成功的话,match()就返回none。
3、例如:
import re
print(re.match('super', 'superstition').span()) # (0,5)
print(re.match('super', 'insuperable')) # None
4、search()会扫描整个字符串并返回第一个成功的匹配:
例如:
import re
print(re.search('super', 'superstition').span()) #(0,5)
print(re.search('super', 'insuperable')) # <_sre.SRE_Match object; span=(2, 7), match='super'>
5、其中span函数定义如下,返回位置信息:
span([group]):
返回(start(group), end(group))。
笔记:
"""
match : 必须从字符串的开头进行匹配
search: 从任意位置开始匹配,匹配到就返回
只匹配一个
"""
42.用Python匹配HTML tag的时候, <.>和<.?>有什么区别?
术语叫贪婪匹配( <.> )和非贪婪匹配(<.?> )
笔记:
. 除了\n的任意字符
* 量词,代表匹配0次或者多次,任意个
.* 贪婪匹配
.*? 非贪婪匹配
43.如何生成一个随机数?
print(random.randint(1,100))
笔记:
import random
random.random 随机获取 0<= x < 1
random.randrange 随机获取指定范围中的整数,用法上同range
random.uniform 随机获取指定范围中的小数
44. super的作用?
可以避免直接使用父类的名字.主要用于多重继承
笔记:
# 用来解决多继承之间复杂的调用关系使用super
在多继承中,如果出现了多个同名方法
super在调用的时候,会按照mro列表的继承顺序依次调用
类.mro() = > lst
45.双下划线和单”下划线的区别?
单下划线(_): 在交互解释器中,表示上一条语句执行输出的结果。另外,单下划线还可以作为特殊的临时变量,表示在后面将不会在用到这个变量。
名称前的单下划线:只能在内部使用,是API中非公开的部分,不能被 import * 和 from import *导入程序中,除非在all列表中包含了以单下划线开头的属性、方法以及类。
名称前的双下划线:以双下划线开头的属性、方法表示避免父类的属性和方法被子类轻易的覆盖,一般不建议这样定义属性和方法,除非你自己将要做什么。
名称前后的双下划线:这类方法是Python内部定义的方法,你可以重写这些方法,这样Python就可以调用这个重写的方法以及利用操作符。
笔记:
class MyClass():
__abc = 90
_ppp = 100
"""
封装: 公有public 私有private 受保护的protected
私有: 只能在当前这个类里面使用,不能再子类或者在类外使用
受保护的: 可以在当前这个类或者子类里使用,不能再类外使用
约定俗成在该变量前面加上一个下划线_ , 就表示受保护了
"""
46. @staticmethod和@classmethod的区 别?
1.定义方式
普通的类方法foo()需要通过self参数隐式的传递当前类对象的实例。 @classmethod修饰的方法class_foo()需要通过cls参数传递当前类对象。@staticmethod修饰的方法定义与普通函数是一样的。
self和cls的区别不是强制的,只是PEP8中一种编程风格,slef通常用作实例方法的第一参数,cls通常用作类方法的第一参数。即通常用self来传递当前类对象的实例,cls传递当前类对象。
2.绑定对象
foo方法绑定对象A的实例,class_foo方法绑定对象A,static_foo没有参数绑定。
>>> print(a.foo)
<bound method A.foo of <__main__.A object at 0x0278B170>>
>>> print(a.class_foo)
<bound method A.class_foo of <class '__main__.A'>>
>>> print(a.static_foo)
<function A.static_foo at 0x02780390>
3.调用方式
foo可通过实例a调用,类对像A直接调用会参数错误。
>>> a.foo(1)
executing foo(<__main__.A object at 0x0278B170>,1)
self: <__main__.A object at 0x0278B170>
>>> A.foo(1)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: foo() missing 1 required positional argument: 'x'
但foo如下方式可以使用正常,显式的传递实例参数a。
>>> A.foo(a, 1)
executing foo(<__main__.A object at 0x0278B170>,1)
self: <__main__.A object at 0x0278B170>
class_foo通过类对象或对象实例调用。
>>> A.class_foo(1)
executing class_foo(<class '__main__.A'>,1)
cls: <class '__main__.A'>
>>> a.class_foo(1)
executing class_foo(<class '__main__.A'>,1)
cls: <class '__main__.A'>
static_foo通过类对象或对象实例调用。
>>> A.static_foo(1)
executing static_foo(1)
>>> a.static_foo(1)
executing static_foo(1)
4.继承与覆盖普通类函数是一样的。
class B(A):
pass
b = B()
b.foo(1)
b.class_foo(1)
b.static_foo(1)
# executing foo(<__main__.B object at 0x007027D0>,1)
# self: <__main__.B object at 0x007027D0>
# executing class_foo(<class '__main__.B'>,1)
# cls: <class '__main__.B'>
# executing static_foo(1)
笔记:
一个静态方法,一个类方法
一个静态方法:(无论是对象还是类,都可以调用,不会默认传递任何参数)
一个类方法 :(无论是对象还是类,都可以调用,会默认传递类这个参数)
47.实现一个单例模式(加锁)。
public class Singleton {
private volatile static Singleton instance;
private Singleton() {
}
public static Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance;
}
}
笔记:
# 单态模式:这个类无论实例化多少次,都有且只有一个对象
from threading import Lock
class MyClass(object):
__obj = None
lock = Lock()
def __new__(cls,*args,**kwargs):
with cls.lock:
if not cls.__obj:
cls.__obj = object.__new__(cls)
return cls.__obj
obj1 = MyClass()
obj2 = MyClass()
print(obj1,obj2)
48.栈和队列的区别?
队列是先进先出,有出口和入口,先进去可以先出来。
栈就像一个箱子,后放上去的,可以先出来
笔记:
栈 : 先进后出,或者 后进先出
队列: 先进先出
49.以下代码输出是什么?请给出答案并解释。
class Parent (object):
X=1
class Child1 (Parent):
pass
class Child2 (Parent):
pass
print(Parent.x,Chi1d1.x,Child2.x)
Child1.x = 2
print(Parent.x,Chi1d1.x,Child2.x)
Parent.x = 3
print(Parent.x,Child1.x,Child2. x)
笔记:
class Parent(object):
x = 1
class Child1(Parent):
pass
class Child2(Parent):
pass
# 1 1 1
print(Parent.x, Child1.x, Child2.x)
Child1.x = 2
# 1 2 1
print(Parent.x, Child1.x, Child2.x)
Parent.x = 3
# 3 2 3
print(Parent.x, Child1.x, Child2.x)
50.参考下面代码片段
class Context:
pass
with Content() as ctx:
ctx. do_ something()
请在Context类下添加代码完成该类的实现
笔记:
面向对象的上下文管理是with语法的具体实现
class Context():
def __enter__(self):
return self
def __exit__(self, exc_type, exc_val, exc_tb):
# 相当于在最后,执行了文件的关闭操作,fp.close()
print("abc123")
def do_something(self):
print(1111)
with Context() as ctx:
ctx.do_something()
print(ctx)
自动实现了关闭操作
with open("文件") as fp:
res = fp.read()
1.如何获取列表中第二大的值?
第一种方法:仅需使用sort()和pop()来实现
list26 = [ 1, 13, 5, 6, 11, 12, 7, 8, 13]
list26.sort() # 先对列表元素按从小到大进行排序
count = list26.count(list26[len(list26) - 1] ) # list26[ len(list26) - 1 ]获得列表中最大元素的下标值,count(……)获得最大元素在列表中出现的次数
c = 0
while c < count: # 使用while循环通过最大值出现的次数决定循环次数
list26.pop() # 使用pop()默认删除列表最后的元素,即最大元素,删除次数取决于循环次数即count()的值
c += 1
print(list26[len(list26) - 1]) # 打印列表最后一个元素,即未删除最大元素之前的第二大值
第二种方法: 仅使用 if 判断和 while 循环
list27 = [ ]
num1 = 0
while num1 < 5:
val1 = int(input("请输入五个数字存入列表: "))
list27.append(val1)
num1 += 1
print("接下来将选出你所输入数字的第二大值:")
max = 0
sec = 0
if list27[0] > list27[1]:
max = list27[0]
sec = list27[1]
else:
max = list27[1]
sec = list27[0]
index = 2
while index < len(list27):
if list27[index] > max:
sec = max
max = list27[index]
index += 1
print(sec)
笔记:
# (1) 所有的容器类型数据都可以通过 sorted (sort只局限于列表进行排序)
# 去重
lst = set([98,1,100,3,-100,50,100,100])
res = sorted(lst)
res_new = res[-2]
print(res_new)
2.简述Python内存管理机制。
引用计数机制、垃圾回收机制、内存池机制
笔记:
# (2) 内存管理机制
计数器,垃圾回收,内存池
# 一.计数器
特点:引用技术如果是0,把这个值从内存中释放掉
a = 100
b = a
print(b)
del b
缺点:在维护引用计数时,又可能数据产生循环引用,造成数据不能删除,造成内存泄漏
lst1 = [1,2]
lst2 = [5,6]
lst1.append(lst2)
lst2.append(lst1)
del lst1
print(lst1)
print(lst2)
# print(lst1)
# print(lst2)
3.简述Python的垃圾回收机制。
Python中的垃圾回收是以引用计数为主,分代收集为辅。引用计数的缺陷是循环引用的问题。 在Python中,如果一个对象的引用数为0,Python虚拟机就会回收这个对象的内存。
笔记:
# 二.垃圾回收:引用计数为主,标记清除和分带回收为辅
标记清除 : 检测标记该对象,避免出现循环引用不能删除的现象
分带回收 :
把内存中的数据分成三个区域: 新生代0,老年代1,永久代2
新生代0数据超过700 , 或者老年代1,永久代2数据超过10,自动触发内存中的垃圾回收机制
新生代0触发将清除所有三代的区域
老年代1触发会清理1,2代
永久代2触发只会清理自己
# 三.内存池
# 在同一个文件当中 (python3.6)
# -->Number 部分
1.对于整型而言,-5~正无穷范围内的相同值 id一致
2.对于浮点数而言,非负数范围内的相同值 id一致
3.布尔值而言,值相同情况下,id一致
4.复数在 实数+虚数 这样的结构中永不相同(只有虚数的情况例外)
# -->容器类型部分
5.字符串 和 空元组 相同的情况下,地址相同
6.列表,元组,字典,集合无论什么情况 id标识都不同 [空元组例外]
# 在不同的文件当中
小数据池 ; 比如整型默认开辟 -5~256 这么多数据提前在内存中驻留
4.请用两个队列来实现一个栈。
public static class TwoQueueStack<E> {
private Queue<E> queueA;
private Queue<E> queueB;
public TwoQueueStack() {
queueA = new LinkedList<>();
queueB = new LinkedList<>();
}
/**
* 选一个非空的队列入队
*
* @param e
* @return
*/
public E push(E e) {
if (queueA.size() != 0) {
System.out.println("从 queueA 入队 " + e);
queueA.add(e);
} else if (queueB.size() != 0) {
System.out.println("从 queueB 入队 " + e);
queueB.add(e);
} else {
System.out.println("从 queueA 入队 " + e);
queueA.add(e);
}
return e;
}
public E pop() {
if (queueA.size() == 0 && queueB.size() == 0) {
return null;
}
E result = null;
if (queueA.size() != 0) {
while (queueA.size() > 0) {
result = queueA.poll();
if (queueA.size() != 0) {
System.out.println("从 queueA 出队 并 queueB 入队 " + result);
queueB.add(result);
}
}
System.out.println("从 queueA 出队 " + result);
} else {
while (queueB.size() > 0) {
result = queueB.poll();
if (queueB.size() != 0) {
System.out.println("从 queueB 出队 并 queueA 入队 " + result);
queueA.add(result);
}
}
System.out.println("从 queueB 出队" + result);
}
return result;
}
}
5.请用Python实现一个链表。
class SingleLinkList(object):
"""单链表"""
def __init__(self):
self.__head = None
def is_empty(self):
"""判断链表是否为空"""
return self.__head == None
def length(self):
"""链表长度"""
# cur初始时指向头节点
cur = self.__head
count = 0
# 尾节点指向None,当未到达尾部时
while cur != None:
count += 1
# 将cur后移一个节点
cur = cur.next
return count
def travel(self):
"""遍历链表"""
cur = self.__head
while cur != None:
print cur.item,
cur = cur.next
print ""
6.请用Python实现链表的逆转。
1、单链表结构
2、反转的想法
建立三个变量,L、M、R互相赋值迭代,并建立指向关系,从而实现单链表的反转。
3、python代码实现
class Node(object):
def __init__(self, data, next=None):
self.val = data
self.next = next
def fun4(head):
if head == None:
return None
L,M,R = None,None,head
while R.next != None:
L = M
M = R
R = R.next
M.next = L
R.next = M
return R
#测试用例
if __name__ == '__main__':
l1 = Node(3)
l1.next = Node(2)
l1.next.next = Node(1)
l1.next.next.next = Node(9)
l = fun4(l1)
print (l.val, l.next.val, l.next.next.val, l.next.next.next.val)