Python 基础面试第三弹

这篇具有很好参考价值的文章主要介绍了Python 基础面试第三弹。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1. 获取当前目录下所有文件名

import os

def get_all_files(directory):
    file_list = []
# os.walk返回一个生成器,每次迭代时返回当前目录路径、子目录列表和文件列表 for root, dirs, files in os.walk(directory): for file in files: file_list.append(os.path.join(root, file)) return file_list # 获取当前目录下的所有文件名 current_directory = os.getcwd() files = get_all_files(current_directory) # 打印所有文件名 for file in files: print(file)

 文章来源地址https://www.toymoban.com/news/detail-682935.html

2. Python中生成器和迭代器区别

迭代器(Iterator)是一种实现了迭代协议的对象,它必须提供一个__iter__()方法和一个__next__()方法。通过调用__iter__()方法,迭代器可以返回自身,并且通过调用__next__()方法,迭代器可以依次返回下一个元素,直到没有更多元素时抛出StopIteration异常。迭代器是一种惰性计算的方式,每次只在需要时生成一个元素,从而节省内存空间。可以使用iter()函数将可迭代对象转换为迭代器。

生成器(Generator)是一种特殊的迭代器,它使用了更为简洁的语法来定义迭代器。生成器可以通过函数中的yield关键字来实现,当函数执行到yield语句时,会暂停执行并返回一个值,保存当前状态,下次调用时从上次暂停的位置继续执行。生成器函数可以像普通函数一样接收参数,并且可以包含循环、条件语句等逻辑。生成器是一种非常方便和高效的迭代器实现方式。

下面是生成器和迭代器的区别总结:

  1. 语法:生成器使用yield关键字来定义,而迭代器需要实现__iter__()__next__()方法。
  2. 实现:生成器可以使用函数来定义,而迭代器可以由类来实现。
  3. 状态保存:生成器在yield语句处暂停执行并保存当前状态,下次调用时从上次暂停的位置继续执行;迭代器通过内部的状态和指针来保存迭代的位置。
  4. 简洁性:生成器的语法更加简洁,可以使用普通的函数定义和控制流语句;迭代器需要实现多个特殊方法,代码相对较多。
  5. 惰性计算:生成器是惰性计算的,每次只在需要时生成一个元素;迭代器也可以实现惰性计算,但需要手动控制。

总之,生成器是一种特殊的迭代器,它提供了更简洁和方便的语法。生成器可以通过函数中的yield语句来实现迭代过程,并且可以像普通函数一样编写逻辑。迭代器是一种更通用的概念,可以通过类来实现,需要显式地定义__iter__()__next__()方法。无论是生成器还是迭代器,它们都能够实现按需生成和处理大量数据的能力,提高了代码的效率和可读性。

 一个小栗子:

当我们需要遍历一个很大的数据集时,生成器可以帮助我们按需生成数据,而不是一次性加载整个数据集到内存中。

下面是一个简单的例子,我们使用生成器来按需生成斐波那契数列的前n个元素:

def fibonacci_generator(n):
    a, b = 0, 1
    count = 0
    while count < n:
        yield a
        a, b = b, a + b
        count += 1

# 使用生成器按需生成斐波那契数列的前10个元素
fibonacci = fibonacci_generator(10)

# 逐个打印生成的元素
for num in fibonacci:
    print(num)

  

  在上述代码中,我们定义了一个生成器函数fibonacci_generator,它使用了yield语句来生成斐波那契数列的元素。每次调用生成器的__next__()方法时,它会执行到yield语句处,

返回当前的斐波那契数并暂停执行,保存当前状态。然后,下次调用生成器的__next__()方法时,它会从上次暂停的位置继续执行,生成下一个斐波那契数。这样,我们可以通过迭代生成器

来按需获取斐波那契数列的元素。当我们遍历生成器对象时,它会依次生成斐波那契数列的元素并打印出来。由于生成器是按需生成数据的,它只在需要时生成一个元素,而不是一次性生成整

个数列。这样可以节省内存空间,特别是当斐波那契数列很大时。总结起来,生成器可以看作是一种特殊的函数,它能够按需生成数据,节省内存空间,并且提供了一种简洁和方便的方式来

实现迭代器。通过使用生成器,我们可以避免一次性加载大量数据到内存中,而是在需要时逐个生成数据,从而提高代码的效率和可扩展性。

3. 什么是可迭代对象,其原理又是什么

  可迭代对象(Iterable)是指可以被迭代遍历的对象。在许多编程语言中,迭代是指按照一定的顺序逐个访问集合中的元素的过程。在Python中,可迭代对象是指实现了迭代器协议(Iterator Protocol)的对象。

迭代器协议包含两个方法:

  1. __iter__()方法:该方法返回一个迭代器对象。迭代器对象用于实现具体的迭代逻辑,并且必须包含__next__()方法。

  2. __next__()方法:该方法返回迭代器中的下一个元素。如果没有元素可供返回,它应该引发StopIteration异常。

当我们使用可迭代对象进行迭代时,实际上是通过迭代器对象来完成的。迭代器对象负责追踪当前的迭代状态,并提供下一个元素。迭代器对象会在每次迭代时调用__next__()方法,并返回下一个元素,直到遍历完所有元素或者引发StopIteration异常为止。

Python中许多内置的数据类型和容器都是可迭代对象,例如列表(List)、元组(Tuple)、字典(Dictionary)、集合(Set)等。此外,我们也可以通过自定义类来实现可迭代对象,只需在类中定义__iter__()方法,并在该方法中返回一个迭代器对象即可。

以下是一个示例,展示了如何使用可迭代对象和迭代器对象进行迭代:

# 创建一个可迭代对象
my_list = [1, 2, 3, 4, 5]

# 获取迭代器对象
my_iter = iter(my_list)

# 使用迭代器对象进行迭代
try:
    while True:
        item = next(my_iter)
        print(item)
except StopIteration:
    pass

  在上述示例中,我们通过调用iter()函数获取了my_list的迭代器对象my_iter,然后使用next()函数从迭代器对象中获取下一个元素并打印,直到遍历完所有元素或引发

StopIteration异常为止。可迭代对象的原理是基于迭代器协议的实现,通过迭代器对象的__next__()方法来提供序列中的下一个元素。这种机制使得我们可以方便地对集合中的元素

进行逐个访问和处理,提供了一种统一的迭代接口

自己实现可迭代对象小栗子

 
class MyIterable:
    def __init__(self, data):
        self.data = data

    def __iter__(self):
        self.index = 0
        return self

    def __next__(self):
        if self.index < len(self.data):
            item = self.data[self.index]
            self.index += 1
            return item
        else:
            raise StopIteration

# 创建一个可迭代对象实例
my_iterable = MyIterable([1, 2, 3, 4, 5])

# 使用迭代器进行迭代
for item in my_iterable:
    print(item)

4. Python2 和 Python3主要的区别有哪些:

Python 2.x 和 Python 3.x 之间的一些主要区别:

  1. 打印函数:在 Python 2.x 中,打印语句是一个关键字,使用类似于 print "Hello" 的语法。而在 Python 3.x 中,print 被改造为一个内置函数,需要使用括号,例如 print("Hello")

  2. 整数除法:在 Python 2.x 中,整数除法的结果会被截断为整数,例如 5 / 2 的结果是 2。而在 Python 3.x 中,整数除法的结果将保留小数部分,得到浮点数结果,例如 5 / 2 的结果是 2.5。如果想要执行截断整数除法,可以使用 // 运算符。

  3. Unicode 字符串:在 Python 2.x 中,字符串类型分为普通字符串和 Unicode 字符串(以 u 前缀表示),这导致字符串处理的一些混乱和困惑。而在 Python 3.x 中,所有字符串都是 Unicode 字符串,普通字符串是以字节表示的,需要使用 b 前缀表示。

  4. xrange 替代 range:在 Python 2.x 中,range 函数返回的是一个列表,如果需要生成大范围的整数序列,会占用大量内存。而在 Python 3.x 中,range 函数的实现类似于 Python 2.x 中的 xrange,返回一个迭代器对象,节省了内存。

  5. 异常语法:在 Python 2.x 中,捕获异常时使用的语法是 except Exception, e,将异常对象存储在变量 e 中。而在 Python 3.x 中,使用 except Exception as e 的语法,将异常对象存储在变量 e 中。

  6. input 函数:在 Python 2.x 中,input 函数会将用户输入的内容作为 Python 代码进行解析,存在安全风险。而在 Python 3.x 中,input 函数始终将用户输入的内容作为字符串返回,不进行解析。

除了上述主要区别之外,Python 3.x 还进行了一些其他改进,包括改进的类定义语法、更好的模块管理和导入机制、更一致的异常处理和错误机制等。然而,这也导致了 Python 2.x 代码无法直接在 Python 3.x 中运行,需要进行一些修改和调整。

 

5. 说说Python中多线程和多进程

  1. 多线程(Multithreading):

    • 多线程是指在一个进程内创建多个线程,每个线程独立执行不同的任务。多线程共享进程的内存空间,因此线程之间可以方便地共享数据。
    • 在 Python 中,可以使用 threading 模块来创建和管理线程。通过创建 Thread 类的实例,指定要执行的函数或方法,并调用 start() 方法,可以启动一个线程。
    • Python 的多线程由于全局解释器锁(Global Interpreter Lock,GIL)的存在,同一时刻只允许一个线程执行 Python 字节码。这意味着多线程并不能充分利用多核处理器,并发性能受限。多线程适用于 I/O 密集型任务,如网络请求、文件读写等,但对于 CPU 密集型任务,多线程并不能提升性能。
  2. 多进程(Multiprocessing):

    • 多进程是指创建多个独立的进程,每个进程都有自己的内存空间和系统资源。多个进程之间相互独立,可以并行执行不同的任务。每个进程都有自己的 Python 解释器,因此可以充分利用多核处理器,提高并发性能。
    • 在 Python 中,可以使用 multiprocessing 模块来创建和管理进程。通过创建 Process 类的实例,指定要执行的函数或方法,并调用 start() 方法,可以启动一个进程。
    • 多进程可以通过进程间通信(Inter-Process Communication,IPC)来实现进程之间的数据共享。Python 提供了多种 IPC 机制,如队列(Queue)、管道(Pipe)和共享内存等。

总结:

  • 多线程适合处理 I/O 密集型任务,可以提高程序的响应能力和效率。
  • 多进程适合处理 CPU 密集型任务,可以充分利用多核处理器提高并发性能。
  • 在 Python 中,多线程受到 GIL 的限制,多进程可以绕过 GIL,实现真正的并行执行。
  • 使用多线程或多进程时需要注意线程安全和进程安全的问题,避免数据竞争和共享资源的冲突。

6. Python中GIL锁:

  全局解释器锁(Global Interpreter Lock,简称 GIL)是在 CPython 解释器中存在的一个特性。它是一种机制,用于保证同一时刻只有一个线程执行 Python 字节码。虽然 GIL 的存在确保了 CPython 解释器的线程安全性,但也对多线程并发执行带来了一些限制。

以下是对 GIL 的一些详细解释和理解:

  1. GIL 的作用:

    • GIL 的主要作用是保护 CPython 解释器内部的数据结构免受并发访问的影响,确保线程安全。
    • CPython 使用引用计数(Reference Counting)作为内存管理的主要机制。GIL 保证了在修改引用计数时的原子性,避免了竞态条件(Race Condition)和内存泄漏问题。
    • GIL 还可以简化 CPython 解释器的实现,使其更加简单高效。
  2. GIL 的影响:

    • 由于 GIL 的存在,同一时刻只有一个线程可以执行 Python 字节码,其他线程被阻塞。这意味着多线程并不能充分利用多核处理器,无法实现真正的并行执行。
    • 对于 CPU 密集型任务,由于 GIL 的限制,多线程并不能提升性能。实际上,由于线程切换的开销,可能导致多线程执行速度比单线程还要慢。
    • GIL 对于 I/O 密集型任务的影响相对较小,因为线程在进行 I/O 操作时会主动释放 GIL,允许其他线程执行。因此,多线程在处理 I/O 操作时仍然可以提供一定的性能优势。
  3. 解决 GIL 的方法:

    • 采用多进程:由于每个进程都有独立的 Python 解释器和 GIL,多进程可以充分利用多核处理器,实现并行执行。
    • 使用扩展模块:某些扩展模块,如 NumPy、Pandas 等,使用 C/C++ 编写,可以释放 GIL,允许多线程并行执行。
    • 使用多线程库:一些第三方库,如 multiprocessing 模块、concurrent.futures 模块等,提供了替代方案,使得在某些情况下可以绕过 GIL 的限制。

需要注意的是,GIL 只存在于 CPython 解释器中,而其他实现(如 Jython、IronPython)可能没有 GIL。此外,对于许多类型的应用程序,如 I/O 密集型、并发处理不频繁的应用程序,GIL

的影响较小,可以继续使用多线程来实现并发。然而,对于 CPU 密集型任务和需要充分利用多核处理器的应用程序,考虑使用多进程或其他解决方案来规避 GIL。

 

到了这里,关于Python 基础面试第三弹的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 前端面试题(第三弹)——js对象的基本方法和深浅拷贝

    第一种 第二种 1.configurable:属性是否可以通过delete删除,默认值为true。 2.enumberable:属性是否可以通过for in 进行循环返回,默认值为true。 3.writable:属性是否可被修改,默认值为true。 4.value:属性实际的值,默认为undefined。 访问器属性有四个属性类型,也是使用Object.defin

    2024年02月13日
    浏览(47)
  • 找工作第三弹——JS面试题由浅入深

    明天面试,大晚上整理js。希望能拿下!!! CSS面试可移步:找工作第二弹——挑战CSS重难点一篇就够 本质区别:进程是操作系统资源分配的基本单位,而线程是处理器任务调度和执行的基本单位。 包含关系:一个进程至少有一个线程,线程是进程的一部分,所以线程也被

    2024年02月13日
    浏览(38)
  • 【网络编程】Linux网络编程基础与实战第三弹——网络名词术语

    数据包从源地址到目的地址所经过的路径,由一系列路由节点组成。 某个路由节点为数据包选择投递方向的选路过程。 路由器工作原理 路由器是连接因特网中各局域网、广域网的设备,它会根据信道的情况自动选择和设定路由,以最佳路径,按前后顺序发送信号的设备。

    2024年02月08日
    浏览(46)
  • C++ 获取dll当前路径下所有文件

    在.cpp文件头引用头文件和作用域 获取dll文件所在目录地址和获取文件信息 功能代码:获取指定路径下所有文件地址信息 **************************************************************************************************************

    2024年02月10日
    浏览(45)
  • el-select获取当前选中的对象所有(item)数据

    在应用 elementUI 的 el-select 下拉框的时候,界面展示只需要文案就足够了, 但我们传参给后端可能需要多个字段 ,如有以下后端接口返回数据: 即需要获取当前选择的name对应的对象的所有数据 使用element官方的属性: value-key 作为 value 唯一标识的键名,绑定值为对象类型时必填

    2024年02月13日
    浏览(51)
  • 微信小程序获取当前位置与跳转第三方地图

    1. 先在app.json添加配置 2. 获取定位权限,打开地址选点 3. 如果要打开跳转第三方地图的内置地图

    2024年02月15日
    浏览(69)
  • python3GUI--仿做一个网易云音乐(第三弹v2.0)By:PyQt5(附下载地址)

    传送门: python3GUI–仿做一个网易云音乐By:PyQt5(附下载地址) python3GUI–仿做一个网易云音乐(第二弹v1.5)By:PyQt5(附下载地址) 本篇为模仿网易云音乐2.0篇,是本系列最后一篇,本篇继续在v1.5基础上进行改进,尽最大努力模仿网易云音乐播放器UI,本篇将全方面介绍咱们的“

    2024年02月15日
    浏览(80)
  • el-tree获取当前选中节点及其所有父节点的id(包含半选中父节点的id)

    如下图,我们现在全勾中的有表格管理及其下的子级,而半勾中的有工作台和任务管理及其子级 现在点击保存按钮后,需要将勾中的节点id及该节点对应的父节点,祖先节点的id(包含半选中父节点的id)也都一并传给后端,那这个例子里就应该共传入9个id,我们可以直接将

    2024年01月22日
    浏览(53)
  • PMP练习题 第三弹

    前言:文中类似“有误a”的字样,是作者做题时自己选错的错误答案 每周一次的项目会议上,一位团队成员表示在修订一项可交付成果时,一名销售经理对客户服务过程想出一项变更讨论,影响到整个项目,项目经理对销售参与到项目可交付成果感到吃惊,经理事先应该怎

    2024年02月08日
    浏览(41)
  • 数据结构第三弹----顺序表

    线性表(linear list)是n个具有相同特性的数据元素的有限序列。 线性表是一种在实际中广泛使 用的数据结构,常见的线性表:顺序表、链表、栈、队列、字符串… 线性表在逻辑上是线性结构,也就说是连续的一条直线。但是在物理结构上并不一定是连续的, 线性表在物理上

    2024年02月03日
    浏览(43)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包