python常见面试题(1)

Python 面试题:

  1. 求和 sum(range(0,101))
  2. 如何在一个函数内部修改全局变量 :gbobal
  3. Python的标准库:os:提供与操作系统相关的函数 sys:用于命令行参数  re:正则匹配 math:数学运算 datetime:处理时间日期
  4. 字典如何删键和合并两个字典:删除键:del dic[键] 合并两个字典:update:合并两个字典
  5. Python的GIL 全局解释锁
  6. Python实现列表去重:转集合 再转列表
  7. Python2和python3 对range(100)的区别:前者返回列表 后者返回迭代器 节约内存
  8. 什么样的语言可以做装器:函数可以作为参数传递的语言,可以使用装饰器
  9. Python内建的数据类型:(整型 浮点型 布尔型)数值 字符串 列表 集合 元组 字典
  10. 简述面向对象中__init__和__new__的区别:
  1. __new__至少有一个参数cls,代表当前类 必须要有返回值
  2. __init__有一个参数self 就是__new__的实例 不需要有返回值
  3. 如果__new__创建的是当前类的实例,会自动调用__init__函数
  1. 简述with方法打开处理文件帮我们做了什么:

如果打开的文件有异常出现,需要用try,except,finally 执行关闭文件的操作,with方法帮我们实现了f.close( )

  1. 内置函数的比如map(1,2)1:是函数的名字(参数)2:一个迭代器
  2. 列表推导式:[i for i in range(10) if 条件]
  3. Python中生成随机整数:random.randint(a,b):生成a-b区间内的整数
  4. Python中生成随机小数:np.random.randn(5):生成五个随机小数
  5. Python中随机生成-0-1之间的小数:random.random( )  导入一个包 import numpy as np
  6. 避免转义可以给字符串前面加 “r”,需要原始字符串,不转义字符
  7. Python中断言(assert)
  8. Python2和Python3的区别:
  1. python3中print必须要以小括号包裹打印的内容 python2既可以使用带小括号的方式,也可以使用一个空格来分隔打印的内容 print ‘hello’
  2. 对于range(x):前者返回列表 后者返回迭代器 节约内存
  3. 编码格式:前者使用ascii编码 后者使用utf-8编码
  4. 字节和字符串:前者用Unicode表示字符串序列,用str表示字节序列,后者用str表示字符串序列,用byte表示字节序列
  5. 中文显示:前者得引入coding声明,后者直接可以直接显示中文
  6. 输出:前者是raw_input( )函数 后者是input( )函数

20.可变数据类型和不可变数据类型:

1)不可变数据类型:字符串 数值 元组tuple:如果改变了变量的值,相当于是新建了一个对象,对于相同的值的对象,则内存中只有一个地址

2)可变数据类型:列表 字典 增加append( ) 只是改变了变量的值,而不会新建一个对象,变量的引用地址也不会发生变化,对于相同值的不同对象,内存中会存在不同的对象,每个对象都有对应的地址,相当于内存中对于相同值的对象保存了多份,不存在引用,都是实实在在的对象

21.去重 使用set集合 sort 排序

22.a = lambda 参数1,参数 2:条件  a( 参数1,参数2 )

23.字典根据键从小到大排序

24.统计出现次数:collections库中的Counter方法

25.re.cpmplie:将正则表达式编译成一个对象,加快速度,并重复使用

26.Python删除文件:os.remove(文件名)   linux: rm 文件名

27.正则表达式:

(.*):贪婪匹配,会把满足正则的尽可能多的往后匹配

(.*?):非贪婪匹配,回吧满足正则的尽可能少的匹配

  1. numpy as np :矩阵   随机生成在一组在一个范围内的数字 random.randint(a,b,(设置矩阵模式))
  2. try...except...else:没有捕获到异常,执行else语句

   try...except...finally:不管是否捕获到异常,都执行finally语句

  1. zip( )函数的使用:会以一个或多个序列(可迭代对象)作为参数,返回一个元组的列表,当参数长度不一致时,zip自动以最短序列长度为准进行截取,获取元组

a = [2,3]

b = [1,4]

c = [i for i in zip(a,b)]

Print(c)  生成结果[ ( 2 , 1 ) , ( 3 , 4 ) ]

  1. 正则表达式中re.sub:表示替换的意思 (匹配规则,要被替换的str,被处理的字符串)
  2. 转化成bytes类型,需要使用encode
  3. 两个列表项加等价于extend:列表末尾一次性追加另一个序列中的多个值
  4. 冒泡排序法:i和 j  互换一下位置即可
  5. Session和cookie区别:

Cookie的安全性比session差

Session存在于服务器端 cookie存在于客户端

Session的运行依赖于session_id,而session_id存在于cookie中,如果cookie被禁用了,session也将会失效

  1. 浅拷贝和深拷贝:

浅拷贝:只复制指向某个对象的指针,不复制对象本身,内存地址不会变,共享

深拷贝:会创建一个我一模一样的对象,新对象和旧对象不共享内存,修改其不会改变

如果拷贝的对象中没有引用,深浅都一样

如果拷贝的对象中有引用,浅拷贝拷贝的是对象的引用,如果对新对象中的引用值进行修改,旧对象还是会跟着改变,深拷贝则会完全拷贝一份,修改其中的值不会对其源对象产生影响,相当于是新建了一个列表,里面放的实心列表的引用

  1. 不使用sort sorted方法,将列表排序
  1. 冒泡排序法
  2. 直接使用求列表中的最小值取出来加入到一个新列表
  1. 函数中参数传递:
  1. 值传递:用于不可变对象的的的传递(数值,字符串,元组)
  2. 引用传递:用于可变对象的传递(列表,字典)
  3. 区别:当形参的值发生变化后,值传递不影响实际参数的值,引用传递,实参的值也会一起变化。
  1. 对于不可变对象,调用了对象本身的任意方法,也不会改变对象本身的内容。相反,这些方法会创建新的对象并返回一个,这样就保证了不可变对象本身是永远不可变的。
  2. 如何判断一个对象是可迭代对象?

通过collections模块中的iterable类型判断

41.IsDigit和IsNumber的区别?

  1. 第一个判断是不是整数
  2. 第二个判断是不是数字

42.列表中sort和sorted的区别:

Sort是list的方法,返回值为none  Revrese 默认升序False  不返回新列表

Sorted是python的内置函数,返回值是一个新列表,不影响原来的顺序

  1. 切片法生成一个新列表  
  2. Pyton是如何进行内存管理的?从三个方面来说,
  1. 对象的引用计数机制
  2. 垃圾回收机制
  3. 内存池机制
  1. 数字、字符串、元组是不可变的,列表、字典是可变的。
  2. 乘法口诀表:

print("\n".join('\t'.join(["{}*{}={}".format(y,x,x*y) for y in range(1,x+1)]) for x in range(1,10)))

  1. 字典的五种创建方式:
  1. 通过另一个字典
  2. 通过关键字参数创建(name = ‘jjj’,age = ‘jjjj’)
  3. 通过键值对的序列创建 dic = dict( [ ( 1 , abc ),( 2 , def ) , ( 3 , ghi ) ])
  4. 通过dict和zip的结合 简单来说就是将两个列表组合起来,一个列表包含键一个包含值
  5. 使用花括号{ }创建
  1. fromkeys创建字典: dic = dict.fromkeys ( [ ‘ a ’ , ’ b ’ ] , 3) 将a和b的值都设置为3
  2. 如何以就地操作方式打乱一个列表的元素?

为了达到这个目的,我们从random模块中导入shuffle()函数。

  1. 把一个字符串中出现次数多的那个只能输出一次

  1. 多线程访问时,如何避免重读?

创建一个数据列表,把访问过的数据放进去,并且加上互斥锁,访问的时候,判断是否在数据列表中出现过。

  1. 带参数的装饰器

  1. @property:实现了一个getter的功能 将属性名和方法名一定要分开,必须在setter之前

广泛用于类的定义中,把方法变成属性,保证对参数进行必要的检查,降低错误

只有@property:可读 加setter 就可以可读可修改

  1. 生成器和生成式的区别:
    1. 从内存上分析:后者手内存限制,列表的容量是有限, 后者不是立即把结果写入内存,而是保存的一种计算方式
    2. 语法来看:() [ ]
    3. 返回值:前者逐个调用输出  后者生成列表

  1. 数据库设计的三范式:
    1. 保持数据的原子性 字段不可分割
    2. 消除部分依赖(确保表中每列都和和主键有关系) 非主键必须依赖主键
    3. 表中的字段不存在对之间的传递依赖(确保每列和主键是直接关系 不是间接关系)

非主键字段之间不能相互依赖

  1. 二叉树的四种遍历算法: 满二叉树 完全二叉树
    1. 先序遍历

根节点》左子树》右子树 0-1-3-4-2-5-6

    1. 中序遍历

左子树》根节点》右子树3-1-4-0-5-2-6

    1. 后序遍历

左子树》右子树》根节点 3-4-1--5-6-2-0

    1. 层序遍历   队列的数据结构

从上往下一次从左至右 0-1-2-3-4-5-6

  1. 类方法和静态方法:
    1. 修饰符 classmethod  staticmethod
    2. 参数:cls 前者类和实例化对象都可以调用 后者无参数 都可调用
    3. 类方法传递类的属性和方法 不能传递实例的

  1. 单引号 双引号 三引号的区别:

单引号和多引号没什么太大区别,表示字符串的时候,单引号里面可以用双引号,而不用转义。如果用单引号括住单引号,得加转义字符 \   三引号一般用于直接书写多行,大篇幅的字符串

  1. python的垃圾回收机制:

主要以引用计数为主,标记清除和分代回收为辅助机制,后者主要用于处理循环引用的难题

引用计数: 有一个变量 引用计数+1,使用del一次会减少引用计数的数值一次,当引用计数为1,调用del就会把对象直接删除

  1. 提取excel中的数据

注意:df[里面的字段可以用list(df)]   因为输出df的时候 输出的是表格中的标题 也就是字段名

Mysql:

  1. 数据库的四大特性:

①原子性

事务包含的所有操作,要么全部执行,要么全部失败回滚

②一致性

事务开始前后,数据的完整性约束没有被破坏

③隔离性

多个并发事务之间不相互干扰。

④持久性

事务一旦被提交,对数据库中数据的改变就是永久的

  1. 事务的隔离级别:通过事务隔离属性来确定

事务的并发导致的问题:

脏读:事务a读取了事务b提交修改的数据,b事务回滚,a读取的数据时脏数据

不可重复度:a事务多次读取同一数据,事务b在事务a读取数据时修改了数据,导致a事务两次读取的数据不一致

幻读:事务a对一个数据表中的数据从1修改为2,同一时间事务b又对数据进行修改为1,导致a督导的结果还是1.就好像出现了幻读

3事务的隔离级别需要得到数据库底层引擎的支持

Oracle支持的两种事务隔离界别:读提交   可串行化

隔离界别越高,越能保证数据的完整性和一致性,但是对并发性能的影响也越大

一般设置为读提交级别,虽然会出现不可重复度和幻读,此时可以采用乐观锁和悲观锁控制

4接下来就该谈到悲观锁和乐观锁:

悲观锁的特点:先获取锁,然后再进行业务操作,需要数据库本身支持,使用select updata即可获得悲观锁

乐观锁:先进行业务操作,不到万不得已不获取锁,加锁方式:给表加一个版本号

5Mysql常见的三大引擎:myisam innodb memory

如果是查询操作,采用myisam会性能高,

因为在innodb中存在事务,可以让一些增删改操作可以回滚,

Innodb支持行锁,在某些情况下还是表锁:

例如 updat 。。。From 。。 where 字段 like ‘%xx%’;

Where是主键操作才会使用到行锁

在myisam中有三张表: 一个是存数据 一个是保存表的结构 一个是保存索引

Memory是把数据存储在内存中的,如果内存出现问题,会造成数据流失。 梳理数据能力高

6临时表:只在当前连接可见,关闭连接后,mysql会自动删除释放内存,

7Hash索引:索引检索效率高,

B+tree:需要重根节点到子节点再到叶子节点,

8为什么用hash索引少:

因为hash索引只能精确查询,对于一些范围查询,hash每次的运算结果都不能保证一致

9 两者区别:

如果是等值查询,则会采用hash索引,(通过键值查找,前提是键值唯一)

一般范围查询,分组,排序 采用B+TREE

10 聚集索引和非聚集索引的区别:表记录的排列顺序和索引的排序是否一致

慢查询:

Reduce函数的工作原理:

Reduce函数接受一个函数和一个序列,然后对序列进行迭代,每次迭代,当前元素和前一个元素的输出都传递给函数,最后返回一个值。

From  functools import reduce

Def add_three(x,y):

returnx+y

li=[1,2,3,5]

reduce(add_three,li)

==>:11

Map的工作原理:

返回一个列表,该列表由序列中的每个元素对函数应用时返回的一个值。

Filter的工作原理:

序列中的每个值都对函数作用,如果函数返回True,则把相应的元素加入到返回的列表序列

解释python是按值调用还是按引用调用::

对于不可变类型,在函数内部对其进行修改,不会影响其在函数外部的值,也就是说在函数内外的不可变类型被修改时不会互相影响

对于可变数据类型,在函数内部改变他的值,在函数外部他的值也会跟着变。

对于__xx:的属性或者方法 对外是不能会直接访问的,要想访问:_类名__xx来访问

单例模式:

Cookie的原理:

首先弄清楚传输数据的两个方向  浏览器端和服务端

  1. 浏览器给服务端第一次发送请求request
  2. 服务端创建cookie,在这个cookie中包含用户的信息,然后将该cookie返回给浏览器
  3. 浏览器再次访问服务端的时候会携带之前的cookie
  4. 服务端通过携带的数据的不同来区分用户

将数据保存在客户端,不安全

只要不关闭浏览器,cookie值永远不会失效  

数据量:3K

Session原理:

  1. 浏览器第一次想服务端发送请求,服务端会自动创建一个session,同时也会创建一个特殊的cookie 会携带一个session的唯一标识,session_key,  然后将该cookie对象发送到浏览器
  2. 浏览器多次请求服务端,会一直携带这个session_key
  3. 服务端根据session_key中的value(session_id)值去区分不同的用户

将数据保存在服务端,数据相对安全。

Session还在一定时间上保存在服务器上,比较占用服务器性能

应用场景: 用户登录后退出的权限管理

一些登录的信息可以存放在session中  不重要的信息保存在cookie中

session_key = request.COOKIES.get('sessionid')

技术栈:

前端 :PC端 :javascript

后端 : python

中间件:数据库mysql  https

运维:git 版本控制 maven

工具:开发工具 pycharm navicate 测试自动化 selenium  抓包

Python多线程  多进程 使用场景:

多进程: cpu密集型 (计算密集型)操作

当cpu进行上万亿的加减乘除计算时,使用多核cpu来提高计算性能

From multiplyprocessing import Process

多线程:IO密集型操作

From Threading  import Thread

输出 输出的操作 文件的读取 网络请求

因为这些操作一般会遇到程序阻塞的问题,使用多核cpu对性能的提升不会很大

ORM:Object Relational Mapping对象关系映射,

它的作用是在关系型数据库和对象之间作一个映射,这样,我们在具体的操作数据库的时候,就不需要再去和复杂的SQL语句打交道,只要像平时操作对象一样操作它就可以了 。

优势:ORM提供了对数据库的映射,不用直接编写SQL代码,只需像操作对象一样从数据库操作数据。提高了开发效率。

劣势:ORM的缺点是会在一定程度上牺牲程序的执行效率。

生成订单号的格式:

格式化时间 : %Y年%m月%d日%H时%M分%S秒%f毫秒
格式化输入九位数字左边缺少的补0: %09d
timezone.localtime():django自带的时间 时区随settings.py文件内设置的而定

order_id = timezone.localtime().strftime('%Y%m%d%H%M%S%f') + ('%09d' % user.id)

生成订单编号:

订单表关联用户和收货地址 一个用户可以有多个订单 一对多

订单商品表关联订单表和商品表 一个订单可以有多个商品 一对多

悲观锁的应用场景:

悲观锁相对于进程锁来说:针对于同一块公共资源来说,如果想获取公共资源,就必须要先获得锁,才可以对该资源进行操作,在锁释放了之后,其他进程那上锁才能对其进行操作

比如:对于想修改商品的库存时,为了防止其他进程对该操作的影响,操作室需要先获取一个锁,(修改首先需要查询到,然后就把该进程加一个悲观锁,进行锁定,没有锁的话只能进行等待)

如何获取悲观锁:

select * from df_goods_sku where id=17 for update;

乐观锁:

针对于查询和更新操作:查询不加锁,更新需要加锁,因为在查询的时候不认为其他用户会抢夺资源,不加锁,更新的时候需要判断库存量。判断和查询的时候是否一致。

八大数据结构:

  1. 数组

数组是连续的内存结构,

优点: 查询时候根据索引快

缺点:一旦固定就不能扩容

         只能存储一种数据结构

  删除,添加慢因为需要动其他元素 相当于给其他的元素重新分配内存

  1. 链表

每个元素包含两个子节点:一个是储存元素的数据结构,另一个是指针指向下一个节点的内存地址

缺点:含有大量指针,占用内存,查找耗时,需要遍历链表

优点:容量大  修改快

完全二叉树:叶子节点只会出现在最后两层,最后一层的叶子节点都向左靠齐

先进后出,一般用于递归  场景: 斐波那契数列

  1. 散列表

可以根据键值映射到集合中的一个位置,快速查找

  1. 队列

先进先出  线性表  场景:多线程阻塞队列管理

有向图 和无向图  垃圾处理机制里面的查找引用

比较折中方案

满二叉树: 节点要么为0 要么为2 所有的叶子节点都出现在最后一层

文件缓存:

 设置缓存settings.py

Caches{

}

需要加一个装饰器  from django.view

数据库缓存:db.Databasecache

首先生成表格:

Python manage.py createcachetable djcache  

  1. 下载安装包
  2. memcached.exe -d install

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值