python外包面试-2025.2.28/更新

147 阅读15分钟

前言

最近想换个环境,所以一直在投外包的简历,先面面外包,涨点经验

日期2025/1/19

1、自我介绍

2、python哪些数据类型是可变的,哪些是不可变的

不可变数据类型(Immutable)

不可变对象一旦创建,其内容不能被修改。如果尝试修改,实际上是创建了一个新的对象。

  1. 整数(int)
    示例:x = 10x 的值不能直接修改,只能重新赋值。
  2. 浮点数(float)
    示例:y = 3.14y 的值不能直接修改,只能重新赋值。
  3. 布尔值(bool)
    示例:z = Truez 的值不能直接修改,只能重新赋值。
  4. 字符串(str)
    示例:s = "hello",字符串的内容不能直接修改(如 s[0] = 'H' 会报错),只能通过重新赋值或生成新字符串。
  5. 元组(tuple)
    示例:t = (1, 2, 3),元组的内容不能修改(如 t[0] = 4 会报错),只能重新赋值。
  6. 冻结集合(frozenset)
    示例:fs = frozenset([1, 2, 3]),冻结集合的内容不能修改。
可变数据类型(Mutable)

可变对象创建后,其内容可以被修改,而对象本身(内存地址)不变。

  1. 列表(list)
    示例:lst = [1, 2, 3],可以通过索引修改元素(如 lst[0] = 10),也可以添加或删除元素。

  2. 字典(dict)
    示例:d = {'a': 1, 'b': 2},可以修改、添加或删除键值对(如 d['a'] = 10 或 d['c'] = 3)。

  3. 集合(set)
    示例:s = {1, 2, 3},可以添加或删除元素(如 s.add(4) 或 s.remove(1))。

  4. 字节数组(bytearray)
    示例:ba = bytearray(b'hello'),可以通过索引修改字节(如 ba[0] = 72)。

3、django和flask的区别

  • Django

    • “全栈”框架:提供了从数据库(ORM)、模板引擎、表单处理到用户认证等一整套工具,开箱即用。
    • 约定优于配置:Django 有固定的项目结构和默认配置,适合快速开发标准化项目。
    • 适合大型项目:内置功能丰富,适合构建复杂的企业级应用。
  • Flask

    • “微框架” :核心功能简单,只提供最基本的路由和请求处理,其他功能通过扩展实现。
    • 灵活性强:开发者可以根据需求自由选择组件和工具,适合定制化开发。
    • 适合小型项目或 API 服务:轻量级,适合快速开发小型应用或 RESTful API。

4、django的values和value_list俩个方法有什么区别

1. values()

  • 返回类型:返回一个包含字典的 QuerySet,每个字典代表一行数据,字典的键是字段名,值是对应的字段值。
  • 用法:适用于需要以字典形式获取多个字段的情况。

2. values_list()

  • 返回类型:返回一个包含元组的 QuerySet,每个元组代表一行数据,元组中的元素是对应字段的值。
  • 用法:适用于需要以元组形式获取多个字段的情况,或者只获取单个字段时,可以设置 flat=True,返回一个简单的列表。

总结

  • 使用 values() 时,返回的是字典,适合需要字段名的场景。
  • 使用 values_list() 时,返回的是元组,适合需要简单数据结构的场景,特别是当只需要一个字段时,可以使用 flat=True 返回一个列表。

5、django中的Q函数和F函数有什么区别

在 Django 中,Q 和 F 是用于构建查询的两个不同工具,它们各自有不同的用途和功能。

1. Q 对象

  • 定义Q 对象用于构建复杂的查询条件,特别是当需要使用逻辑运算符(如 AND、OR)时。

  • 用途:可以用于组合多个查询条件,支持嵌套和逻辑运算。

  • 示例

    from django.db.models import Q
    # 查询名字为 'Alice' 或者年龄大于 30 的用户
    users = User.objects.filter(Q(name='Alice') | Q(age__gt=30))
    

2. F 对象

  • 定义F 对象用于引用模型字段的值,允许在查询中使用字段之间的比较。

  • 用途:可以在查询中进行字段之间的运算,比如更新某个字段的值为另一个字段的值。

  • 示例

    from django.db.models import F
    # 将用户的年龄增加 1
    User.objects.filter(name='Alice').update(age=F('age') + 1)
    

总结

  • Q:用于构建复杂的查询条件,支持逻辑运算。
  • F:用于引用模型字段的值,支持字段之间的运算。

6、jwt、session、cookie的区别,jwt由哪几部分组成

JWT(JSON Web Token)、Session 和 Cookie 是 Web 开发中常用的身份验证和状态管理机制,它们之间有一些重要的区别:

1. JWT(JSON Web Token)

  • 定义:JWT 是一种开放标准(RFC 7519),用于在网络应用环境间以 JSON 对象安全地传递信息。信息可以被验证和信任,因为它是数字签名的。
  • 存储:通常存储在客户端的本地存储或 Cookie 中。
  • 无状态:JWT 是无状态的,服务器不需要存储会话信息。所有信息都包含在 JWT 中。
  • 结构:JWT 由三部分组成:头部(Header)、载荷(Payload)和签名(Signature)。
  • 使用场景:适用于分布式系统和微服务架构,能够在不同的服务间传递用户身份信息。

2. Session

  • 定义:Session 是一种在服务器端存储用户会话信息的机制。每个用户在服务器上都有一个唯一的会话 ID。
  • 存储:会话数据存储在服务器的内存或数据库中,客户端通过 Cookie 存储会话 ID。
  • 有状态:Session 是有状态的,服务器需要维护会话信息。
  • 安全性:由于会话数据存储在服务器上,安全性相对较高。
  • 使用场景:适用于需要存储大量用户数据的应用,如购物车、用户偏好设置等。

3. Cookie

  • 定义:Cookie 是由服务器发送到客户端并存储在用户浏览器中的小数据块。它们用于存储用户的状态信息。
  • 存储:存储在客户端的浏览器中,通常用于保存用户的登录状态、偏好设置等。
  • 有状态:Cookie 本身不存储会话信息,但可以与 Session 结合使用。
  • 大小限制:每个 Cookie 的大小通常限制在 4KB 左右。
  • 使用场景:适用于存储小量的用户信息,如用户偏好、登录状态等。

总结

  • JWT 是一种无状态的身份验证机制,适合分布式系统。
  • Session 是有状态的,适合需要存储大量用户数据的应用。
  • Cookie 是存储在客户端的小数据块,通常用于保存用户的状态信息。

7、mysql如何对sql进行调优

1. 使用索引

  • 创建索引:在查询中经常使用的列上创建索引,可以显著提高查询速度。
  • 选择合适的索引类型:根据查询的特点选择合适的索引类型(如 B-tree、哈希索引等)。
  • 避免过多索引:虽然索引可以加速查询,但过多的索引会影响插入、更新和删除操作的性能。

2. 优化查询语句

  • 选择必要的列:使用 SELECT 语句时,只选择需要的列,避免使用 SELECT *
  • 使用 WHERE 子句:通过 WHERE 子句过滤不必要的数据,减少返回的行数。
  • 避免子查询:尽量使用连接(JOIN)代替子查询,尤其是在子查询返回大量数据时。

3. 使用连接(JOIN)

  • 选择合适的连接类型:根据数据的特点选择合适的连接类型(如 INNER JOIN、LEFT JOIN 等)。
  • 优化连接条件:确保连接条件使用索引列,以提高连接效率。

4. 分析执行计划

  • 使用 EXPLAIN:在执行 SQL 查询之前,使用 EXPLAIN 语句查看查询的执行计划,识别潜在的性能瓶颈。
  • 分析执行顺序:检查表的访问顺序、使用的索引、连接类型等,确保查询的执行顺序是最优的。

8、mysql中where和having的区别

在 MySQL 中,WHERE 和 HAVING 都用于过滤数据,但它们的使用场景和功能有所不同。以下是它们的主要区别:

1. 使用位置

  • WHERE:在 SELECT 语句中,WHERE 子句用于在数据被分组之前过滤记录。它通常用于过滤行数据。
  • HAVING:在 GROUP BY 子句之后使用,HAVING 用于过滤分组后的结果。它通常用于过滤聚合函数的结果。

2. 适用条件

  • WHERE:可以用于任何列的条件,包括非聚合列。
  • HAVING:通常用于聚合函数(如 SUMCOUNTAVG 等)的条件。

2025/2/28 更新 软通动力

1、进程、线程和协程的区别

1. 基本概念
  • 进程

    • 进程是操作系统分配资源的基本单位,每个进程有独立的内存空间。
    • 进程之间相互隔离,一个进程崩溃不会影响其他进程。
    • 在 Python 中,可以通过 multiprocessing 模块创建和管理进程。
  • 线程

    • 线程是操作系统调度的基本单位,是进程内的执行单元。
    • 线程共享进程的内存空间,因此线程间通信更方便,但也更容易出现资源竞争问题。
    • 在 Python 中,可以通过 threading 模块创建和管理线程。
  • 协程

    • 协程是一种用户态的轻量级线程,由程序员在代码中显式控制调度。
    • 协程不需要操作系统介入,切换开销小,适合高并发 I/O 密集型任务。
    • 在 Python 中,可以通过 asyncio 模块和 async/await 语法实现协程。
2. 区别与联系
特性进程线程协程
资源占用高(独立内存空间)中(共享内存空间)低(用户态调度)
切换开销
并发性多进程并行多线程并发高并发(单线程内)
适用场景CPU 密集型任务I/O 密集型任务高并发 I/O 密集型任务
通信方式进程间通信(IPC)共享内存事件循环、回调
隔离性高(进程间隔离)低(线程间共享内存)中(任务间独立)
3. 实际应用
  • 进程

    • 适合 CPU 密集型任务,如科学计算、图像处理。

    • 示例:

      from multiprocessing import Process
      
      def task():
          print("Process is running")
      
      if __name__ == "__main__":
          p = Process(target=task)
          p.start()
          p.join()
      
  • 线程

    • 适合 I/O 密集型任务,如文件读写、网络请求。

    • 示例:

      from threading import Thread
      
      def task():
          print("Thread is running")
      
      t = Thread(target=task)
      t.start()
      t.join()
      
  • 协程

    • 适合高并发 I/O 密集型任务,如 Web 服务器、爬虫。

    • 示例:

      import asyncio
      
      async def task():
          print("Coroutine is running")
      
      async def main():
          await asyncio.gather(task(), task())
      
      asyncio.run(main())
      

2、python列表和字典的一些方法

列表(List)常用方法

  1. append()  :

    • 功能: 在列表末尾添加一个元素。

    • 例子:

      my_list = [1, 2, 3]
      my_list.append(4)
      print(my_list)  # 输出: [1, 2, 3, 4]
      
  2. extend()  :

    • 功能: 将一个列表的所有元素添加到另一个列表的末尾。

    • 例子:

      my_list = [1, 2, 3]
      my_list.extend([4, 5])
      print(my_list)  # 输出: [1, 2, 3, 4, 5]
      
  3. insert()  :

    • 功能: 在指定位置插入一个元素。

    • 例子:

      my_list = [1, 2, 3]
      my_list.insert(1, 1.5)
      print(my_list)  # 输出: [1, 1.5, 2, 3]
      
  4. remove()  :

    • 功能: 移除列表中第一个匹配的元素。

    • 例子:

      my_list = [1, 2, 3, 2]
      my_list.remove(2)
      print(my_list)  # 输出: [1, 3, 2]
      
  5. pop()  :

    • 功能: 移除并返回列表中指定位置的元素(默认是最后一个元素)。

    • 例子:

      my_list = [1, 2, 3]
      popped_element = my_list.pop(1)
      print(popped_element)  # 输出: 2
      print(my_list)  # 输出: [1, 3]
      
  6. index()  :

    • 功能: 返回列表中第一个匹配元素的索引。

    • 例子:

      my_list = [1, 2, 3, 2]
      index = my_list.index(2)
      print(index)  # 输出: 1
      
  7. count()  :

    • 功能: 返回列表中某个元素出现的次数。

    • 例子:

      my_list = [1, 2, 3, 2]
      count = my_list.count(2)
      print(count)  # 输出: 2
      
  8. sort()  :

    • 功能: 对列表进行排序(默认是升序)。

    • 例子:

      my_list = [3, 1, 2]
      my_list.sort()
      print(my_list)  # 输出: [1, 2, 3]
      
  9. reverse()  :

    • 功能: 反转列表中的元素顺序。

    • 例子:

      my_list = [1, 2, 3]
      my_list.reverse()
      print(my_list)  # 输出: [3, 2, 1]
      

字典(Dictionary)常用方法

  1. keys()  :

    • 功能: 返回字典中所有的键。

    • 例子:

      my_dict = {'a': 1, 'b': 2, 'c': 3}
      keys = my_dict.keys()
      print(keys)  # 输出: dict_keys(['a', 'b', 'c'])
      
  2. values()  :

    • 功能: 返回字典中所有的值。

    • 例子:

      my_dict = {'a': 1, 'b': 2, 'c': 3}
      values = my_dict.values()
      print(values)  # 输出: dict_values([1, 2, 3])
      
  3. items()  :

    • 功能: 返回字典中所有的键值对。

    • 例子:

      my_dict = {'a': 1, 'b': 2, 'c': 3}
      items = my_dict.items()
      print(items)  # 输出: dict_items([('a', 1), ('b', 2), ('c', 3)])
      
  4. get()  :

    • 功能: 返回指定键的值,如果键不存在则返回默认值(默认为None)。

    • 例子:

      my_dict = {'a': 1, 'b': 2, 'c': 3}
      value = my_dict.get('b')
      print(value)  # 输出: 2
      
  5. pop()  :

    • 功能: 移除并返回指定键的值。

    • 例子:

      my_dict = {'a': 1, 'b': 2, 'c': 3}
      popped_value = my_dict.pop('b')
      print(popped_value)  # 输出: 2
      print(my_dict)  # 输出: {'a': 1, 'c': 3}
      
  6. update()  :

    • 功能: 更新字典中的键值对(可以添加新的键值对或更新已有的键值对)。

    • 例子:

      my_dict = {'a': 1, 'b': 2}
      my_dict.update({'b': 3, 'c': 4})
      print(my_dict)  # 输出: {'a': 1, 'b': 3, 'c': 4}
      
  7. clear()  :

    • 功能: 清空字典中的所有键值对。

    • 例子:

      my_dict = {'a': 1, 'b': 2}
      my_dict.clear()
      print(my_dict)  # 输出: {}
      

3、python的生成器和迭代器

在Python中,生成器(Generator)  和迭代器(Iterator)  是用于处理可迭代对象的重要概念。它们可以帮助你高效地处理大量数据,尤其是在内存有限的情况下。

1. 迭代器(Iterator)

  • 定义:迭代器是一个实现了迭代协议的对象,即它必须包含__iter__()__next__()方法。

  • 作用:迭代器用于逐个访问集合中的元素,而不需要一次性将所有元素加载到内存中。

  • 特点

    • 迭代器只能向前遍历,不能回退。
    • 一旦迭代器耗尽(即__next__()引发StopIteration异常),就不能再次使用。

示例

class MyIterator:
    def __init__(self, max_num):
        self.max_num = max_num
        self.current = 0

    def __iter__(self):
        return self

    def __next__(self):
        if self.current < self.max_num:
            self.current += 1
            return self.current
        else:
            raise StopIteration

# 使用迭代器
my_iter = MyIterator(5)
for num in my_iter:
    print(num)

2. 生成器(Generator)

  • 定义:生成器是一种特殊的迭代器,使用yield关键字来生成值。

  • 作用:生成器允许你按需生成值,而不是一次性生成所有值,从而节省内存。

  • 特点

    • 生成器函数在调用时不会立即执行,而是返回一个生成器对象。
    • 每次调用next()或使用for循环时,生成器函数会执行到yield语句,返回一个值,并暂停执行,直到下一次调用。

示例

def my_generator(max_num):
    current = 0
    while current < max_num:
        current += 1
        yield current

# 使用生成器
gen = my_generator(5)
for num in gen:
    print(num)

3. 生成器表达式

生成器表达式与列表推导式类似,但使用圆括号而不是方括号。它返回一个生成器对象,而不是一个列表。

示例

gen_exp = (x * x for x in range(5))
for num in gen_exp:
    print(num)

4. 迭代器与生成器的区别

  • 实现方式:迭代器通常通过类实现,而生成器通过函数实现。
  • 内存使用:生成器更节省内存,因为它按需生成值,而不是一次性生成所有值。
  • 代码简洁性:生成器通常更简洁,尤其是使用yield时。

5. 使用场景

  • 迭代器:适用于需要自定义迭代行为的场景。
  • 生成器:适用于处理大量数据或需要按需生成值的场景。

6. 内置函数

Python提供了许多内置函数来处理迭代器和生成器,例如:

  • iter():将可迭代对象转换为迭代器。
  • next():获取迭代器的下一个值。
  • enumerate():为可迭代对象添加索引。
  • zip():将多个可迭代对象组合在一起。

示例

# 使用内置函数
my_list = [1, 2, 3]
my_iter = iter(my_list)
print(next(my_iter))  # 输出: 1

4、mysql的InnoDB和MyISAM引擎区别

InnoDB 和 MyISAM 是 MySQL 数据库中两种常见的存储引擎,它们在功能、性能和适用场景上有显著的区别。以下是它们的主要区别:

1. 事务支持

  • InnoDB:支持事务(ACID 特性),可以确保数据的完整性和一致性。适用于需要事务处理的应用程序,如银行系统、电商平台等。
  • MyISAM:不支持事务,适合不需要事务支持的简单查询和插入操作。

2. 外键支持

  • InnoDB:支持外键约束,可以维护表与表之间的引用完整性。
  • MyISAM:不支持外键。

3. 锁定机制

  • InnoDB:支持行级锁定,可以在更细粒度的层次上进行并发控制,减少锁冲突,提高并发性能。
  • MyISAM:仅支持表级锁定,当有写操作时,会锁定整个表,影响并发性能。

4. 崩溃恢复

  • InnoDB:具有崩溃恢复能力,可以在数据库崩溃后通过日志文件恢复数据。
  • MyISAM:崩溃后数据恢复较为困难,可能会导致数据丢失。

5. 存储结构

  • InnoDB:数据和索引存储在一个文件中(表空间),支持更复杂的查询和操作。
  • MyISAM:数据和索引分别存储在不同的文件中,结构较为简单。

6. 全文索引

  • InnoDB:在 MySQL 5.6 及以上版本中支持全文索引。
  • MyISAM:较早支持全文索引,适用于全文搜索场景。

7. 性能

  • InnoDB:在需要高并发、事务处理的场景下性能更好。
  • MyISAM:在大量读取操作且不需要事务支持的场景下性能较好。

8. 适用场景

  • InnoDB:适用于需要事务、外键、高并发和复杂查询的应用场景。
  • MyISAM:适用于读多写少、不需要事务支持的简单应用场景。

总结

  • InnoDB:更适合现代应用,特别是在需要事务处理和高并发的情况下。
  • MyISAM:适用于传统应用,特别是在读取操作远多于写入操作的场景。