Python后端面试准备之python基础之基础

1. Python文件存储知识
Q1. 4G内存怎么读取5G的数据?
  1. 使用生成器

    可以通过生成器分多次读取,每次读取数量相对少的数据进行处理,处理结束后再读取后面500MB的数据。

  2. linux命令split切割成小文件

    linux命令split切割切割成小文件,再对数据进行处理,此方法效率搞,可以按照数据行切割,也可以按照文件大小切割。https://blog.csdn.net/mxgsgtc/article/details/12048919

Q2. read、readline和readlines的区别?

read: 读取整个文件。

readline: 读取下一行,使用生成器的方法。

readlines: 读取整个文件到一个迭代器以供我们遍历。

Q3. 使用递归输出一个文件夹中的所有文件夹名称
def print_directory_contents(sPath):
    import os
    for sChild in os.listdir(sPath):
        sChildPath = os.path.join(sPath, sChild)
        if os.path.isdir(sChildPath):
            print_directory_contens(sPath):
        else:
            print(sChildPath)
Q4.在except中return后还会不会执行finally中的代码?怎么抛出自定义异常?

会继续处理finally中的代码;用raise方法可以抛出自定义异常。

Q5. 介绍一下except的作用和用法?

except: #捕获所有异常
except: <异常名>: #捕获指定异常
except:<异常名1, 异常名2> : 捕获异常1 或者异常2
except:<异常名>,<数据>:捕获指定异常及其附加的数据
except:<异常名 1,异常名 2>:<数据>:捕获异常名 1 或者异常名 2,及附加的数据

Q6. 赋值、浅拷贝和深拷贝的区别?

一. 赋值

在Python中,对象的复制就是简单的对象引用,这点和C++不同,如下所示:

a = [1,2,"helo",['python','c++']]
b = a

在上述情况下,a和b是一样的,他们指向同一片内存,b不过是a的别名,是引用。我们可以使用b is a去判断,返回True,表明他们地址相同,内容相同,也可以使用id()函数来查看两个列表的地址是否相同。
赋值操作(包括对象作为参数、返回值)不会开辟新的内存空间,它只是复制了对象的引用。也就是说除了b这个名字之外,没有其他的内存开销。修改了a,也就影响了b,同理,修改了b,也就影响了a。

二. 浅拷贝

浅拷贝会创建新对象,其内容非原对象本身的引用,而是原对象内第一层对象的引用。
浅拷贝有三种形式:切片操作、工厂函数、copy模块中的copy函数。
比如上述的列表a;
切片操作:b = a[:] 或者 b = [x for x in a];
工厂函数:b = list(a);
copy函数:b = copy.copy(a);

浅拷贝产生的列表b不再是列表a了,使用is判断可以发现他们不是同一个对象,使用id查看,他们也不指向同一片内存空间。但是当我们使用id(x) for x in a 和 id(x) for x in b来查看a和b中元素的地址时,可以看到二者包含的元素的地址是相同的。
在这种情况下,列表a和b是不同的对象,修改列表b理论上不会影响到列表a。
但是要注意的是,浅拷贝之所以称之为浅拷贝,是它仅仅只拷贝了一层,在列表a中有一个嵌套的list,如果我们修改了它,情况就不一样了
比如:a[3].append(‘java’)。查看列表b,会发现列表b也发生了变化,这是因为,我们修改了嵌套的list,修改外层元素,会修改它的引用,让它们指向别的位置,修改嵌套列表中的元素,列表的地址并未发生变化,指向的都是用一个位置。

**三. 深拷贝:(deep copy) **

深拷贝只有一种形式,copy模块中的deepcopy()函数。
深拷贝和浅拷贝对应,深拷贝拷贝了对象的所有元素,包括多层嵌套的元素。因此,它的时间和空间开销要高。
同样的对列表a,如果使用 b = copy.deepcopy(a),再修改列表b将不会影响到列表a,即使嵌套的列表具有更深的层次,也不会产生任何影响,因为深拷贝拷贝出来的对象根本就是一个全新的对象,不再与原来的对象有任何的关联。

四. 拷贝的注意点

对于非容器类型,如数字、字符,以及其他的“原子”类型,没有拷贝一说,产生的都是原对象的引用。
如果元组变量值包含原子类型对象,即使采用了深拷贝,也只能得到浅拷贝。

Q7. __init____new__的区别?
  • __init__在对象创建后,对对象进行初始化。
  • __new__是在对象创建之前创建一个对象,并将该对象返回给__init__
Q8. 说明一下os.pathsys.path分别代表什么?

os.path主要是用于对系统路径文件的操作

os模块的常见方法

os.remove()删除文件
os.rename()重命名文件
os.walk()生成目录树下的所有文件名
os.chdir()改变目录

os.mkdir/makedirs创建目录/多层目录
os.rmdir/removedirs删除目录/多层目录
os.listdir()列出指定目录的文件
os.getcwd()取得当前工作目录
os.chmod()改变目录权限
os.path.basename()去掉目录路径,返回文件名
os.path.dirname()去掉文件名,返回目录路径
os.path.join()将分离的各部分组合成一个路径名
os.path.split()返回(dirname(),basename())元组
os.path.splitext()(返回filename,extension)元组
os.path.getatime\ctime\mtime分别返回最近访问、创建、修改时间
os.path.getsize()返回文件大小

os.path.exists()是否存在

os.path.isabs()是否为绝对路径
os.path.isdir()是否为目录
os.path.isfile()是否为文件

sys.path主要是对Python解释器的系统环境参数的操作(动态的改变Python解释器搜索路径)

sys.argv 命令行参数List,第一个元素是程序本身路径
sys.modules.keys() 返回所有已经导入的模块列表
sys.exc_info() 获取当前正在处理的异常类,exc_type、exc_value、exc_traceback当前处理的异常详细信息

sys.path 返回模块的搜索路径,初始化时使用PYTHONPATH环境变量的值

Q9. 模块和包是什么?

在Python中,模块是搭建程序的一种方式。每一个Python代码文件都是一个模块,并可以引用其他的模块,比如对象和属性。一个包含许多Python代码的文件夹是一个包。一个包可以包含模块和子文件夹。

2. Python的特性
Q1. Python是强语言类型还是弱语言类型?

Python 是强类型的动态脚本语言。
强类型:不允许不同类型相加。
动态:不使用显示数据类型声明,且确定一个变量的类型是在第一次给它赋值的时候。
脚本语言:一般也是解释型语言,运行代码只需要一个解释器,不需要编译。

Q2. 谈一下什么是解释性语言,什么是编译性语言?

计算机不能直接理解高级语言,只能直接理解机器语言,所以必须要把高级语言翻译成机器语言,计算机才能执行高级语言编写的程序。
解释性语言在运行程序的时候才会进行翻译。
编译型语言写的程序在执行之前,需要一个专门的编译过程,把程序编译成机器语言(可执行文件)。

Q3. Python2与Python3的区别有哪些?
  1. Python3对Unicode字符的原生支持。
    Python2中使用 ASCII 码作为默认编码方式导致string有两种类型str和unicode,Python3只支持unicode的string。

  2. Python3采用的是绝对路径的方式进行import。

Python2中相对路径的import会导致标准库导入变得困难(想象一下,同一目录下有file.py,如何同时导入这个文件和标准库file)。Python3中这一点将被修改,如果还需要导入同一目录的文件必须使用绝对路径,否则只能使用相关导入的方式来进行导入。

  1. Python2中存在老式类和新式类的区别,Python3统一采用新式类。新式类声明要求继承object,必须用新式类应用多重继承。

  2. Python3使用更加严格的缩进。Python2的缩进机制中,1个tab和8个space是等价的,所以在缩进中可以同时允许tab和space在代码中共存。这种等价机制会导致部分IDE使用存在问题。Python3中1个tab只能找另外一个tab替代,因此tab和space共存会导致报错:TabError: inconsistent use of tabs and spaces in indentation.

  3. 废弃类差异

    1. print语句被Python3废弃,统一使用print函数
    2. exec语句被python3废弃,统一使用exec函数
    3. execfile语句被Python3废弃,推荐使用exec(open("./filename").read())
    4. 不相等操作符"<>“被Python3废弃,统一使用”!="
    5. long整数类型被Python3废弃,统一使用int
    6. xrange函数被Python3废弃,统一使用range,Python3中range的机制也进行修改并提高了大数据集生成效率
    7. Python3中这些方法再不再返回list对象:dictionary关联的keys()、values()、items(),zip(),map(),filter(),但是可以通过list强行转换:
    8. 迭代器iterator的next()函数被Python3废弃,统一使用next(iterator)
    9. raw_input函数被Python3废弃,统一使用input函数
    10. 字典变量的has_key函数被Python废弃,统一使用in关键词
    11. file函数被Python3废弃,统一使用open来处理文件,可以通过io.IOBase检查文件类型
    12. apply函数被Python3废弃
    13. 异常StandardError 被Python3废弃,统一使用Exception
Q4. 关于Python程序的运行方面,有什么手段能提升性能?

1、使用多进程,充分利用机器的多核性能
2、对于性能影响较大的部分代码,可以使用C或C++编写
3、对于IO阻塞造成的性能影响,可以使用IO多路复用来解决
4、尽量使用Python的内建函数
5、尽量使用局部变量

Q5. PEP8规范
  1. 变量
    常量:大写加下划线 USER_CONSTANT。
    私有变量 : 小写和一个前导下划线 _private_value。
    Python中不存在私有变量一说,若是遇到需要保护的变量,使用小写和一个前导下划线。但这只是程序员之间的一个约定,用于警告说明这是一个私有变量,外部类不要去访问它。但实际上,外部类还是可以访问到这个变量。
    内置变量 : 小写,两个前导下划线和两个后置下划线 __class__

两个前导下划线会导致变量在解释期间被更名。这是为了避免内置变量和其他变量产生冲突。用户定义的变量要严格避免这种风格。以免导致混乱。

  1. 函数和方法
    总体而言应该使用,小写和下划线。但有些比较老的库使用的是混合大小写,即首单词小写,之后每个单词第一个字母大写,其余小写。但现在,小写和下划线已成为规范。
    私有方法 :小写和一个前导下划线
    这里和私有变量一样,并不是真正的私有访问权限。同时也应该注意一般函数不要使用两个前导下划线(当遇到两个前导下划线时,Python 的名称改编特性将发挥作用)。
    特殊方法 :小写和两个前导下划线,两个后置下划线
    这种风格只应用于特殊函数,比如操作符重载等。
    函数参数 : 小写和下划线,缺省值等号两边无空格


  2. 类总是使用驼峰格式命名,即所有单词首字母大写其余字母小写。类名应该简明,精确,并足以从中理解类所完成的工作。常见的一个方法是使用表示其类型或者特性的后缀,例如:
    SQLEngine,MimeTypes对于基类而言,可以使用一个 Base 或者 Abstract 前缀BaseCookie,AbstractGrou

  3. 模块和包
    除特殊模块 init 之外,模块名称都使用不带下划线的小写字母。
    若是它们实现一个协议,那么通常使用lib为后缀,例如:

    import smtplib
    import os
    import sys
    
  4. 关于参数
    5.1 不要用断言来实现静态类型检测。断言可以用于检查参数,但不应仅仅是进行静态类型检测。 Python 是动态类型语言,静态类型检测违背了其设计思想。断言应该用于避免函数不被毫无意义的调用。
    5.2 不要滥用 *args 和 **kwargs。*args 和 **kwargs 参数可能会破坏函数的健壮性。它们使签名变得模糊,而且代码常常开始在不应该的地方构建小的参数解析器。

  5. 其他
    6.1 使用 has 或 is 前缀命名布尔元素
    is_connect = True
    has_member = False
    6.2 用复数形式命名序列
    members = [‘user_1’, ‘user_2’]
    6.3 用显式名称命名字典
    person_address = {‘user_1’:‘10 road WD’, ‘user_2’ : ‘20 street huafu’}

6.4 避免通用名称
诸如 list, dict, sequence 或者 element 这样的名称应该避免。
6.5 避免现有名称
诸如 os, sys 这种系统已经存在的名称应该避免。

  1. 一些数字
    一行列数 : PEP 8 规定为 79 列。根据自己的情况,比如不要超过满屏时编辑器的显示列数。
    一个函数 : 不要超过 30 行代码, 即可显示在一个屏幕类,可以不使用垂直游标即可看到整个函数。
    一个类 : 不要超过 200 行代码,不要有超过 10 个方法。一个模块 不要超过 500 行
3. Python数据类型
Q1.说一下字典和json的区别?

字典是一种数据结构,json是数据的表现形式,字典的key的值只要是能hash就行,json必须是字符串。

Q3. 存入字典的数据没有先后排序?

存入的字典不会自动排序,可以使用sort函数对字典进行排序。如:现有字典 d={‘a’:24,‘g’:52,‘i’:12,‘k’:33}请按字典中的 value值进行排序?

sorted(d.items(),key = lambda x:x[1]) 
Q4. 如何理解Python中字符串中的\字符?

1、转义字符 2、路径名中用来连接路径名 3、编写太长代码手动软换行。

Q5. 列表的增删改查
  1. 增加

    列表名.insert(index, 数据):在指定位置插入数据(位置前有空元素会补位)。

    列表名.append(数据):在列表的末尾追加数据(最常用的方法)。

    列表.extend(Iterable):将可迭代对象中的元素追加到列表。

  2. 取值和修改

    取值:列表名[index] :根据下标来取值。

    修改:列表名[index] = 数据:修改指定索引的数据。

  3. 删除

    del 列表名[index]:删除指定索引的数据。

    列表名.remove(数据):删除第一个出现的指定数据。

    列表名.pop():删除末尾的数据,返回值: 返回被删除的元素。

    列表名.pop(index):删除指定索引的数据,返回被删除的元素。

    列表名.clear():清空整个列表的元素。

  4. 排序

    列表名.sort():升序排序 从小到大。

    列表名.sort(reverse=True):降序排序 从大到小。

    列表名.reverse():列表逆序、反转。

Q6. 给定两个list A ,B,请用找出 A ,B中相同的元素,A ,B中不同的元素

A、B 中相同元素:print(set(A)&set(B))
A、B 中不同元素:print(set(A)^set(B))

Q7. 集合

交集:a&b 并集:a | b 差集:a - b 对称差集:a^b

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值