Python基础及面试题

一、概述

1、含义

        Python是一个面向对象的解释型的交互式高级脚本语言。Python被设计成一种高可读性的语言,因为它大量地使用了英语中的单词作为关键字,而且不像其他语言使用标点符号构成复杂的语法结构,Python的语法结构非常少。

        Python是一种带有对象、模块、线程、异常和内存自动管理的编程语言。

2、优缺点

(1)优点

        在于它简单易用,可移植,可扩展,内置数据结构,并且它是一个开源的

  •  解释性
  • 动态特性
  • 面向对象
  • 语法简洁
  • 可移植性好
  • 开源
  • 丰富的社区资源

(2)缺点

  • 执行速度不够快,代码效率低
  • GIL锁限制并发
  • Python2与Python3不兼容

3、Django和flask的区别

(1)Django

  1. 大而全,功能极其强大,是Python web框架的先驱,用户多,第三方库极其丰富。
  2. 非常适合企业级网站的开发,但是对于小型的微服务来说,总有“杀鸡焉有宰牛刀”的感觉,体量较大,非常臃肿,定制化程度没有Flask高,也没有Flask那么灵活

(2)flask

  1. 小巧、灵活,让程序员自己决定定制哪些功能,非常适用于小型网站。
  2. 对于普通的工人来说将毛坯房装修为城市综合体还是很麻烦的,使用Flask来开发大型网站也一样,开发的难度较大,代码架构需要自己设计,开发成本取决于开发者的能力和经验

4、PEP 8

        PEP 8是一个编码约定,一组推荐,关于如何编写Python代码更具可读性

5、标识符

        标识符不建议使用下划线开头:因为在 Python 中以下划线开头的变量为私有变量

        标识符就是一个名字,它的主要作用就是作为变量、函数、类、模块以及其他对象的名称。Python 标识符的命名不是乱来的,而是要遵守一定的命令规则:

  • 标识符是由字母(A--Z 和 a--z)、下划线和数字组成。如果标识符中出现除了这 3 类字符之外的其他字符,就肯定是不合法标识符。

  • 标识符的第一个字符不能是数字。

  • 标识符不能和 Python 关键字相同。

  • 标识符中的字母是严格区分大小写的。

  • 以下划线开头的标识符有特殊含义,除非特定场景需要,应避免使用以下划线开头的标识符。

  • 标识符可以是汉字。但我们应尽量避免使用汉字作为标识符,这会避免遇到很多没必要的错误。

二、关键字和函数

1、深拷贝和浅拷贝的区别

  • 浅拷贝:copy模块里面的copy方法实现。浅拷贝后,改变原始对象中为可变类型的元素的值,会同时影响拷贝对象;改变原始对象中为不可变类型的元素的值,不会响拷贝对象。浅拷贝是将对象的引用复制给另一个对象。因此,如果我们在副本中进行更改,则会影响原对象
  • 深拷贝:copy模块里面的deepcopy方法实现。深拷贝,除了顶层拷贝,还对子元素也进行了拷贝。经过深拷贝后,原始对象和拷贝对象所有的可变元素地址都没有相同的了。深拷贝是将对象本身复制给另一个对象。这意味着如果对对象的副本进行更改时不会影响原对象。

2、迭代器和生成器的区别

  1. 迭代器:是一个可以记住遍历的位置的对象,包含iter()和 next(),
>>> list=[1,2,3,4]
>>> it = iter(list)    # 创建迭代器对象
>>> print (next(it))   # 输出迭代器的下一个元素
1
>>> print (next(it))
2

  2. 生成器:使用了 yield 的函数被称为生成器,在调用生成器运行的过程中,每次遇到 yield 时函数会暂停并保存当前所有的运行信息,返回 yield 的值, 并在下一次执行 next() 方法时从当前位置继续运行。

import sys
 
def fibonacci(n): # 生成器函数 - 斐波那契
    a, b, counter = 0, 1, 0
    while True:
        if (counter > n): 
            return
        yield a
        a, b = b, a + b
        counter += 1
f = fibonacci(10) # f 是一个迭代器,由生成器返回生成
 
while True:
    try:
        print (next(f), end=" ")
    except StopIteration:
        sys.exit()

输出:0 1 1 2 3 5 8 13 21 34 55

3、字典、列表、元组、集合的区别

(1)字典

        字典存储键值对数据

lists = {1:'a',2:'b',3:'c'}

#字典最外面用大括号,每一组用冒号连起来,然后各组用逗号隔开。
#字典最大的价值是查询,通过键,查找值。

(2)列表

        特点就是:可重复,类型可不同。python里的列表用“[]”表示

lst = ['arwen',123]
print(lst[0])
print(st[1])

lst[0] = 'weiwen'

(3)元组

        元组和列表在结构上没有什么区别,唯一的差异在于元组是只读的,不能修改。元组用“()”表示

tup = ('arwen',123)
print(tup[0])
print(tup[1])

(4)集合

        集合最好的应用是去重。集合没有特殊的表示方法,而是通过一个set函数转换成集合

lst = [ 1, 1, 0]
lst_set = set( lst )  #lst_set 为1 , 0
tup = (2, 2, 1)
tup_set = set( tup) # tup_set为2 , 1
for item in lst_set:
    print(item)

4、列表和数组的区别

        列表中元素是可以不同类型的,数组中为同一类型

5、lambda和filter

(1)lambda

        Python使用lambda来创建匿名函数。

  • lambda只是一个表达式,函数体比def简单很多。
  • lambda的主体是一个表达式,而不是一个代码块。仅仅能在lambda表达式中封装有限的逻辑进去。
  • lambda函数拥有自己的命名空间,且不能访问自有参数列表之外或全局命名空间里的参数。
func=lambda x:x+2
print(func(1))
print(func(2))

#以上lambda等同于以下函数
def func(x):
    return(x+2)

(2)filter

        filter(函数,序列)函数用于过滤序列,过滤掉不符合条件的元素,返回由符合条件元素组成的新列表。

        该函数接收两个参数,第一个为函数,第二个为序列,序列的每个元素作为参数传递给函数进行判断,然后返回 True 或 False,最后将返回 True 的元素放到新列表中。

def is_odd(n):
    return n%2==1
 
newlist = filter(is_odd,[1,2,3,4,5,6,7,8,9,10])
print(newlist)

Python3.6结果:<filter object at 0x00000184ED881358>

        上面lambda和filter合在一起:

newlist = list(filter(lambda n:n%2==1,[1,2,3,4,5,6,7,8,9,10]))
print(newlist)
结果:[1, 3, 5, 7, 9]

6、装饰器

        装饰器是修改其他函数的功能的函数,有助于使得代码更简短。 

        Python 内置的 3 种函数装饰器,分别是 @staticmethod、@classmethod 和 @property,其中 staticmethod()、classmethod() 和 property() 都是 Python 的内置函数。

#funA 作为装饰器函数
def funA(fn):
    print("C语言中文网")
    fn() # 执行传入的fn参数
    print("http://c.biancheng.net")
    return "装饰器函数的返回值"
@funA
def funB():
    print("学习 Python")


等价于:
def funA(fn):
    #...
    fn() # 执行传入的fn参数
    #...
    return '...'
def funB():
    #...
funB = funA(funB)


#输出结果:
    C语言中文网
    学习 Python
    http://c.biancheng.net

通过比对以上 2 段程序不难发现,使用函数装饰器 A() 去装饰另一个函数 B(),其底层执行了如下 2 步操作:

  1. 将 B 作为参数传给 A() 函数;
  2. 将 A() 函数执行完成的返回值反馈回  B

7、局部变量和全局变量

局部变量:如果在函数体内的任何位置为变量分配了一个新值,则假定它是本地的
全局变量:仅在函数内引用的那些变量是隐式全局变量
变量调用的顺序是先找局部作用域,如果找不到,再往外层找,然后在找全局作用域

name="gouguoqi"
def change_name():
    global name
    name="miaoye"
    print ("111",(name))
change_name()
print(name)


结果:
    111 miaoye
    miaoye

        global name,就代表调用全局的变量name。专业的说法是global 后面的name是一个指针,一个内存地址,直接调用的那个内存地址,调用之后在子程序(局部程序)里面再次给name赋值的话就修改了全局变量name了

8、pass

        pass是Python中的空操作语句,或者说,它是一个复杂语句中的一个空间占位符,只是用来表示空白,什么都不用写

9、*args和**kwargs

        如果我们不知道将多少个参数传递给函数,比如当我们想传递一个列表或一个元组值时,就可以使用*args。

        当我们不知道将会传入多少关键字参数时,使用**kwargs 会收集关键字参数。

        使用 args 和 kwargs 作为参数名只是举例,可以任意替换

        类似的 break 语句可以跳出循环,continue 语句可以跳到下一轮循环

三、内存管理

1、管理方式

       Python内存由Python私有堆空间管理。所有Python对象和数据结构都位于私有堆中。程序员无权访问此私有堆,解释器负责处理此私有堆。

        Python对象的Python堆空间分配由Python内存管理器完成。核心API提供了一些程序员编写代码的工具。

        Python还有一个内置的垃圾收集器,它可以回收所有未使用的内存并释放内存并使其可用于堆空间。

        Python不需要显式内存管理,因为解释器本身会将内存分配给新变量并自动释放它们

2、释放

        当退出 Python 时是否释放所有内存分配,答案是否定的。那些具有对象循环引用或者全局命名空间引用的变量,在 Python 退出是往往不会被释放,另外不会释放 C 库保留的部分内容

四、多线程

1、如何实现

        线程是轻量级的进程,多线程允许一次执行多个线程。众所周知,Python 是一种多线程语言,它有一个多线程包。

        GIL(全局解释器锁)确保一次执行单个线程。一个线程保存 GIL 并在将其传递给下一个线程之前执行一些操作,这就产生了并行执行的错觉。但实际上,只是线程轮流在 CPU 上。当然,所有传递都会增加执行的开销。

2、多线程优点

多线程类似于同时执行多个不同程序,其优点:

  • 使用线程可以把占据长时间的程序中的任务放到后台去处理。
  • 用户界面可以更加吸引人,比如用户点击了一个按钮去触发某些事件的处理,可以弹出一个进度条来显示处理的进度。
  • 程序的运行速度可能加快。
  • 在一些等待的任务实现上如用户输入、文件读写和网络收发数据等,线程就比较有用了。在这种情况下我们可以释放一些珍贵的资源如内存占用等等

五、运算

1、解释 Python 中的//,/,%和**运算符

  • //运算符执行地板除法,7//2返回结果的整数部分 (向下取整),为3
  • 用/符号除法结果为 3.5
  • **符号表示取幂. a**b 返回 a 的 b 次方
  • % 是取模符号。返回除法后的余数

2、Python有几种运算符

        在 Python 中有7中运算符:算术运算符、关系 (比较) 运算符、赋值运算符、逻辑运算符、位运算符、成员运算符、身份运算符。

(1)算术运算符

        算术运算符包括+、-、*、/、//(地板除法)、%(取模)、**(取幂)

(2)关系运算符

        关系运算符用来比较两个对象,包括<、>、<=、>=、==、!=

(3)赋值运算符

        一般将算数运算符和赋值符号用在一起,包括+=、-=、*=、/=、**=、//=、%=

(4)逻辑运算符

        Python中有三个逻辑运算符:and、or、not

(5)位运算符

        位运算符按二进制位对值进行操作。

  • 与 (&) 返回按位与结果。A与B值均为1时,A、B与的运算结果才为1,否则为0
  • 或 (|) 返回按位或结果。A或B值为1时,A、B或的运算结果才为1,否则为0
  • 异或 (^) 返回按位异或结果。A与B不同为1时,A、B的预算结果才为1,否则为0
  • 取反 (~) 返回按位取反结果
  • 左移位 (<<) 将符号左边数的二进制左移右边数位
  • 右移位 (>>)与左移位方式相同,但方向相反

(6)成员运算符

        使用 in 和 not in 运算符我们可以判断某个值是否在成员中

(7)身份运算符

        is 和 is not 运算符可以判断两个对象是否相同

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值