Python面试指南博客(继续更新ing)

文章目录

第一部分 语言特性

1.1 谈谈对 Python 和其他语言的区别

  • Python属于解释型语言,当程序运行时,是一行一行的解释,并运行,所以调式代码很方便,开发效率高,语法简洁优美,功能强大,标准库与第三方库都非常强大,而且应用领域也非常广 , 但是运行速度慢
  • 与java相比:在很多方面,Python比Java要简单,比如java中所有变量必须声明才能使用,而Python不需要声明,用少量的代码构建出很多功能;(高效的高级数据结构)
  • 与php相比:python标准包直接提供了工具,并且相对于PHP代码更易于维护;
  • 与c相比:Python这门语言是由C开发而来
    对于使用:Python的类库齐全并且使用简洁,如果要实现同样的功能,Python 10行代码可以解决,C可能就需要100行甚至更多.
    对于速度:Python的运行速度相较与C慢些

1.2 简述解释型语言和编译型语言

  • 解释型:就是边解释边执行 , 例如Python,php
  • 编译型:编译后再执行 , 例如c、java、c#

1.3 Python的解释器种类以及相关特点

  • CPython
    是官方版本的解释器 , 是使用C语言开发的,所以叫CPython。在命令行下运行python就是启动CPython解释器。CPython是使用最广的Python解释器。教程的所有代码也都在CPython下执行。
  • IPython
    IPython是基于CPython之上的一个交互式解释器,也就是说,IPython只是在交互方式上有所增强,但是执行Python代码的功能和CPython是完全一样的。CPython用>>>作为提示符,而IPython用In [序号]:作为提示符。
  • PyPy
    由Python写的解释器,它的执行速度是最快。PyPy采用JIT技术,对Python代码进行动态编译(注意不是解释),绝大部分Python代码都可以在PyPy下运行,但是PyPy和CPython有一些是不同的,这就导致相同的Python代码在两种解释器下执行可能会有不同的结果。
  • Jython
    Jython是运行在Java平台上的Python解释器,可以直接把Python代码编译成Java字节码执行。
  • IronPython
    IronPython和Jython类似,只不过IronPython是运行在.Net平台上的Python解释器,可以直接把Python代码编译成.Net的字节码。
  • 小结:
    Python的解释器很多,但使用最广泛的还是CPython。如果要和Java或.Net平台交互,最好的办法不是用Jython或IronPython,而是通过网络调用来交互,确保各程序之间的独立性。

1.4 说说你知道的 Python3 和 Python2 之间的区别

  • 打印时,py2可以不加括号,py3 必须加括号
    python 2 : print (‘lili’) , print ‘lili’
    python 3 : print (‘lili’)
    exec语句被python3废弃,统一使用exec函数
  • 内涵
    Python2:源码的重复量很多。语法不清晰,掺杂着C,php,Java,的一些陋习。
    Python3:几乎是重构后的源码,规范,清晰,优美。
  • 输出中文的区别
    python2:要输出中文 需加 # -- encoding:utf-8 --
    Python3 : 直接输出
  • input不同
    python2 :raw_input
    python3 :input 统一使用input函数
  • 指定字节
    python2在编译安装时,可以通过参数-----enable-unicode=ucs2 或-----enable-unicode=ucs4分别用于指定使用2个字节、4个字节表示一个unicode;
    python3无法进行选择,默认使用 ucs4
    查看当前python中表示unicode字符串时占用的空间:
    impor sys
    print(sys.maxunicode)
    #如果值是65535,则表示使用usc2标准,即:2个字节表示
    #如果值是1114111,则表示使用usc4标准,即:4个字节表示
  • py2:xrange , range
    py3:range 统一使用range,Python3中range的机制也进行修改并提高了大数据集生成效率
  • 在包的知识点里
    包:一群模块文件的集合 + init
    区别:py2 : 必须有__init__
       py3:不是必须的了
  • 不相等操作符"<>“被Python3废弃,统一使用”!="
  • long整数类型被Python3废弃,统一使用int
  • 迭代器iterator的next()函数被Python3废弃,统一使用next(iterator)
  • 异常StandardError 被Python3废弃,统一使用Exception
  • 字典变量的has_key函数被Python废弃,统一使用in关键词
  • file函数被Python3废弃,统一使用open来处理文件,可以通过io.IOBase检查文件类型

1.5 Python3 和 Python2 中 int 和 long 区别

  • 在python3里,只有一种整数类型int,大多数情况下,和python2中的长整型类似。

1.6 xrange 和 range 的区别

  • 都在循环时使用,xrange内存性能更好,xrange用法与range完全相同,range一个生成list对象,xrange是生成器
  • 要生成很大的数字序列的时候,用xrange会比range性能优很多,因为不需要一上来就开辟一块很大的内存空间。
  • 在python2中:
    range([start,] stop[, step]),根据start与stop指定的范围以及step设定的步长,生成一个序列
  • 例子
    xrange用法与range完全相同,所不同的是生成的不是一个数组,而是一个生成器。
  • 例子
    由上面的示例可以知道:要生成很大的数字序列的时候,用xrange会比range性能优很多,因为不需要一上来就开辟一块很大的内存空间,这两个基本上都是在循环的时候用。
  • 在 Python 3 中,range() 是像 xrange() 那样实现,xrange()被抛弃。

第二部分 编码规范

2.1 什么是 PEP8

  • PEP是 Python Enhancement Proposal 的缩写,翻译过来就是 Python增强建议书 , 简单说就是一种编码规范,是为了让代码“更好看”,更容易被阅读。
  • 缩进
    不要使用 tab 缩进
    使用任何编辑器写 Python,请把一个 tab 展开为 4 个空格
    绝对不要混用 tab 和空格,否则容易出现 IndentationError
  • 空格
    在 list, dict, tuple, set, 参数列表的 , 后面加一个空格
    在 dict 的 : 后面加一个空格
    在注释符号 # 后面加一个空格,但是 #!/usr/bin/python 的 # 后不能有空格
    操作符两端加一个空格,如 +, -, *, /, |, &, =
    接上一条,在参数列表里的 = 两端不需要空格
    括号((), {}, [])内的两端不需要空格
  • 空行
    function 和 class 顶上两个空行
    class 的 method 之间一个空行
    函数内逻辑无关的段落之间空一行,不要过度使用空行
    不要把多个语句写在一行,然后用 ; 隔开
    if/for/while 语句中,即使执行语句只有一句,也要另起一行
  • 换行
    每一行代码控制在 80 字符以内
    使用 \ 或 () 控制换行
  • 命名
    使用有意义的,英文单词或词组,绝对不要使用汉语拼音
    package/module 名中不要出现 -
    各种类型的命名规范:
  • import
    • 所有 import 尽量放在文件开头,在 docstring 下面,其他变量定义的上面
    • 不要使用 from foo imort *
    • import 需要分组,每组之间一个空行,每个分组内的顺序尽量采用字典序,分组顺序是:标准库 , 第三方库 , 本项目的 package 和 module
    • 不要使用隐式的相对导入(implicit relative imports),可是使用显示的相对导入(explicit relative imports),如 from …utils import parse,最好使用全路径导入(absolute imports)
    • 对于不同的 package,一个 import 单独一行,同一个 package/module 下的内容可以写一起:
    • 为了避免可能出现的命名冲突,可以使用 as 或导入上一级命名空间
    • 不要出现循环导入(cyclic import)
  • 注释
    • 文档字符串 docstring, 是 package, module, class, method, function 级别的注释,可以通过 doc 成员访问到,注释内容在一对 “”” 符号之间
    • function, method 的文档字符串应当描述其功能、输入参数、返回值,如果有复杂的算法和实现,也需要写清楚
    • 不要写错误的注释,不要无谓的注释
    • 优先使用英文写注释,英文不好全部写中文,否则更加看不懂
  • 异常
    • 不要轻易使用 try/except
    • except 后面需要指定捕捉的异常,裸露的 except 会捕捉所有异常,意味着会隐藏潜在的问题
    • 可以有多个 except 语句,捕捉多种异常,分别做异常处理
    • 使用 finally 子句来处理一些收尾操作
    • try/except 里的内容不要太多,只在可能抛出异常的地方使用
    • 从 Exception 而不是 BaseException 继承自定义的异常类
  • Class(类)
    显示的写明父类,如果不是继承自别的类,就继承自 object 类
    使用 super 调用父类的方法
    支持多继承,即同时有多个父类,建议使用 Mixin

2.2 了解 Python 之禅吗

  • Beautiful is better than ugly.
    优美胜于丑陋(Python以编写优美的代码为目标)
  • Explicit is better than implicit.
    明了胜于晦涩(优美的代码应当是明了的,命名规范,风格相似)
  • Simple is better than complex.
    简洁胜于复杂(优美的代码应当是简洁的,不要有复杂的内部实现)
  • Complex is better than complicated.
    复杂胜于凌乱(如果复杂不可避免,那代码间也不能有难懂的关系,要保持接口简洁)
  • Flat is better than nested.
    扁平胜于嵌套(优美的代码应当是扁平的,不能有太多的嵌套)
  • Sparse is better than dense.
    间隔胜于紧凑(优美的代码有适当的间隔,不要奢望一行代码解决问题)
  • Readability counts.
    可读性很重要(优美的代码是可读的)
  • Special cases aren’t special enough to break the rules.Although practicality beats purity.
    即便假借特例的实用性之名,也不可违背这些规则(这些规则至高无上)
  • Errors should never pass silently. Unless explicitly silenced.
    不要包容所有错误,除非你确定需要这样做(精准地捕获异常,不写except:pass风格的代码)
  • In the face of ambiguity, refuse the temptation to guess.
    当存在多种可能,不要尝试去猜测
  • There should be one-- and preferably only one --obvious way to do it.
    而是尽量找一种,最好是唯一一种明显的解决方案(如果不确定,就用穷举法)
  • Although that way may not be obvious at first unless you’re Dutch.
    虽然这并不容易,因为你不是 Python 之父(这里的Dutch是指Guido)
  • Now is better than never. Although never is often better than right now.
    做也许好过不做,但不假思索就动手还不如不做(动手之前要细思量)
  • If the implementation is hard to explain, it’s a bad idea.
    If the implementation is easy to explain, it may be a good idea.
    如果你无法向人描述你的方案,那肯定不是一个好方案;反之亦然(方案测评标准)
  • Namespaces are one honking great idea – let’s do more of those!
    命名空间是一种绝妙的理念,我们应当多加利用(倡导与号召)

2.3 了解 docstring 吗

  • docstrings : 文档字符串 。DocStrings是一个重要的工具,由于它帮助你的程序文档更加简单易懂,你应该尽量使用它。你甚至可以在程序运行的时候,从函数恢复文档字符串
  • 短字符串
    单引号:’’
    双引号:" "
  • 跨行字符串
    三单引号:’’’ ‘’’
    三双引号:""" “”"

2.4 了解类型注解吗

  • 用 : 类型 的形式指定函数的参数类型,用 -> 类型 的形式指定函数的返回值类型。
    要强调的是,Python 解释器并不会因为这些注解而提供额外的校验,没有任何的类型检查工作。也就是说,这些类型注解加不加,对你的代码来说没有任何影响
  • 这么做的好处是:
    让别的程序员看得更明白
    让 IDE 了解类型,从而提供更准确的代码提示、补全和语法检查(包括类型检查,可以看到类型注解的参数被高亮提示)
  • 在 Python 3.6 中,又引入了对变量类型进行注解的方法:
    a: int = 123
    b: str = ‘hello’
    更进一步,如果你需要指明一个全部由整数组成的列表:
    from typing import List
    l: List[int] = [1, 2, 3]
    这些仅仅是“注解”,不会对代码产生任何影响。

2.5 例举你知道 Python 对象的命名规范 , 例如方法或类等

  • 文件名
    全小写,可使用下划线

  • 应该是简短的、小写的名字。如果下划线可以改善可读性可以加入。如mypackage。
  • 模块
    与包的规范同。如mymodule。

  • 总是使用首字母大写单词串。如MyClass。内部类可以使用额外的前导下划线。
  • 函数&方法
    函数名应该为小写,可以用下划线风格单词以增加可读性。如:myfunction,my_example_function。
    注意:混合大小写仅被允许用于这种风格已经占据优势的时候,以便保持向后兼容。
  • 函数和方法的参数
    总使用“self”作为实例方法的第一个参数。总使用“cls”作为类方法的第一个参数。
    如果一个函数的参数名称和保留的关键字冲突,通常使用一个后缀下划线好于使用缩写或奇怪的拼写。
  • 全局变量
    对于from M import *导入语句,如果想阻止导入模块内的全局变量可以使用旧有的规范,在全局变量上加一个前导的下划线。
    注意:应避免使用全局变量
  • 变量
    变量名全部小写,由下划线连接各个单词。如color = WHITE,this_is_a_variable = 1
    注意
    不论是类成员变量还是全局变量,均不使用 m 或 g 前缀。
    私有类成员使用单一下划线前缀标识,多定义公开成员,少定义私有成员。
    变量名不应带有类型信息,因为Python是动态类型语言。如 iValue、names_list、dict_obj 等都是不好的命名。
  • 常量
    常量名所有字母大写,由下划线连接各个单词如MAX_OVERFLOW,TOTAL。
  • 异常
    以“Error”作为后缀。
  • 缩写
    命名应当尽量使用全拼写的单词,缩写的情况有如下两种:
    常用的缩写,如XML、ID等,在命名时也应只大写首字母,如XmlParser。
    命名中含有长单词,对某个单词进行缩写。这时应使用约定成俗的缩写方式。
    例如:
    function 缩写为 fn
    text 缩写为 txt
    object 缩写为 obj
    count 缩写为 cnt
    number 缩写为 num,等。
  • 前导后缀下划线
    一个前导下划线:表示非公有。
    一个后缀下划线:避免关键字冲突。
    两个前导下划线:当命名一个类属性引起名称冲突时使用。
    两个前导和后缀下划线:“魔”(有特殊用图)对象或者属性,例如__init__或者__file__。绝对不要创造这样的名字,而只是使用它们。

2.6 Python 中的注释有几种

  • 用#号作为注释一行
    #此处为注释
  • 一般用"""(三个英文引号)也可以注释多行,不过一般用来表示函数文档
    “”"
    此处是注释
    此函数功能为。。。。
    “”"

2.7 如何优雅的给一个函数加注释

  • 为自己编写代码时:
    将注释作为代码的大纲
    删除任何已经变得多余的注释
    使用注释来定义自己代码的棘手部分
  • 为他人编写代码时:
    如果有一个名称不易理解的复杂方法或函数,需要在def行后面添加一个简短的注释,以说明问题
    对于任何公共函数,都尽量包含一个关联的docstring
    避免:W.E.T.注释
    避免:利用注释来弥补代码
    避免:粗鲁的注释

2.8 如何给变量加注释

  • docstring

2.9 Python 代码锁紧中是否支持 Tab 键和空格混用

  • python语法中是不支持代码缩进以TAB和空格混用

2.10 是否可以在一句 import 中导入多个库

  • 尽管可以使用import语句一次导入任意多个标准库或扩展库,但是仍建议每次只导入一个标准库或扩展

2.11 在给 py 文件命名的时候需要注意什么

  • 注意重名,
  • 全小写,可使用下划线

2.12 例举几个规范 Python 代码风格的工具

  • Pylint , black

第三部分 数据类型

3.1 字符串

3.1.1 列举 Python 中的基本数据类型

int 整型 , float 浮点型 , str 字符串 , list 列表 , tuple 元组 , dict 字典

3.1.2 如何区别可变数据类型与不可变数据类型
  • 可变数据类型,变量名存储的是一个地址,该地址指向一个具体的对象,并且不管对变量的值即对象做怎么样的操作,都不会改变变量名存储的地址。在id不变的情况下,value可改变(列表和字典是可变类型,但是字典中的key值必须是不可变类型)
  • 不变数据类型的对象一旦发生改变,就会在内存中开辟一个新的空间用于存储新的对象,原来的变量名就会指向一个新的地址。value改变,id也跟着改变。(数字,字符串,布尔类型,都是不可变类型)
3.1.3 将 “hello world"转换成首字母大写"Hello World”
arr = "hello world".split(" ")
new_str = f"{arr[0].capitalize()} {arr[1].capitalize()}"
print(new_str)
3.1.4 如何检测字符串中只含数字
print(str.isdigit())
3.1.5 将字符串"ilovechina"进行反转
s1 = "ilovechina"[::-1]
print(s1)
3.1.6 Python 中的字符串格式化方式你知道哪些
# 第一种
print 'hello %s and %s' % ('df', 'another df')
# 第二种
print 'hello %(first)s and %(second)s' % {'first': 'df', 'second': 'another df'}
# 第三种
print 'hello {first} and {second}'.format(first='df', second='another df')
3.1.7 有一个字符串开头和末尾都有空格 , 比如 " adabdw " , 要求写一个函数把这个字符串的前后空格去掉
str = ' adabdw '
newstr = str.split(' ')
print(newstr[1])
3.1.8 获取字符串" 123456 "最后两个字符
str = '123456'
ns = str.split('4')
print(ns[1])
3.1.9 一个编码为 GBK 的字符串 S , 要将其转成 UTF-8 编码的字符串 , 应如何操作
import sys
print(sys.getdefaultencoding())
str = "s"                   #默认是utf-8
str_gbk = str.encode("gbk")     #utf-8转成gbk
print(str_gbk)
print(str.encode())
3.1.10 正则切分字符串,去除多余空格只留一个空格

(1) s = "info: xiaoZhang 33 shandong " , 用正则切分字符串输出[‘info’, ‘xiaoZhang’, ‘33’, ‘shandong’]

import re
list = []
s = "info:xiaoZhang 33 shandong"
for i in range(1,5):
    res = re.match('(\w+):(\w+)\s(\d+)\s(\w+)', s)
    ress = res.group(i)
    list.append(ress)
print(list)

(2) a = "你好 中国 " , 去除多余空格只留一个空格

re.sub(+,’ ', a)
3.1.11 字符串转换为小写,单引号 , 双引号 , 三引号的区别

(1) 怎样将字符串转换为小写

str.lower()

(2) 单引号 , 双引号 , 三引号的区别

  • 单引号表示的字符串中不能带有双引号
  • 双引号表示的字符串中可以存在单引号
  • 三引号中可以存在单引号和双引号,并且可以跨行表示字符串,而单双引号皆不能跨行

3.2 列表

3.2.1 已知 AList = [1,2,3,1,2] , 对 AList列表元素去重 , 写出具体过程
AList = [1,2,3,1,2]
BList = []
for i in AList:
    a1 = i
    if a1 not in BList:
        BList.append(a1)
print(BList)
3.2.2 如何实现 “1, 2, 3” 变成 [“1”, “2”, “3”]
a = list("1,2,3")
b = []
for i in range(3):
    b.append(a[i * 2])
print(b)
3.2.3 给定两个 list , A 和 B , 找出相同元素与不同元素
A = [1, 6, 8, 9, "iii", 95]
B = [6, 85, 64]
C = []  不同值
D = []  相同值
for i in A:
    for m in B:
        if i == m:
            D.append(i)
print(D)

new_c = A+B
a = list(set(new_c))
for i in a:
    if i not in D:
        C.append(i)
print(C)
3.2.4 [[1,2],[3,4],[5,6]] 一行代码展开该列表 , 得出[1,2,3,4,5,6]
print(sum([[1, 2], [3, 4], [5, 6]], []))
3.2.5 合并列表 [1,5,7,9] 和 [2,2,6,8]
a = [1,5,7,9]
b = [2,2,6,8]
c = a+b
print(c)
3.2.6 如何打乱一个列表的元素
import random
x = [i for i in range(10)]
print(x)
random.shuffle(x)
print(x)

3.3 字典

3.3.1 字典操作中 del 和 pop 有什么区别
  • 对于 del 来说,它是根据索引(元素所在位置)来删除的
    a = [3, 2, 2, 1]
    del a[1]
  • del还可以删除指定范围内的值
    a = [3,2,2,1]
    del a[1,3]
    print a
    结果是[3]
  • del还可以删除整个列表
    del a
  • pop返回的是你弹出的那个数值
    a = [4, 3, 5]
    a.pop(1)
    3
    print a
    [4, 5]
3.3.2 按照字典内的年龄排序
d1 = [
	{'name':'alice', 'age':38},
	{'name':'bob', 'age':18},
	{'name':'carl', 'age':28}
]
sorted(d1, key=lambda x:x["age"])
3.3.3 请合并下面两个字典 a = {“A”:1, “B”:2},b = {“C”:3,“D”:4}
  • dict(d1.items() + d2.items())
    d1.items()获取字典的键值对的列表
    d1.items() + d2.items()拼成一个新的列表
    dict(d1.items()+d2.items())将合并成的列表转变成新的字典
  • 字典的update()
    d3 = {}
    d3.update(d1)
    d3.update(d2)
  • 字典的dict(d1, **d2)方法
    dict(d1, **d2)
  • 字典的常规处理方法
    d3 = {}
    for k,v in d1.items():
    d3[k] = v
    for k,v in d2.items():
    d3[k] = v
3.3.4 如何使用生成式的方式生成一个字典,写一段功能代码
#需求 : 把字典的 key 和 value 值调换;
d = {'a''1', 'b''2'}
print({v:k for k,v in d.items()})
3.3.5 如何把元组 (“a”,“b”) 和元组 (1,2),变为{“a”:1,“b”:2}
print(dict(zip(("a","b"), (1,2))))

3.4 综合

3.4.1 Python 常用的数据结构的类型及其特性
A: {1:0,2:0,3:0}
B: {"a":0, "b":0, "c":0}
C: {(1,2):0, (2,3):0}
D: {[1,2]:0, [2,3]:0}
  • 列表list
    列表用 [ ] 括住数据
    列表内的数据允许重复
    列表内的数据可以修改
    列表允许用下标访问,例如 l = list[1,2,3],l[ 0 ] = 1;
    列表支持加法和乘法运算
    列表中可以有不同类型的成员
    列表中的成员也可以是列表
  • 元组tuple
    元组内的成员用( )括起来
    元组跟列表不同的地方就是元组中的成员是不允许修改的,包括修改成员位置也不可以,所以排序是不行的
    元组中也可以包含不同类型的成员。
    元组也可以有相同的成员
    元组也支持加法,乘法
    列表中的方法只要不是修改元组中的成员的,都可以用
    元组支持下标访问
    元组中的成员也可以是元组
  • 字典dict
    字典的数据用{ }括起来
    字典中没位置可言,不能用下标访问
    字典的成员都是以 key:value 键值对的形式存在的
    字典的成员可以重复,但没有意义,key:value 中的key也可以重复,但是迭代字典时,只会显示一个key:value
    key最好不要重复
    字典不支持加法乘法
  • 集合set
    集合支持并集,交集,差集运算
    由于集合是无序的,所以不能用下标访问
    集合可以有重复的成员,但迭代打印时,只会打印一个,所以最好不要有重复的成员
3.4.2 如何交换字典 {“A”: 1,“B”: 2} 的键和值
d = {"A": 1,"B": 2}
print({value:key for key, value in d.items()})
3.4.3 Python 里面如何实现 tuple 和 list 的转换
l = list(t)
t = tuple(l)
3.4.4 我们知道对于列表可以使用切片操作进行部分元素的选择,那么如何对生成器类型的对象实现相同功能
  • 使用自带的itertools库进行实现
    具体实现方式 itertools.islice(生成器对象,起始位置,结束位置),即可实现切片功能
for i in itertools.islice(c, 10, 15):
    print(i)
3.4.5 请将 [i for i in range(3)]改成生成器
a = (i for i in range(3))
print(type(a)
3.4.6 a = “hello” 和 b = “你好” 编码成 bytes 类型
a = b"hello"
b = "你好".encode()
3.4.7 下面的代码输出结果是什么
a = (1, 2, 3, [4, 5, 6, 7], 8)
a[2] = 2
  • 输出结果:
    会报错,因为是 tuple 元组类型,不支持修改操作
3.4.8 下面的代码输出结果是什么
a = (1, 2, 3, [4, 5, 6, 7], 8)
a[3][0] = 2
  • 输出结果 :2

第四部分 操作类

4.1 Python 交换两个变量的值

x = input('input num1: ')
y = input('input num2: ')
x, y = y, x
print(x, y)

4.2 在读文件操作时会使用 read、readline或者 readlines,简述他们各自的作用

  • file.read([size])
    从文件读取指定的字节数,size如果未给定或为负则读取所有
    read([size])从文件当前位置起读取size个字节,若无参数size,则表示读取至文件结束为止。它的返回是字符串对象,原样返回文件行内容
  • file.readline([size])
    读取整行,包括”\n”字符
    readline每次读取一行内容,所以读取时占用内存小,比较适合大文件。readline返回一个字符串对象,原样返回一行内容
  • file.readlines([sizeint])
    读取所有行并返回列表,若给定sizeint>0,返回总和大约为sizeint字节的行。 实际读取值可能比sizeint大,因为需要填充缓冲区
    readlines读取文件的所有行,保存在一个列表(list)变量中。每1个文件行作为一个list元素,但读取大文件会比较占内存,readlines返回一个list,其中每一个文件行是一个字符串元素
  • 参考链接
    https://blog.csdn.net/yjk13703623757/article/details/79502998

4.3 json 序列化时,可以处理的数据类型有哪些?如何定制支持 datetime 类型?

4.4 json 序列化时,默认遇到中文会转成 unicode,如果想要保留中文怎么办?

import json
a=json.dumps({"ddf":"你好"},ensure_ascii=False)
print(a) #{"ddf": "你好"}

参考链接
https://www.cnblogs.com/wangkun122/p/9084825.html

4.5 有两个磁盘文件 A 和 B,各存放一行字母,要求把这两个文件中的信息合并(按字母顺序排列),输出到一个新文件中

lis_A = open('a.txt').readlines()
lis_B = open('b.txt').readlines()

lis_C = zip(lis_A,lis_B)

file_C = open('c.txt', 'w')
for txt in lis_C:
    s = ''.join(txt).replace('\n', '')
    file_C.write(''.join(sorted(s)) + '\n')
file_C.close()

参考链接
https://testerhome.com/topics/12900?locale=zh-TW

4.6 如果当前日期为 20190530,要求写一个函数输出N天后的日期,(比如 N 为 2,则输出 20190601)

import datetime


def get_day(n):
    y = 2019
    m = 6
    d = 30

    # datetime.datetime指定日期
    the_date = datetime.datetime(y, m, d)

    # datetime.timedelta,时间差
    result_date = the_date + datetime.timedelta(days=n)
    target_date = result_date.strftime('%Y%m%d')
    return target_date


print(get_day(2))

参考链接
https://blog.csdn.net/ost_csdn/article/details/93642395

4.7 写一个函数,接收整数参数 n,返回一个函数,函数的功能是把函数的参数和 n 相乘并把结果返回

def fuc_1(n):
    def fuc_2(m):
        return n * m
    return fuc_2


zw = fuc_1(7)
print(zw(9))

参考链接
https://blog.csdn.net/ost_csdn/article/details/93642395

4.8 下面代码会存在什么问题,如何改进?

def strappend(num):
	str='first'
	for i in range(num)"
		str+=(i)
	return str

TypeError: ‘str’ object is not callable
str 不可以被系统调用,原因是:你正在调用一个不能被调用的变量或对象,具体表现就是你调用函数、变量的方式错误

def strappend(num):
    str='first'
    for i in range(num):
        str+=str[i]
    return str

参考链接
https://blog.csdn.net/ost_csdn/article/details/93642395

4.9 一行代码输出 1-100 之间的所有偶数

# 第一种方法
print([i*2 for i in range(1, 51)])
# 第二种方法
print(list(x for x in range(1, 101) if x % 2 == 0))
或者
print([x for x in range(1, 101) if x % 2 == 0])

参考链接
https://blog.csdn.net/ost_csdn/article/details/93642395

4.10 with 语句的作用,写一段代码

4.11 python 字典和 json 字符串相互转化的方法

  • json.dumps() 将Python中的对象转换为JSON中的字符串对象
  • json.loads() 将JSON中的字符串对象转换为Python中的对象

4.12 请写一个 Python 逻辑,计算一个文件中的大写字母数量

# 第一种方法
list = open('test1.txt')
count = 0
file_o = list.read()
for i in file_o:
    if i.isupper():
        count += 1
print(count)

# 第二种方法
import re
file = open('test1.txt')
file_o = file.read()
len_capital = len(re.compile(r'[A-Z]').findall(file_o))
print(len_capital)

4.13 请写一段 Python 连接 Mongo 数据库的代码

4.14 说一说 Redis 的基本类型

4.15 请写一段 Python 连接 Redis 数据库的代码

4.16 请写一段 Python 连接 MySQL 数据库的代码

# 导入MySQL驱动:
import mysql.connector
# 注意把password设为你的root口令:
conn = mysql.connector.connect(user='root', password='password', database='test')
cursor = conn.cursor()
# 创建user表:
cursor.execute('create table user (id varchar(20) primary key, name varchar(20))')
# 插入一行记录,注意MySQL的占位符是%s:
cursor.execute('insert into user (id, name) values (%s, %s)', ['1', 'Michael'])
cursor.rowcount
# 提交事务:
conn.commit()
cursor.close()
# 运行查询:
cursor = conn.cursor()
cursor.execute('select * from user where id = %s', ('1',))
values = cursor.fetchall()
# 关闭Cursor和Connection:
cursor.close()
conn.close()

参考链接
https://www.liaoxuefeng.com/wiki/1016959663602400/1017802264972000

4.17 了解 Redis 的事务吗

  • Redis 事务可以一次执行多个命令, 并且带有以下三个重要的保证:
    批量操作在发送 EXEC 命令前被放入队列缓存
    收到 EXEC 命令后进入事务执行,事务中任意命令执行失败,其余的命令依然被执行
    在事务执行过程,其他客户端提交的命令请求不会插入到事务执行命令序列中
  • 一个事务从开始到执行会经历以下三个阶段:
    开始事务
    命令入队
    执行事务
  • 参考链接
    https://www.runoob.com/redis/redis-transactions.html

4.18 了解数据库的三范式吗

  • 设计关系数据库时,遵从不同的规范要求,设计出合理的关系型数据库,这些不同的规范要求被称为不同的范式,各种范式呈递次规范,越高的范式数据库冗余越小。
    目前关系数据库有六种范式:第一范式(1NF)、第二范式(2NF)、第三范式(3NF)、巴斯-科德范式(BCNF)、第四范式(4NF)和第五范式(5NF,又称完美范式)
  • 第一范式(1NF)
    强调的是列的原子性,即列不能够再分成其他几列。
    • 例如:【联系人】(姓名,性别,电话)
    • 如果在实际场景中,一个联系人有家庭电话和公司电话,那么这种表结构设计就没有达到 1NF。要符合 1NF 我们只需把列(电话)拆分
      即:【联系人】(姓名,性别,家庭电话,公司电话)
  • 第二范式(2NF)
    首先满足 1NF,另外包含两部分内容,一是表必须有一个主键;二是没有包含在主键中的列必须完全依赖于主键,而不能只依赖于主键的一部分
    • 例如:【OrderDetail】(OrderID,ProductID,UnitPrice,Discount,Quantity,ProductName)
    • 在一个订单中可以订购多种产品,所以单单一个 OrderID 是不足以成为主键的,主键应该是(OrderID,ProductID)。显而易见 Discount(折扣),Quantity(数量)完全依赖(取决)于主键(OderID,ProductID),而 UnitPrice,ProductName 只依赖于 ProductID。所以 OrderDetail 表不符合 2NF。不符合 2NF 的设计容易产生冗余数据。
    • 可以把【OrderDetail】表拆分为【OrderDetail】(OrderID,ProductID,Discount,Quantity)和【Product】(ProductID,UnitPrice,ProductName)来消除原订单表中UnitPrice,ProductName多次重复的情况。
  • 第三范式(3NF)
    在1NF基础上,任何非主属性不依赖于其它非主属性(在2NF基础上消除传递依赖),第三范式(3NF)是第二范式(2NF)的一个子集,即满足第三范式(3NF)必须满足第二范式(2NF),首先满足 2NF,另外非主键列必须直接依赖于主键,不能存在传递依赖。即不能存在:非主键列 A 依赖于非主键列 B,非主键列 B 依赖于主键的情况
    • 【Order】(OrderID,OrderDate,CustomerID,CustomerName,CustomerAddr,CustomerCity)主键是(OrderID)
    • 其中 OrderDate,CustomerID,CustomerName,CustomerAddr,CustomerCity 等非主键列都完全依赖于主键(OrderID),所以符合 2NF。不过问题是 CustomerName,CustomerAddr,CustomerCity 直接依赖的是 CustomerID(非主键列),而不是直接依赖于主键,它是通过传递才依赖于主键,所以不符合 3NF
    • 通过拆分【Order】为【Order】(OrderID,OrderDate,CustomerID)和【Customer】(CustomerID,CustomerName,CustomerAddr,CustomerCity)从而达到 3NF
  • 参考链接
    https://blog.csdn.net/Dream_angel_Z/article/details/45175621

4.19 了解分布式锁吗

  • 分布式锁
    是控制分布式系统之间同步访问共享资源的一种方式。在分布式系统中,常常需要协调他们的动作。如果不同的系统或是同一个系统的不同主机之间共享了一个或一组资源,那么访问这些资源的时候,往往需要互斥来防止彼此干扰来保证一致性,在这种情况下,便需要使用到分布式锁。
  • 参考链接
    https://baike.baidu.com/item/%E5%88%86%E5%B8%83%E5%BC%8F%E9%94%81/10459578

4.20 用 Python 实现一个 Redis 的分布式锁功能

4.21 写一段 Python 使用 Mongo数据库创建索引的代码

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值