1、python 语言的基础特性

  • python中一切皆对象:
    • 在python中,无论函数、类、模块等等都是对象,他们都继承自object
    • 所有变量的本质都是对象的引用(指针)
  • 动态解释性语言:
    • python是解释性语言,运行时需要一行一行解释执行,不会编译成二进制文件执行。
    • python类型是动态的:变量无需声明类型,运行时动态决定。
  • python的数据类型
    • 内置数据类型: int float dict set list str bool tuple
      • 可变数据类型: list dict set
      • 不可变数据类型:int float tuple
  • 函数式编程的支持:
    • python支持高阶函数、lambda、map/filter/reduce、生成器和迭代器
    • 主要功能节省内存
    • 迭代器
      • 定义:实现了__iter__和__next__方法的对象
      • 特点:
        • 按顺序逐个访问元素
        • 只能向前遍历icing
        • 节省内存,不会一次性加上所有元素
          常见的迭代器: iter(list) 、 iter(dict)、open() 返回的文件对象
    • 生成器
      • 定义: 一种特殊的迭代器,用yield返回数据
      • 特点:
        • 惰性计算: 只在需要生成时生成值
        • 语法简洁,比写完整的迭代器类跟更方便
        • 自动实现__iter__() 和 next() 方法
    • 什么时候用迭代器,什么使用用生成器
      • 迭代器:
        • 需要对自定义对象支持for…in … 遍历
        • 比如设计一个树结果,希望for node in tree 能迭代所有节点
      • 生成器:
        • 数据量大,不相一次性加载数据到内存
        • 流式处理(语音帧、日志流、网络数据流)
        • 典型的场景:
        1
        2
        3
        4
        5
        6
        7
        # 文件逐行读取
        def read_file(path):
        with open(path) as f:
        for line in f:
        yield line

        无限序列(斐波那契、自然数流)

2、常见算法: 散列表、红黑树、二叉树,能否对应适合的应用场景(通用)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31

┌───────────────┐
│ 数据结构 │
└──────┬────────┘

┌──────────────┴───────────────┐
│ │
┌─────────────┐ ┌─────────────┐
│ 散列表 │ │ 树类 │
│ (Hash Table) │ └─────┬───────┘
└─────┬───────┘ │
│ │
┌───────┴─────────┐ ┌────────┴─────────┐
│ │ │ │
Key-Value / Set 特点:查找快 二叉树 堆
典型应用: O(1) 平均 │ │
- 去重 优点:快速 ├─────┬─────────┤
- 缓存 缺点:无序 BST 红黑树 完全二叉树
- 频率统计 │ │ │
- 映射表 │ │ │
范围查找 平衡树 O(log n) TopK/优先队列
排序维护 系统调度 /排行榜

| 数据结构 | 特性 | 时间复杂度(查/增/删) | 典型应用场景 |
| ---------------------------------- | --------------------- | --------------------------------- | ------------------------------------------------------------------------- |
| **散列表(Hash Table / dict, set)** | 无序,基于哈希,O(1) 平均查找 | 查 O(1),增 O(1),删 O(1) | - 唯一性检查(去重)<br>- 频率统计(词频、日志统计)<br>- 缓存(LRU/Redis)<br>- 快速查找(用户 ID → 信息映射) |
| **二叉树(Binary Tree)** | 每个节点最多两个子节点 | 查 O(n),增 O(n),删 O(n)(普通二叉树) | - 表示分层结构(组织结构、文件目录)<br>- 基础遍历算法练习(前序、中序、后序)<br>- 递归问题(DFS、回溯) |
| **二叉搜索树(BST, Binary Search Tree)** | 左 < 根 < 右 | 平均查 O(log n),最坏 O(n) | - 排序存储数据<br>- 快速查找 / 范围查询(如查找 > x 且 < y 的值) |
| **平衡二叉树(AVL / 红黑树)** | 保持高度平衡 → O(log n) 查增删 | 查 O(log n),增 O(log n),删 O(log n) | - 高速查找 + 动态更新<br>- Java TreeMap、C++ map/set 底层<br>- 操作系统任务调度(红黑树管理定时器) |
| **堆(Heap / 优先队列)** | 完全二叉树,父节点 ≥ / ≤ 子节点 | 查最大/最小 O(1),增 O(log n),删 O(log n) | - Top K 问题(高频元素、排行榜)<br>- 实时任务调度(优先队列)<br>- Dijkstra / A\* 算法中的最短路径 |

2.1 散列表(Hash Table /dict ,set)

定义

  • 基于哈希函数,将key映射到内存地址存储值
  • python的dict和set就是典型的实现

特性

  • 无序存储(python3.7+ dict保存,但逻辑上还是哈希表)
  • 支持快速查询、插入、删除
  • 通过哈希碰撞处理(开发寻址或者链表)

时间复杂度

1
2
3
4
5
| 操作 | 平均   | 最坏 |
| -- | ---- | ---- |
| 查找 | O(1) | O(n) |
| 插入 | O(1) | O(n) |
| 删除 | O(1) | O(n) |

典型引用场景

  • 去重:set存储已访问元素
  • 频率统计:词频统计、日志统计
  • 缓存/映射表:用户ID–> 用户信息
  • 面试高频题目:

1、两数之和

1
2
3
4
5
6
7
8
9
10
11
12
13
14

# https://leetcode.cn/problems/two-sum/

class Solution:
def twoSum(self, nums: List[int], target: int) -> List[int]:
d = {}
# [2,7,11,15] 9
for i, num in enumerate(nums):
if target - num in d:
return [d[target-num], i] # [1,0]
d[num] = i # d[2]
# 标记数字跟索引之间的关系
d = {2: 0,7:1, 11:2,15:3 }

2、统计词频 TopK

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# https://leetcode.cn/problems/word-frequency/

words = """
the day is sunny the the
the sunny is is
"""

res = {}

def count(words: str):
lines = words.strip().split("\n")
for line in lines:
ls = str(line).strip().split(" ")
for j in ls:
if j in res.keys():
res[j] = res[j] + 1
else:
res[j] = 1
return res

print(count(words))

from collections import Counter

# 或者counter = Counter([data])

2.2 二叉树 & 二叉搜索树

定义

  • 每个节点最多有两个子节点(左右)
  • BST 左边 < 根 < 右

特性

  • 树形结构 --> 支持分层、递归处理
  • 中序遍历BST --> 得到有序列表
操作 普通二叉树 BST(平均) BST(最坏退化成链)
查找 O(n) O(log n) O(n)
插入 O(n) O(log n) O(n)
删除 O(n) O(log n) O(n)

典型的应用场景

  • 分层结构表示: 组织结构、文件目录
  • 排序存储+ 范围查询
  • 遍历恩替(DFS、BFS、回溯)

常见题

  • 二叉树最大深度
1
2
3
4
5
6
7
8
 
# https://leetcode.cn/problems/er-cha-shu-de-shen-du-lcof/description/
def maxDepth(root):
if not root:
return 0
return 1 + max(maxDepth(root.left),maxDepth(root.right))

# 递归DFS
  • 验证BST
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

# Definition for a binary tree node.
# class TreeNode(object):
# def __init__(self, val=0, left=None, right=None):
# self.val = val
# self.left = left
# self.right = right
class Solution(object):
def isValidBST(self, root,low=float('-inf'), high=float('inf')):
"""
:type root: Optional[TreeNode]
:rtype: bool
"""
if not root:
return True
if not rlow < root.val < high:
return False
return self.isValidBST(root.left, low, root.val) and self.isValidBST(root.right, root.val, high)
# 核心点:递归 + 边界判断

2.3 红黑树(自平衡二叉搜索树)

定义

  • 自平衡二叉搜索树

特性

  • 根节点黑色

  • 红节点不能连续

  • 任意路径黑节点数量相同

  • 保证 O(log n) 查找/增删

操作 时间
查找 O(log n)
插入 O(log n)
删除 O(log n)
典型应用场景

需要动态维护有序数据的场景

系统底层实现:

Java TreeMap / TreeSet

C++ map / set

高频题:动态排行榜、区间查询、调度系统

2.4 堆(Heap/优先队列)

定义

完全二叉树

父节点 ≥ 子节点(最大堆)或 ≤ 子节点(最小堆)

特性

查找最大/最小元素 O(1)

插入、删除 O(log n)

典型应用场景

Top K 问题(高频词、排行榜)

优先级任务调度(调度器、操作系统)

图算法(Dijkstra, Prim)

3、Pytorch框架的搭建

4、python闭包、装饰器、异常捕获、多线程用法?

1、python闭包

定义
函数内部定一函数,并且内部函数引用了外部函数的局部变量,就形成了闭包。
闭包能保存函数运行时的环境。

1
2
3
4
5
6
7
8

def make_multiplier(factor):
def multiply(x):
return x* factor #引用外部变量
return multiply

times2 = make_multiplier(2)
print(times2(5)) # 10

✅ 面试考点:

闭包常用于延迟计算、函数工厂、隐藏实现细节。

注意 Python 中闭包变量是 引用 而非拷贝。

2、装饰器(Decorator)

定义
本质是一个函数,接收一个函数作为参数,返回一个增强后的函数
常用语日志、权限检验、性能统计、缓存等等

1
2
3
4
5
6
7
8
9
10
11
12
def time(func):
def wapper(*args,**kwargs):
start = time.time()
result = func(*args,**kwargs)
print(f"{func.__name__} 耗时: {time.time() - start:.4f}s")
return result
return wrapper

def slow_function():
time.sleep(1)

slow_function()

3、异常捕获

Python 用 try-except-finally 来处理异常,保证程序健壮性。

1
2
3
4
5
6
7
8
9
10
11
try:
x = 1 / 0
except ZeroDivisionError as e:
print("除零错误:", e)
except Exception as e:
print("其他错误:", e)
else:
print("没有异常时执行")
finally:
print("无论如何都会执行")

4、多线程(Threading)

Python 提供 threading 模块,但要注意 GIL 限制:CPU 密集型任务不能真正并行,但 I/O 密集型任务(网络、磁盘)有明显加速。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import Threading
import time

def worker(name):
print(f"{name} 开始工作")
time.sleep(1)
print(f"{name} 完成")

threads = []
for i range(3):
t = threading.Thread(target=worker, args=(f"线程{i}",))
t.start()
threads.append(t)

for t in threads:
t.join()

I/O 密集型 → threading / concurrent.futures.ThreadPoolExecutor。

CPU 密集型 → multiprocessing(绕开 GIL)。

threading.Lock() / RLock() 用于线程同步。

10、python中with语句的了解?

1、with语句是什么?

with是上下文管理器的语法糖,用来简化资源的获取和释放
核心的两个方法是:
- __enter__(self):  进入上下文时执行
- __exit__(self, exc_type, exc_val, exc_tb)): 退出上下文执行,无论是否发生异常

2、语法

1
2
3
4
5
6
7
8
9
10
11
12

# 文件操作
with open("test.txt","w") as f:
f.write("Hello world!!")
# 自动关闭文件

# 等价于
f = open("test.txt",w)
try:
f.write("Hello world!!")
finally:
f.close()

3、自定义上下文管理器

1
2
3
4
5
6
7
8
9
10
11
12

class MyResource:
def __enter__(self):
print("资源初始化")
return self
def __exit__(self, exc_type, exc_val, exc_tb):
print("资源释放")
return False # 返回 True 可以屏蔽异常

with MyResource() as r:
print("使用资源")

11、python多线程的用法

Python 提供threading模块

1、启动方式

  • 方式1: 直接创建Thread
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import threading
import time

def worker(name):
print(f"{name} 开始工作")
time.sleep(1)
print(f"{name} 完成")

# 创建并启动线程
t1 = threading.Thread(target=worker,args =("线程1"))
t2 = threading.Thread(target=worker,args = ("线程2"))

t1.start()
t2.start()

# 等等所有线程结束
t1.join()
t2.join()

  • 方式2:继承Thread
1
2
3
4
5
6
7
8
9
10
11
class MyThread(thread.Thread):
def __init__(self,name):
super().__int__()
self.name = name

def run(self):
print(f"{self.name} 开始工作")

t = Thread("线程A")
t.start()
t.join()

2、现成同步(锁)

多线程同时访问共享数据时,容易出现竞态条件,需要用 锁 Lock。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

lock = threading.Lock()
counter = 0

def safe_worker():
global counter
with lock: # 自动上锁解锁
for _ in range(100000):
counter += 1

threads = [threading.Thread(target=safe_worker) for _ in range(5)]
[t.start() for t in threads]
[t.join() for t in threads]

print("最终计数:", counter)
# 👉 没有锁时,结果可能小于 5 * 100000。

3、线程池(推荐)ThreadPoolExecutor

1
2
3
4
5
6
7
8
9
10
11
12

from concurrent.futures import ThreadPoolExecutor
import time

def task(n):
time.sleep(1)
return n * n

with ThreadPoolExecutor(max_workers=3) as executor:
results = executor.map(task, [1, 2, 3, 4, 5])
print(list(results))

4. GIL 限制

Python 有 GIL(全局解释器锁),同一时刻只有一个线程能执行 Python 字节码。

因此:
CPU 密集型任务(计算) → 适合用 multiprocessing(多进程)。
I/O 密集型任务(网络请求、文件读写) → 多线程能显著提升性能。

12、如何提高python执行效率的方法用过哪些?

1. 算法与数据结构优化(最重要)

时间复杂度 > 语言性能

例:搜索用 set/dict(O(1))替代 list(O(n))。

例:用堆 (heapq) 实现 TopK,比排序快。

应用场景:语音识别时,查询词典用 dict 而不是 list。

2. 内置函数和库替代手写循环

Python 内置函数(sum, map, any, all)和 列表推导式 通常比手动 for 循环快。

NumPy/Pandas:矩阵、数据处理用 C 实现,比 Python 循环高效几个数量级。

import numpy as np
a = np.arange(1e6)
print(np.sum(a)) # 比 for 循环快很多

3. 并行与并发

多线程 (threading):适合 I/O 密集型(语音流读取、网络请求)。

多进程 (multiprocessing):适合 CPU 密集型(语音特征提取、模型推理)。

异步 (asyncio):高并发网络任务。

应用场景:车载语音系统中,多线程负责多个音频流并发录音;多进程负责特征提取。

4. JIT 编译 & C 扩展

PyPy:带 JIT 编译,比 CPython 快。

Cython:将 Python 代码编译为 C,提高数倍性能。

Numba:用 @jit 装饰器,加速数值计算。

from numba import jit

@jit(nopython=True)
def add(a, b):
return a + b

5## . 内存管理优化

生成器 (yield) 替代一次性加载(节省内存)。

迭代器 代替列表,避免存储全部数据。

应用场景:逐帧读取语音文件,而不是一次性加载整个音频。

6. 减少不必要的开销

避免重复计算(缓存结果,用 functools.lru_cache)。

局部变量比全局变量访问快。

避免频繁的字符串拼接,用 str.join()。

from functools import lru_cache

@lru_cache(maxsize=128)
def fib(n):
if n < 2: return n
return fib(n-1) + fib(n-2)

7. 使用合适的解释器 & 框架

CPython:默认实现。

PyPy:JIT 加速。

C/C++ 扩展:关键部分用 C 实现(如 torch, numpy)。

应用场景:深度学习框架 PyTorch 底层就是 C++/CUDA。

8. 分布式与缓存

多机并行(Ray, Dask, Spark)。

缓存:热点数据放 Redis,减少重复计算。

13、*args和**kwargs的区别是什么?

1. *args

作用:接收 任意数量的位置参数,会打包成一个 元组。

适合参数个数不确定的函数。

def foo(*args):
print(args)

foo(1, 2, 3)

输出: (1, 2, 3)

2. **kwargs

作用:接收 任意数量的关键字参数,会打包成一个 字典。

适合需要灵活传递键值对参数的场景。

def bar(**kwargs):
print(kwargs)

bar(a=1, b=2, c=3)

输出: {‘a’: 1, ‘b’: 2, ‘c’: 3}

3. *args 和 **kwargs 一起用

一般写法:def func(*args, **kwargs)

*args 处理位置参数

**kwargs 处理关键字参数

def func(*args, **kwargs):
print(“args:”, args)
print(“kwargs:”, kwargs)

func(1, 2, x=10, y=20)

args: (1, 2)

kwargs: {‘x’: 10, ‘y’: 20}

  1. 区别总结
    特性 *args **kwargs
    参数形式 位置参数 关键字参数
    数据类型 元组 (tuple) 字典 (dict)
    应用场景 参数数量不定(如加法函数) 配置灵活(如传递参数给API)
  2. 面试延伸问题(华为 OD 常问)

❓ 为什么要用 *args 和 **kwargs?
👉 提高函数的通用性和可扩展性,适用于接口设计、装饰器开发。

❓ 如果调用函数时用 * 或 ** 会怎样?
👉 会进行 参数解包:

def add(x, y): return x + y
nums = (1, 2)
print(add(*nums)) # 3

params = {“x”: 3, “y”: 4}
print(add(**params)) # 7

❓ 在装饰器里为什么常见 *args, **kwargs?
👉 因为装饰器要支持 任意函数签名,保证通用性。

⚡ 记忆口诀:

*args → tuple → 位置参数

**kwargs → dict → 关键字参数

14、Django、Flask、Tornado三大框架各种应用的场景?

1. Django —— 重量级、全家桶

特点:

自带 ORM、模板系统、Admin 后台、用户认证等一整套“全家桶”。

遵循 MTV 模式,强调快速开发、约定大于配置。

有较多内置组件,适合开发复杂的大型 Web 应用。

适用场景:

大型企业应用、内容管理系统(CMS)、电商平台、新闻门户网站。

对数据一致性、权限管理要求高的系统。

典型案例: Instagram、知乎早期。

2. Flask —— 轻量级、自由度高

特点:

只有最核心的功能(路由 + WSGI 支持),其余功能通过扩展实现。

灵活度高,开发者可以自由选择 ORM(SQLAlchemy、Peewee 等)、模板引擎等。

学习曲线较低,适合快速搭建原型。

适用场景:

中小型 Web 应用、原型验证、API 服务、微服务。

对框架约束少,希望灵活度高的项目。

典型案例: Pinterest、国内很多中小型 SaaS。

3. Tornado —— 高性能异步框架

特点:

内置高性能异步非阻塞 I/O,适合处理长连接和高并发请求。

自带 Web Server,不依赖 Gunicorn/uWSGI。

学习成本稍高,生态不如 Django/Flask 丰富。

适用场景:

即时通讯(IM)、WebSocket、长轮询、实时推送系统。

对高并发、低延迟有要求的后台服务。

典型案例: FriendFeed(Facebook 收购的实时社交网站)。

✅ 一句话总结:

Django:全家桶,适合 大型复杂系统。

Flask:轻量自由,适合 中小项目、微服务、原型。

Tornado:异步高并发,适合 实时系统。

__END__