Python基础知识Python进阶之路大数据 爬虫Python AI Sql

Python后端面试(持续更新)

2019-03-14  本文已影响20人  dreamkong

Python后端

Python后端技术栈

Web请求的流程

Python语言基础

算法与数据结构

编程范式

操作系统

网络编程

数据库

Python Web框架

系统设计

技术之外,软实力

Python初、中级工程师技能要求

初级工程师

中级工程师

软技能

面试准备

简历书写与自我介绍

简历内容

简历加分项

简历注意事项

自我介绍

image

行为面试题与表达技巧

什么是行为面试

根据候选人过去的行为评测其胜任能力

行为面试套路

STAR模型

image

面试官一般会问:你还有什么要问我的吗?

注意事项

Python语言基础常见考题

Python是静态还是动态类型?是强类型还是弱类型?

Python作为后端语言优缺点

什么是鸭子类型

什么是monkey patch

什么是自省(Introspection)

什么是列表和字典推导式(List Comprehension)

Python2/3对比

Python3改进

def hello(name: str) -> str:
   return 'hello' + name
class Base(object):
 def hello(self):
     print('say hello')

class C(Base):
 def hello(self):
         # py2
     return super(C, self).hello()

class C2(Base):
 def hello(self):
         # py3
     return super().hello()
def add(a, b, *, c):
    print(a+b+c)

# 会报错
add(1, 2, 3)
# 正确写法
add(1, 2, c=3)

Python3新增

Python2/3工具

Python函数常考题

以下Python代码分别输出什么?

def flist(l):
    l.append(0)
    print(l)
    ​
l = []
flist(l) #[0]
flist(l) #[0, 0]
def fstr(s):
    s + = 'a'
    print(s)

s = 'hehe'
fstr(s) #'hehea'
fstr(s) #'hehea'

Python如何传递参数?

Python可变/不可变对象

测试

# 一个小例题,请问这段代码会输出什么结果?
# first
def clear_list(l):
    l = []

ll = [1, 2, 3]
clear_list(ll)
print(ll)
​
# second
# 默认参数只计算一次
def flist(l=[1]):
    l.append(1)
    print(l)

flist()
flist()

Python *args, *kwargs

Python异常机制常考题

什么是Python异常?

什么时候需要捕获处理异常?看Python内置异常类型

如何处理Python异常

try:
    # func                            # 可能会抛出异常的代码
except (Exception1, Exception2) as e: # 可以捕获多个异常并处理
    # 异常处理代码
else:
    pass                              # 异常没有发生的时候代码逻辑
finally:
    pass                              # 无论异常有没有发生都会执行的代码,一般处理资源的关闭和释放

如何自定义异常

class MyException(Exception):
    pass 
​
try:
    raise MyException('my exception')
except MyException as e:
    print(e)

Python性能分析与优化,GIL常考题

什么是Cpython GIL

GIL影响

如何规避GIL影响

image

问题

import threading
​
n = [0]
​
def foo():
    n[0] = n[0] + 1
    n[0] = n[0] + 1

threads = []
for i in range(50000):
    t = threading.Thread(target=foo)
    threads.append(t)

for t in threads:
    t.start()

print(n)

# 大多数情况下打印10000,偶尔打印9998,Python的多线程并不是绝对安全的

为什么有了GIL还要关注线程安全

import dis
​
def update_list(l):
 # 原子操作,不用担心线程安全问题
    l[0] = 1

dis.dis(update_list)
'''
 5           0 LOAD_CONST               1 (1)
 2 LOAD_FAST                0 (l)
 4 LOAD_CONST               2 (0)
 6 STORE_SUBSCR             # 字节码操作,线程安全
 8 LOAD_CONST               0 (None)
 10 RETURN_VALUE
'''
​
def incr_list(l):
 # 危险!不是原子操作
    l[0] += 1

dis.dis(incr_list)
'''
 3           0 LOAD_FAST                0 (l)
 2 LOAD_CONST               1 (0)
 4 DUP_TOP_TWO
 6 BINARY_SUBSCR
 8 LOAD_CONST               2 (1)
 10 INPLACE_ADD              # 需要多个字节码操作,有可能在线程执行过程中切到其他线程
 12 ROT_THREE
 14 STORE_SUBSCR
 16 LOAD_CONST               0 (None)
 18 RETURN_VALUE
'''

如何剖析程序性能

服务端性能优化措施

Python生成器与协程

生成器(Generator)

def simple_gen():
    yield 'hello'
    yield 'world'

gen = simple_gen()
print(type(gen))
print(next(gen))
print(next(gen))
'''
<class 'generator'>
hello
world
'''

基于生成器的协程

def coro():
    # yield关键字在=右边作为表达式,可以被send值
    hello = yield 'hello'
    yield hello

c = coro()
# 输出'hello',这里调用next产出第一个值'hello',之后函数暂停
print(next(c))
# 再次调用send发送值,此时hello变量赋值为'world',然后yield产出hello变量的值'world'
print(c.send('world'))
# 之后协程结束,后续再send值会抛出异常StopIteration

协程注意点

协程装饰器

from functools import wraps

def coroutine(func):
    '''
    装饰器:向前执行一个yield表达式,预激func
    '''
    @wraps(func)
    def primer(*args, **kwargs):
        gen = func(*args, **kwargs)
        next(gen)
        return gen
    return primer

Python3.5引入async/await支持原生协程(native coroutine)

import asyncio
import datetime
import random

async def display_date(num, loop):
    end_time = loop.time() + 50.0
    while True:
        print('Loop: {} Time: {}'.format(num, datetime.datetime.now()))
        if (loop.time() + 1.0) >= end_time:
            break
        await asyncio.sleep(random.randint(0, 5))
        
      
loop = asyncio.get_event_loop()
asyncio.ensure_future(display_date(1, loop))
asyncio.ensure_future(display_date(2, loop))
loop.run_forever()

Python单元测试

什么是单元测试

为什么写单元测试

单元测试相关的库

def binary_search(arr, target):
    if not arr:
        return -1
    low, high = 0, len(arr) - 1
    while low <= high:
        mid = low + (high - low) >> 2
        if arr[mid] == target:
            return mid
        elif arr[mid] > target:
            high = mid - 1
        else:
            low = mid + 1
    return - 1


def test():
    '''
    如何设计测试用例:
    - 正常值功能测试
    - 边界值(比如最大最小,最左最右)
    - 异常值(比如None,空值,非法值)
    '''
    # 正常值,包含有和无两种结果
    assert binary_search([0, 1, 2, 3, 4, 5], 1) == 1
    assert binary_search([0, 1, 2, 3, 4, 5], 6) == -1
    assert binary_search([0, 1, 2, 3, 4, 5], -1) == -1
    # 边界值
    assert binary_search([0, 1, 2, 3, 4, 5], 0) == 0
    assert binary_search([0, 1, 2, 3, 4, 5], 5) == 5
    assert binary_search([0], 0) == 0
    # 异常值
    assert binary_search([], 1) == -1

Python基础练习题

Python深拷贝与浅拷贝

import copy

l1 = [1, 2, 3]
l2 = l1
l3 = copy.copy(l1)
l4 = copy.deepcopy(l1)
print(l1, l2, l3, l4)
'''
[1, 2, 3] [1, 2, 3] [1, 2, 3] [1, 2, 3]
'''
l2[0] = 666
print(l1, l2, l3, l4)
'''
[666, 2, 3] [666, 2, 3] [1, 2, 3] [1, 2, 3]
'''
l3[0] = 888
print(l1, l2, l3, l4)
'''
[666, 2, 3] [666, 2, 3] [888, 2, 3] [1, 2, 3]
'''
l4[0] = 999
print(l1, l2, l3, l4)
'''
[666, 2, 3] [666, 2, 3] [888, 2, 3] [999, 2, 3]
'''

Python内置数据结构和算法常考

数据结构/算法 语言内置 内置库
线性结构 list、tuple array(数组,不常用)/collections.namedtuple
链式结构 collections.deque(双端队列)
字典结构 dict collections.Counter(计数器)/OrderedDict(有序字典)
集合结构 set/frozenset(不可变集合)
排序算法 sorted
二分算法 bisect模块
堆算法 heapq模块
缓存算法 functools.lru_cache(Least Recent Used, python3)

collections模块提供了一些内置数据结构的扩展

import collections

Point = collections.namedtuple('Point', 'x, y')
p = Point(1, 2)
print(p.x)
'''
1
'''
print(p.y)
'''
2
'''
print(p.x == p[0])
'''
True
'''
import collections

de = collections.deque()
de.append(1)
de.appendleft(0)
print(de)
'''
deque([0, 1])
'''
de.pop()
'''
1
'''
de.popleft()
'''
0
'''
print(de)
'''
deque([])
'''

Python dict底层结构

Python list/tuple区别

t = [1,2], 1, 2
t[0].append(3)
print(t)
'''
([1, 2, 3], 1, 2)
'''

什么是LRUCache?

上一篇下一篇

猜你喜欢

热点阅读