不打无准备之战,Python100道经典题目(二),参考学习(附答案)

近年来,Python在编程语言界里赚足了风头,无论是受欢迎程度,还是薪资待遇,都非常可观,相应的,Python岗位要求也越来越高,无论你是零基础还是老前辈,在Python面试中都不能轻视。

不打无准备之战,在平时我们就需要多积累,比如面试的时候,面试官会出其不意的问一些问题,今天给大家分享一些Python面试内容,都是基础实例,经典实用,代码清晰可拿来即用,很适合学习提升使用,适用性广,实用性强。不仅可当作练习使用,也可以当作面试参考,建议人手一份。话不多说,一起来看看吧!

昨天分享了前10道,今天依旧更新10道

1.django的生命周期

Django的生命周期可以分为以下几个阶段

  • 请求阶段:当用户发送请求时,Django会根据URL路由规则找到对应的视图函数,并将请求传递给该函数处理。

  • 视图函数阶段:视图函数会处理请求,并返回一个HttpResponse对象,该对象包含了要返回给用户的内容。

  • 中间件阶段:在视图函数处理请求之前或之后,Django会执行中间件的相应方法,例如处理请求头、身份验证、缓存等。

  • 模板渲染阶段:如果视图函数返回的是一个模板,Django会将模板渲染成HTML页面,并将其包含在HttpResponse对象中返回给用户。

  • 响应阶段:最后,Django会将HttpResponse对象发送给用户的浏览器,完成请求响应过程。

在整个生命周期中,Django还会执行一些其他的操作,例如数据库查询、缓存读写、日志记录等。

2.进程和线程的区别

Python进程和线程的区别如下

  • 进程是操作系统资源分配的最小单位,而线程是程序执行的最小单位。

  • 进程之间相互独立,每个进程都有自己的地址空间、数据栈、文件描述符等,而线程共享进程的地址空间和资源。

  • 进程之间通信需要使用IPC(Inter-Process Communication)机制,如管道、消息队列、共享内存等,而线程之间可以通过共享内存、信号量、互斥量等方式进行通信。

  • 进程的创建和销毁需要较大的系统开销,而线程的创建和销毁则比较轻量级。

  • 进程之间的切换需要较大的系统开销,而线程之间的切换则比较轻量级。

  • 进程可以利用多核CPU实现并行处理,而线程则不能。

总之,进程和线程都是实现并发编程的方式,但是它们的应用场景和使用方式有所不同。在Python中,可以使用multiprocessing和threading模块来创建进程和线程。

3.分布式系统中的单例任务是怎么实现的

在Python分布式系统中,单例任务可以通过以下方式实现

  • 使用分布式锁:可以使用第三方库如redis等实现分布式锁,确保同一时间只有一个节点可以执行该任务。

  • 使用消息队列:将任务放入消息队列中,每个节点从队列中获取任务并执行,通过设置消息队列的消费者数量为1,确保同一时间只有一个节点可以执行该任务。

  • 使用数据库:将任务信息存储在数据库中,每个节点从数据库中获取任务并执行,通过设置任务状态为“执行中”,确保同一时间只有一个节点可以执行该任务。

需要注意的是,以上方法都需要考虑分布式系统中的网络延迟、节点故障等问题,确保任务的正确执行。

4.pg与mysql的区别有哪些

PG(PostgreSQL)和MySQL是两种不同的关系型数据库管理系统,它们有以下区别

  • 数据类型:PG支持更多的数据类型,如数组、JSON、XML等,而MySQL则不支持。

  • ACID支持:PG支持完全的ACID(原子性、一致性、隔离性、持久性)事务,而MySQL只支持部分ACID事务。

  • 复杂查询:PG支持更复杂的查询,如递归查询、窗口函数等,而MySQL则不支持。

  • 存储引擎:MySQL支持多种存储引擎,如InnoDB、MyISAM等,而PG只支持一种存储引擎。

  • 性能:在高并发、大数据量的情况下,PG的性能比MySQL更好。

  • 开源许可证:PG采用的是BSD许可证,而MySQL采用的是GPL许可证。

总的来说,PG更适合处理复杂的数据结构和高并发的场景,而MySQL则更适合处理简单的数据结构和小型应用。

5.python列表和字典底层原理实现

Python中的列表和字典都是基于哈希表实现的

列表底层实现

Python中的列表是一种动态数组,它的底层实现是一个数组,数组中的每个元素都是一个指针,指向存储在其他地方的真实数据。当列表需要扩容时,Python会重新分配一块更大的内存空间,并将原来的数据复制到新的内存空间中。这种实现方式使得列表的随机访问非常高效,但在插入和删除元素时需要移动大量的数据,效率较低。

字典底层实现

Python中的字典是一种哈希表,它的底层实现是一个数组,数组中的每个元素都是一个指针,指向一个链表或红黑树。哈希表的关键是哈希函数,它将键映射到数组的索引上。当发生哈希冲突时,Python会使用链表或红黑树来解决冲突。字典的插入、删除和查找操作都非常高效,时间复杂度为O(1)。

总结

列表和字典都是Python中常用的数据结构,它们的底层实现都是基于哈希表。列表适用于随机访问,字典适用于键值对的存储和查找。

7.给了一个长度为m的列表,返回前n小的元素,要求比较次数尽可能少

可以使用堆排序来解决这个问题,堆排序的时间复杂度为O(nlogn)。

具体实现步骤如下

  • 构建一个大小为n的最大堆,堆中元素为列表中前n个元素。

  • 遍历列表中剩余的元素,如果当前元素小于堆顶元素,则将堆顶元素替换为当前元素,并重新调整堆。

  • 遍历完成后,堆中的元素即为前n小的元素。

代码实现如下:

import heapq

def get_n_smallest(nums, n):
    heap = nums[:n]
    heapq._heapify_max(heap)
    for i in range(n, len(nums)):
        if nums[i] < heap[0]:
            heapq._heapreplace_max(heap, nums[i])
    return heap

# 示例
nums = [3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5]
n = 4
print(get_n_smallest(nums, n))  # 输出 [1, 1, 2, 3]

在上述代码中,使用了Python内置的heapq模块来实现堆排序。其中,_heapify_max()函数用于构建最大堆,_heapreplace_max()函数用于替换堆顶元素并重新调整堆。

8.pg的事务隔离级别

PostgreSQL的事务隔离级别包括以下四种

  • 读未提交(Read Uncommitted):一个事务可以读取另一个事务未提交的数据,可能会导致脏读、不可重复读和幻读问题。

  • 读已提交(Read Committed):一个事务只能读取另一个事务已经提交的数据,可以避免脏读问题,但是可能会出现不可重复读和幻读问题。

  • 可重复读(Repeatable Read):一个事务在执行期间多次读取同一数据,保证每次读取的数据都是一致的,可以避免脏读和不可重复读问题,但是可能会出现幻读问题。

  • 序列化(Serializable):最高的隔离级别,保证所有事务的执行顺序和结果与串行执行的结果相同,可以避免脏读、不可重复读和幻读问题,但是会影响并发性能。

在实际应用中,需要根据具体业务场景和性能需求选择合适的事务隔离级别。

9.进程和线程的区别,为什么线程的开销会比进程小

Python中的进程和线程都是用于实现多任务的方式,但它们之间有一些重要的区别。

进程是操作系统中资源分配的基本单位,每个进程都有自己独立的内存空间、代码和数据。进程之间的通信需要使用IPC(Inter-Process Communication)机制,如管道、消息队列、共享内存等。由于进程之间的资源是独立的,因此进程之间的通信开销较大。

线程是进程中的一个执行单元,每个线程都共享进程的内存空间和数据。线程之间的通信可以直接访问共享的内存,因此线程之间的通信开销较小。但是,由于线程共享进程的资源,因此需要进行同步和互斥操作,以避免多个线程同时访问共享资源导致的数据不一致问题。

线程的开销比进程小,主要是因为线程的创建和销毁比进程快,线程之间的切换也比进程快。此外,由于线程共享进程的资源,因此线程之间的通信开销也比进程小。

总之,进程和线程都有各自的优缺点,应根据具体的应用场景选择合适的方式。

10.Python为什么要设置GIL而不是允许开发者自己去设置线程锁

Python中的GIL(全局解释器锁)是一种机制,它确保同一时刻只有一个线程可以执行Python字节码。这意味着在多线程环境中,只有一个线程可以执行Python代码,而其他线程则被阻塞。这是因为Python的内存管理不是线程安全的,如果多个线程同时访问和修改Python对象,可能会导致内存错误和数据损坏。

进程和线程都是并发执行的方式,但是它们之间有一些重要的区别:

  • 进程是操作系统分配资源的基本单位,而线程是进程的执行单位。
  • 进程之间相互独立,而线程共享进程的资源。
  • 进程切换的开销比线程大,因为进程之间需要切换地址空间和上下文,而线程只需要切换上下文。

由于Python的内存管理机制,如果没有GIL,多个线程同时访问和修改Python对象可能会导致内存错误和数据损坏。因此,Python选择使用GIL来保护Python对象,确保同一时刻只有一个线程可以执行Python字节码。虽然GIL会导致多线程程序的性能下降,但是它可以保证程序的正确性和稳定性。

如果Python允许开发者自己去设置线程锁,那么开发者需要手动管理线程锁,这会增加代码的复杂度和开发难度。而且,由于Python的内存管理机制,即使开发者手动管理线程锁,也不能完全避免内存错误和数据损坏。因此,Python选择使用GIL来保护Python对象,这是一种更加简单和可靠的方式。

未完待续。。。。。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值