Python常见面试题

0、Python是什么?

  • Python是一种解释型语言。但是跟C和C的衍生语言不同,Python代码在运行之前不需要编译。其他解释型语言还包括PHP和Ruby。
  • Python是动态类型语言,指的是在声明变量时,不需要说明变量的类型。可以直接编写类似x=111x="Hello World"这样的代码,程序不会报错。
  • Python是一门强类型语言,是指不容忍隐式的类型转换,比如字符串类型的数字和整型的数字进行比较不会成立。
  • Python非常适合面向对象的编程(OOP),因为它支持通过组合(composition)与继承(inheritance)的方式定义类(class)。
  • 在Python语言中,函数是第一类对象(first-class objects)。这指的是它们可以被指定给变量,函数既能返回函数类型,也可以接受函数作为输入。类(class)也是第一类对象。
  • Python代码编写快,而运行速度比编译语言通常要慢。但是Python允许加入基于C语言编写的扩展,也常被用作“胶水语言”。因此我们能够优化代码,消除瓶颈。比如说numpy就是一个很好地例子,它的运行速度非常快。
  • Python用途非常广泛——爬虫、Web 程序开发、桌面程序开发、自动化、科学计算、科学建模、大数据应用、图像处理、人工智能等等。
  • Python包含八种数据类型:字符串、元组、字典、列表、集合、布尔类型、整型、浮点型。拥有三大特性:封装、继承、多态。最显著特点是采用缩进/4个空格(不能混用)表示语句块的开始和结束。
  • Python的标识符命名规则有:可以由字母下划线数字组成,不能以数字开头,不能与关键字重名,不能含有特殊字符和空格,使用大驼峰、小驼峰式命名。Python区分大小写

_单下划线开头:声明为私有变量,通过from M import * 方式将不导入所有以下划线开头的对象,包括包、模块、成员。
单下划线结尾_:为了避免与python关键字的命名冲突。
__双下划线开头:模块内的成员,表示私有成员,外部无法直接调用
__双下划线开头双下划线结尾__:指那些包含在用户无法控制的名字空间中的“魔术”对象或属性,如类成员的name 、doc、init、import、file、等。
表达式:算术运算符  + - * / // %   ; 比较运算符 >  <  >=  <= !=  ; 逻辑运算符 and or not ;判断是否为同一对象:is、is not ; 判断是否属于另一个对象: in  、not in。
函数支持递归、默认参数值、可变参数、闭包,实参与形参之间的结合是传递对象的引用。另外还支持字典、集合、列表的推导式。

Python3中的print函数代替Python2的print语句
Python3中的Str类型代表Unicode字符串,Python2中的Str类型代表bytes字节序列
Python3中的 / 返回浮点数,Python2中根据结果而定,能被整除返回整数,否则返回浮点数
Python3中的捕获语法 except exc as var 代替Python2中的 except exc, var  

1、Python新式类&旧式类的区别

Python2中默认都是旧式类,除非显式继承object才是新式类; Python3中默认都是新式类,无需显式继承object。

 新式类对象可以直接通过__class__属性获取自身类型:实例对象a1.__class__ 、type(实例对象a1)结果为:<class '__main__.A1'>; 旧式类为 __main__.A、<type 'instance'>

 多继承时,经典类搜索父类的顺序: 先深入继承树左侧,再返回开始找右侧,菱形搜索,深度优先搜索(MRO算法); 新式类搜索父类的顺序: 先水平搜索,然后再向上移动,广度优先搜索(C3算法)。

 新式类增加了__slots__内置属性, 可以把实例属性的种类锁定到__slots__规定的范围之中。

 新式类增加了__getattribute__方法

2、如何在一个函数内部修改全局变量  

a = 10    

def info():
  print(a)

def foo():
  global a
  a = 22
  print(a)

print(a)
info()
foo()

# 经过foo函数的修改,a的值已变为22
print(a)
info()

3、列出5个python标准库

标准库:sys、os、re、urllib、logging、datetime、random、threading、multiprocessing、base64
第三方库:requests、Scrapy、gevent、pygame、pymysql、pymongo、redis-py、Django、Flask、Werkzeug、celery、IPython、pillow

4、字典如何删除键和合并两个字典

di = {"name": "power"}
ci = {"age": 18}

# 删除键
del di["name"]

# 合并字典
di.update(ci)

5、python实现列表去重的方法

li = [2, 2, 1, 0, 0, 1, 2]

# 方法一:使用set方法
sl = list(set(li))


# 方法二:额外使用一个列表
li2 = list()
for i in li:
    if i not in li2:
        li2.append(i)
      

# 方法三:使用列表的sort方法
l1 = ['b','c','d','c','a','a']
l2 = list(set(l1))
l2.sort(key=l1.index)
print(l2)

l1 = ['b','c','d','c','a','a']
l2 = sorted(set(l1),key=l1.index)
print(l2)

 

6、一句话解释什么样的语言能够用装饰器?

装饰器本质上是一个Python函数,他可以让其他函数在不需要做任何代码改动的前提下额外增加功能,装饰器接收一个函数作为参数,返回值也是一个函数。
谁可以用:函数可以作为参数传递的语言,就可以使用装饰器。
作用:在不改变源代码的情况下添加新的功能。
使用场景:插入日志、性能测试(计算函数运行时间)、事务处理(让函数实现事务的一致性)、缓存、权限校验等场景

问题:函数A接收整数参数n,返回一个函数B,函数B是将函数A的参数与n相乘后的结果返回

def info(func):
  def foo(n):
    res = func(n)
    return res * n
  return foo

@info
def func(n):
  return n

func(2)
[Out]: 4

7、python内建数据类型有哪些 

# 不可变类型
int      整形
str      字符串
float    浮点型
tuple  元组


bool   布尔型 



# 可变类型
list     列表
dict    字典
      

8、简述面向对象中__new__和__init__区别

1、__new__必须接收一个名为 cls 的参数,代表的是当前类对象。
2、__new__必须有返回值,返回的是由当前类对象创建的实例对象,而__init__什么都不返回。
3、__init__必须接收一个名为 self 的参数,代表的是由__new__方法所创建的实例对象。
4、只有在__new__方法返回一个 cls 的实例时,后面的__init__才能被调用。
5、当创建一个新实例对象是,自动调用__new__方法, 当初始化一个实例时调用__init__方法。

ps: __metaclass__ 是创建类时起作用.所以我们可以分别使用__metaclass__,__new____init__来分别在类创建,实例创建和实例初始化的时候做一些小手脚.

9、进程&线程&协程?

1、进程多与线程进行比较

  • 线程是CPU真正调度的单位,也是进程内的一个执行单元,进程是系统资源分配的基本单位;
  • 一个进程内至少有一个线程,同一个进程内的线程共享进程的资源,而进程有自己独立的地址空间,每个进程各自有独立的资源互不干扰。
  • 每个独立的线程必须有一个程序运行的入口、顺序执行序列和程序的出口,但是线程不能够独立执行,必须依存在进程当中。
  • 不仅进程之间可以并发执行,同一个进程的多个线程之间也可以并发执行。
  • 多线程的意义在与一个应用程序中,有多个执行部分可以同时执行。但操作系统并没有将多个线程看做多个独立的应用,来实现进程的调度和管理以及资源分配。这就是进程和线程的重要区别。

2、协程与线程进行比较

  •  一个线程内可以有多个协程,一个进程也可以单独拥有多个协程,这样python中则能使用多核CPU。
  • 线程进程都是同步机制,而协程可以选择同步或异步。
  • 协程能保留上一次调用时的状态,每次过程重入时,就相当于进入上一次调用的状态。

10、列表[1,2,3,4,5],请使用map()函数输出[1,4,9,16,25],并使用列表推导式提取出大于10的数,最终输出[16,25]

li = [1, 2, 3, 4, 5]

def info(x):
    return x**2

li2 = [i for i in map(info, li) if i > 10]

11、python中生成随机整数、随机小数、0--1之间小数方法

import random
import numpy as np

# 随机整数
print(random.randint(0, 99999))

# 随机小数
print(np.random.randn())

# 随机 0-1 小数
print(random.random())

12、避免转义给字符串加哪个字母表示原始字符串?

import re

a = 'power.top*one'

res = re.match(r'.*', a)

print(res)

# 注:r 只针对于Python代码生效,与re正则并无关系

13、<div class="nam">中国</div>,用正则匹配出标签里面的内容(“中国”),其中class的类名是不确定的

import re

a = '<div class="nam">中国</div>'

res = re.match(r'<div class=".*">(.*)</div>', a)
res.group(1)


res = re.findall(r'<div class=".*">(.*)</div>', a)
print(res[0])

14、python中断言方法举例

15、数据表student有id,name,score,city字段,其中name中的名字可有重复,需要消除重复行,请写sql语句

select distinct  name from student

 

16、10个Linux常用命令

cd、ls、cp、mv、mkdir、touch、cat、grep、echo、pwd、more、tar、tree

 

17、python2和python3区别? 

1、Python3 使用 print 必须要以小括号包裹打印内容,比如 print('hi')
   Python2 既可以使用带小括号的方式,也可以使用一个空格来分隔打印内容,比如 print 'hi'

2、python3的range 返回可迭代对象,python2的range返回列表,xrange返回迭代器
  for ... in 和 list() 都是迭代器
3、python2中使用ascii编码,python中使用utf-8编码 

4、python2中unicode表示字符串序列,str表示字节序 python3中str表示字符串序列,byte表示字节序列 

5、python2中为正常显示中文,引入coding声明,python3中不需要 

6、python2中是raw_input()函数,python3中是input()函数

 


18、列出python中可变数据类型和不可变数据类型,并简述原理

可变类型: 列表、字典

不可变类型:字符串、整型、浮点型、元组


19、s = "ajldjlajfdljfddd",去重并从小到大排序输出"adfjl"

s = "ajldjlajfdljfddd"

# set方法
li = list(set(s))
li.sort()        # 注:sort 没有返回值


# 循环遍历
li2 = []
for i in s:
    if i not in li2:
        li2.append(i)
li2.sort()

20、用lambda函数实现两个数相乘

nu = lambda x, y: x*y

nu(2, 3)


lambda 函数是一个可以接收任意多个参数(包括可选参数)并且返回单个表达式值的函数。

1、lambda函数比较轻便,即用即扔,很适合的场景是,需要完成一项功能,但此功能只在此一处使用,连名字都很随意的情况下。
2、匿名函数,一般用来给 filter、map 这样的函数式编程服务。
3、作为回调函数,传递给某些应用,比如消息处理。

21、字典根据键从小到大排序

dict(sorted(di.items(), key=lambda x: x))


22、利用collections库的Counter方法统计字符串每个单词出现的次数"kjalfj;ldsjafl;hdsllfdhg;lahfbl;hl;ahlf;h"

from collections import Counter

s = "kjalfj;ldsjafl;hdsllfdhg;lahfbl;hl;ahlf;h"

Counter(s)

# 输出结果
Counter({'l': 9, 'h': 6, ';': 6, 'f': 5, 'a': 4, 'd': 3, 'j': 3, 's': 2, 'b': 1, 'g': 1, 'k': 1})

23、字符串a = "not 404 found 张三 99 深圳",每个词中间是空格,用正则过滤掉英文和数字,最终输出"张三  深圳

import re

a = "not 404 found 张三 99 深圳"

# 第一种方式
res = re.sub('[^\u4e00-\u9fa5]', '', a).split()
print(res)


# 第二种方式
value = re.findall(r'[^a-zA-Z\d\s]+', a)
print(''.join(value))

24、filter方法求出列表所有奇数并构造新列表,a =  [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

# filter(function, iterable)      function -- 判断函数。 iterable -- 可迭代对象。

a =  [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]


def info(x):
    
    if x % 2 == 1:
    
        return x


print(list(filter(info, a)))


25、列表推导式求列表所有奇数并构造新列表,a =  [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

li = [i for i in a if i % 2 == 1]

26、正则re.complie作用

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

 

27、a=(1,)b=(1),c=("1") 分别是什么类型的数据?

元组 : a=(1,)

整型 :b=(1)

字符串 : c=("1")

28、两个列表合并为一个列表

#[1,2,5,6,7,8,9]

li1 = [1,5,7,9]
li2 = [2,2,6,8]

# 第一种方法
li3 = list(set(li1 + li2))
print(li3.sort())

# 第二种方法
li1.extent(li2)
li5 = list(set(li1))
li5.sort()
print(li5)

# 第三种方法
li6 = li1 + li2
print(li6)

29、用python删除文件和用linux命令删除文件方法

python:   os.remove(文件名)
linux:       rm  文件名

30、log日志中,我们需要用时间戳记录error,warning等的发生时间,请用datetime模块打印当前时间戳 “2018-04-01 11:38:54”

from datetime import datetime

print(datetime.now().strftime("%Y-%m-%d %H:%M:%S"))

print(datetime.strftime(datetime.now(), "%Y-%m-%d %H:%M:%S"))


# Out[12]: '2019-03-30 18:57:55'


logging模块的日志等级:

DEBUG    最详细的日志信息,典型应用场景是:问题诊断

INFO     信息细程度仅次于DEBUG,通常只记录关键节点信息,用于确认一切都是按照我们预期的那样进行工作

WARNING   当某些不期望的事情发生时记录的信息(如,磁盘可用空间较低),但是此时应用程序还是正常运行的

ERROR     由于一个更严重的问题导致某些功能不能正常运行时记录的信息

CRITICAL   当发生验证错误,导致应用程序不能继续运行时记录的信息

logging.debug('debug message')
logging.info('info message')
logging.warn('warn message')
logging.error('error message')
logging.critical('critical message')  

31、写一段自定义异常代码

li = [1, 2, 3, 0]

for i in li:
    try:
        if i == 0:
            raise Exception("遍历得到0")
    except Exception as e:
        print(e)

32、正则表达式匹配中,(.*)和(.*?)匹配区别?

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

33、[[1,2],[3,4],[5,6]]一行代码展开该列表,得出[1,2,3,4,5,6]

li = [[1, 2], [3, 4], [5, 6]]

lis = [j for i in li for j in i]

34、x="abc",y="def",z=["d","e","f"],分别求出x.join(y)和x.join(z)返回的结果

x="abc"

z=["d","e","f"]

y="def"


x.join(y)
# Out[202]:'dabceabcf'

x.join(z)
# Out[202]: 'dabceabcf'

35、举例说明异常模块中 try except else finally 的相关意义

li = [1, 2, 3, 0]

for i in li:
    try:
         if i == 0:
             raise Exception("遍历得到0")
     except Exception as e:
         print(e)
     else:
         print(i)
     finally:
         print("顺利跑完")
 

# Out[28]:
1
顺利跑完
2
顺利跑完
3
顺利跑完
遍历得到0
顺利跑完


try: 放置可能出现异常的代码
except: 当出现异常时,执行此处代码
else: 当程序没有没有出现异常时,执行此处代码
finally:  不管程序是否出现异常,此处代码都会执行

36、举例说明zip()函数用法

37、a="张明 98分",用re.sub,将98替换为100

res = re.sub(r'\d+', '100', a)
print(res)

38、写5条常用sql语句

# 增
insert into student (name, age) values ("power", 22);

# 删
delete from student where name="power";

# 改
update student set age=12 where name="power";

# 查
select name from student where id=2;

39、简述ORM

O  模型类对象    R 关系    M 映射    :    模型类对象和数据库的表的映射关系


ORM拥有转换语法的能力,没有执行SQL 语句的能力,执行SQL语句需要安装数据库驱动(python3解释器需安装PyMySQL, python2解释器需安装mysql)django只能识别mysqldb驱动,需要给pymysql起别名骗过django

ORM作用:
1. 将面向对象的操作数据库的语法转换为相对应SQL语句
2. 解决数据库之间的语法差异性(根据数据库的配置不同,生成不同的SQL语句) 

40、a="hello"和b="你好"编码成bytes类型

a="hello"
print(b'a')

b="你好"
print(b.encode())

  

41、提高python运行效率的方法

1、使用生成器,因为可以节约大量内存。 

2、循环代码的优化,避免重复执行循环代码。
 
3、核心模块用Cython  PyPy等,提高效率。
 
4、对于不同场景使用多进程、多线程、协程,充分利用CPU资源。
 
5、多个if elif条件判断,将最有可能先发生的条件放到前面写,可减少程序判断的次数。

42、遇到bug如何处理 

0、查看报错信息(错误日志信息),分析bug出现原因。

1、在接口的开头打断点,单步执行往下走,逐渐缩小造成bug的代码范围。

2、【可选】在程序中通过 print() 打印,能执行到print() 说明一般上面的代码没有问题,分段检测程序是否有问题,如果是js的话可以alert或console.log

2、若自己无法解决,利用搜索引擎将报错信息进行搜索。

3、查看官方文档,或者一些技术博客。

4、查看框架的源码。

5、对于bug进行管理与归类总结,一般测试将测试出的bug用teambin等bug管理工具进行记录。

43、正则匹配,匹配日期2018-03-20

a= 'aa20kk18-power03-30oo'

res = re.findall(r'[-\d]+', a)
data = ''.join(res)
print(data)

Out[82]: '2018-03-30'

44、list=[2,3,5,4,9,6],从小到大排序,不许

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值