泛型什么意思?

泛型是参数化类型。泛型(Generics)是指在定义函数、接口或类的时候,不预先指定具体的类型,而在使用的时候再指定类型的一种特性。

Features

谈谈对Python和其他语言的区别 Java: Java是静态强类型语言,Python是动态强类型语言。
C++: C++是静态弱类型语言,Python是动态强类型语言。
Javascript: Javascript是动态弱类型语言,Python是真正的面向对象,而Javascript不是。
What are the major differences between Python and Java? 类型系统:Python是动态类型的,允许变量类型的灵活性,而Java是静态类型的,需要显式类型声明。
性能:Java通常由于编译为字节码和静态类型而提供更好的性能,而Python的解释性质可能会导致执行速度变慢。
简述解释型和编译型编程语言 在编译语言中,目标机器直接编译程序,生成可执行的机器代码。在解释型语言中,源代码不直接由目标机器翻译。相反,另一个程序(也称为解释器)读取并执行代码,解释器逐行运行程序并执行每个命令。因此,编译语言的执行速度往往比解释语言更快、更高效。
Python是解释型的还是编译型的? Python 是一种解释语言,而不是编译语言。这意味着源文件可以直接运行,运行的可执行文件。解释型语言通常比编译型语言具有更短的开发/调试周期,但它们的程序通常运行速度更慢。
Python的解释器种类以及相关特点?什么时候,为什么会使用他们? CPython: 与现有C/C++代码无缝集成的项目来说,CPython是一个可靠的选择,特别是当 Jython 和 PyPy 的特定功能和优化对于项目目标并不重要时。
PyPy: 一般来说,当性能、内存效率以及与现有 Python 代码库的兼容性是项目的重要考虑因素时,PyPy可能是一个令人信服的选择。
Jython: 当您的项目涉及与 Java 密切交互、利用 Java 库和工具或将 Python 集成到以 Java 为中心的环境时,Jython 是一个令人信服的选择。
Python语言的有哪些缺陷? 性能: 特别是在CPU密集型任务中。
全局解释器锁(GIL):CPython 中的 GIL 通过一次只允许一个线程执行 Python 字节码来限制多线程性能,影响了某些类型应用程序的多核系统的可扩展性。
动态类型:可能会给大型代码库和静态分析工具带来挑战。

说一说你见过比较cool的python实现

github上都fork过哪些python库,列举一下你经常使用的,每个库用一句话描述下其功能

What is the Global Interpreter Lock (GIL) in Python? 在CPython中,全局解释器锁(GIL)是一个互斥体,用于保护对Python对象的访问,防止多个线程同时执行Python字节码。GIL可防止竞争条件并确保线程安全。由于GIL,一次只能有一个线程处理Python。总之,这个互斥体是必要的主要是因为CPython的内存管理不是线程安全的。
Why is a Python I/O bound task not blocked by the GIL? 所有Python的阻塞I/O语句都会在等待I/O块解析时释放GIL。当一个线程等待IO完成时,它会释放GIL,而另一个线程可以继续执行。所以对于io密集型任务,python的多线程起到作用,但对于cpu密集型任务,python的多线程几乎占不到任何优势,还有可能因为争夺资源而变慢。
How To Overcome the Global Interpreter Lock (GIL) Limitations in Python? 规避GIL限制的一种流行方法是通过多进程和协程。(协程也只是单CPU,但是能减小切换代价提升性能).多进程之间内存不能共享,因此CPU的每个核运行的代码不会互相相关。
有哪些方法提高python的运行效率? * 为您的特定用例选择最合适的数据结构: 使用Set测试存在,使用字典进行查找,使用列表顺序遍历。
* 优化循环:尽量减少嵌套循环的使用,并考虑使用列表推导式、映射、过滤器和其他函数式编程技术来提高循环效率。
* 利用内置函数和库: 利用内置函数和库有效地执行常见任务,因为它们通常针对性能进行了优化。
* 分析和优化工具: 使用 cProfile 和 line_profiler 等分析工具来识别代码中的瓶颈,然后对这些区域应用有针对性的优化。
* Cython 或 Numba: 虑使用 Cython 或 Numba 将部分代码编译为 C 或机器代码,特别是对于计算密集型部分。
* 并行性和并发性:利用 multiprocessing 或 concurrent.futures 等库进行并行处理,或者考虑使用 asyncio 异步编程来执行 I/O 密集型任务。
内存管理:注意内存使用并避免不必要的对象创建,尤其是在循环中。 处理大型数据集时,尽可能重用对象,并考虑使用生成器而不是列表。
JIT 编译:探索 PyPy 等替代实现,它使用即时 (JIT) 编译器在某些情况下比标准 CPython 提供显着的性能改进。
算法效率:确保算法有效实施,避免不必要的重复工作或低效的搜索和排序操作。
print(0+”0”)会不会报错,为什么
反射是什么?

反射是指程序在运行时检查和修改自身结构、行为和属性的能力。

type()、dir() 和 getattr() 等函数可用于内省对象、检索其类型信息、列出其属性以及在运行时动态访问其属性。

元类:元类提供了一种自定义类创建行为并启用高级反射功能的方法,允许在类实例化期间修改类结构和行为。

动态属性访问:Python 支持动态属性访问和修改,使程序能够在运行时使用 getattr()、setattr() 和 hasattr() 等技术查询和操作对象属性。

通过利用反射,Python开发人员可以编写更灵活、通用和适应性更强的代码,同时获得在运行时动态自省和修改编程实体的能力

Syntax and Semantics

Lexical analysis

单引号、双引号、三引号的区别和用法

单引号和双引号是等效的。三引号的用途是表示多行字符串或者多行注释。

Python中单下划线和双下划线

__foo__:一种约定,Python内部的名字,用来区别其他用户自定义的命名,以防冲突,就是例如__init__(),__del__(),__call__()这些特殊方法

_foo:一种约定,用来指定变量私有.程序员用来指定私有变量的一种方式.不能用from module import * 导入,其他方面和公有一样访问;类对象和子类对象能访问到这些变量。

__foo:这个有真正的意义:解析器用_classname__foo来代替这个名字,以区别和其他类相同的命名,它无法直接像公有成员一样随便访问,通过对象名._类名__xxx这样的方式可以访问. 双下划线开头,表示为私有成员,只允许类本身访问,子类也不行。

如何加注释?

#开头的时单行注释,三引号多行注释。

Data model

Special method names

列出几种魔法方法(magic method / special method)并简要介绍用途

__new__: 创建类 cls 的新实例

__init__: 在创建实例之后但在将其返回给调用者之前调用,并初始化。

__getattr__: 当默认属性访问失败并出现AttributeError时被调用。

__getattribute__: 定义当该类的属性被访问时的行为(先调用该方法,查看是否存在该属性,若不存在,接着去调用getattr)。

__setattr__: 定义当一个属性被设置时的行为。

__len__: 调用以实现内置函数 len()。

__getitem__: 调用以实施self[key]

__setitem__: 调用以实现对self[key]的赋值

__iter__: 当容器需要迭代器时调用此方法。自定义类型给for循环。

魔法函数 __call__怎么使用?

使得对象可以像函数一样被调用。

Metaclasses

什么是元类(Metaclasses)?

在Python中,类也是对象。该对象(类)本身能够创建对象(称为实例)。因此,像所有对象一样,可以将类赋值给变量,可以给类的属性赋值,可以将类作为参数传递。

由于类是对象,因此您可以像任何对象一样动态创建它们。当您使用class关键字时,Python会自动创建此对象。但与Python中的大多数事情一样,它为您提供了一种手动完成此操作的方法。

默认情况下,类是使用type()构造的。类主体在新的命名空间中执行,类名在本地绑定到type(name, bases, namespace)的结果。type是Python使用的内置元类,但是当然,您可以创建自己的元类。


>>> class Foo(object):
...     bar = True
# Can be translated to:
>>> Foo = type('Foo', (), {'bar':True})
    

>>> def echo_bar(self):
...     print(self.bar)
>>> FooChild = type('FooChild', (Foo,), {'echo_bar': echo_bar})
# Can be translated to:
>>> class FooChild(Foo):
...     def echo_bar(self):
...         print(self.bar)
    

They are the classes' classes, you can picture them this way:


MyClass = MetaClass()
my_object = MyClass()
    

可以通过在类定义行中传递 metaclass 关键字参数或从包含此类参数的现有类继承来自定义类创建过程。


class Meta(type):
    pass
class MyClass(metaclass=Meta):
    pass
class MySubclass(MyClass):
    pass
    

Python 3 中元类添加的一件事是,您还可以将属性作为关键字参数传递到元类中,如下:


class Foo(object, metaclass=something, kwarg1=value1, kwarg2=value2):
    ...
    

Custom metaclasses


# remember that `type` is actually a class like `str` and `int`
# so you can inherit from it
class UpperAttrMetaclass(type):
    # __new__ is the method called before __init__
    # it's the method that creates the object and returns it
    # while __init__ just initializes the object passed as parameter
    # you rarely use __new__, except when you want to control how the object
    # is created.
    # here the created object is the class, and we want to customize it
    # so we override __new__
    # you can do some stuff in __init__ too if you wish
    # some advanced use involves overriding __call__ as well, but we won't
    # see this
    def __new__(
        upperattr_metaclass,
        future_class_name,
        future_class_parents,
        future_class_attrs
    ):
        uppercase_attrs = {
            attr if attr.startswith("__") else attr.upper(): v
            for attr, v in future_class_attrs.items()
        }
        return type(future_class_name, future_class_parents, uppercase_attrs)
    

class UpperAttrMetaclass(type):
    def __new__(cls, clsname, bases, attrs):
        uppercase_attrs = {
            attr if attr.startswith("__") else attr.upper(): v
            for attr, v in attrs.items()
        }
        return type(clsname, bases, uppercase_attrs)
    

class UpperAttrMetaclass(type):
    def __new__(cls, clsname, bases, attrs):
        uppercase_attrs = {
            attr if attr.startswith("__") else attr.upper(): v
            for attr, v in attrs.items()
        }
        return type.__new__(cls, clsname, bases, uppercase_attrs)
    

class UpperAttrMetaclass(type):
    def __new__(cls, clsname, bases, attrs):
        uppercase_attrs = {
            attr if attr.startswith("__") else attr.upper(): v
            for attr, v in attrs.items()
        }
        return super().__new__(cls, clsname, bases, uppercase_attrs)
    

在 Python 3 中,如果您使用关键字参数进行此调用,如下所示:


class Foo(object, metaclass=MyMetaclass, kwarg1=value1):
    ...
    

它在元类中转换为以下内容以使用它:


class MyMetaclass(type):
    def __new__(cls, clsname, bases, dct, kwargs1=default):
        ...
    
http://stackoverflow.com/questions/100003/what-is-a-metaclass-in-python

Execution model

Python中的作用域和搜索顺序是怎样的?

作用域定义了块内名称的可见性。如果局部变量是在块中定义的,则其范围包括该块。

首先搜索的最里面的作用域。然后从最近的封闭范围开始搜索的任何封闭函数的范围包含非本地名称,但也包含非全局名称。之后搜索当前模块的全局名称。最后搜索包含内置名称的命名空间。

如果 global 语句出现在块内,则该语句中指定的名称的所有使用都将引用这些名称在顶级命名空间中的绑定。首先搜索全局命名空间。如果在那里找不到名称,则会搜索内置名称空间。

nonlocal语句导致相应的名称引用最近的封闭函数作用域中先前绑定的变量。如果给定名称不存在于任何封闭函数作用域中,则在编译时引发SyntaxError。

Python中的作用域

Python中,一个变量的作用域总是由在代码中被赋值的地方所决定的。

当Python遇到一个变量的话他会按照这样的顺序进行搜索:本地作用域(Local)→当前作用域被嵌入的本地作用域(Enclosing locals)→全局/模块作用域(Global)→内置作用域(Built-in)

Modules

是否遇到过python的模块间循环引用的问题,如何避免它?

首先出现这种问题是因为没有规划好层级,哪些模块和哪些模块逻辑上应该在一起,哪些模块是公共的依赖项,哪些是实际的业务代码。

全局变量初值都赋值为不依赖其他模块的值,比如None,整数等,如果需要依赖,模块提供init函数,由main模块在程序启动时候手工按顺序初始化好

Expressions

Simple statements

Assignment statements

怎样声明多个变量并赋值?

a, b = 0, 1

a=1, b=2, 不用中间变量交换a和b的值
Python的引用赋值、深拷贝和浅拷贝怎么理解

Remember that arguments are passed by assignment in Python. Since assignment just creates references to objects, there’s no alias between an argument name in the caller and callee, and so no call-by-reference per se.

请记住,Python 中的参数是通过赋值传递的。由于赋值只是创建对对象的引用,因此调用者和被调用者中的参数名称之间没有别名,因此本身没有按引用调用。

Python 的参数传递模型既不是“按值传递”也不是“按引用传递”,而是“按对象引用传递”。

根据您在函数中传递的对象类型,函数的行为会有所不同。不可变对象显示“按值传递”,而可变对象显示“按引用传递”。

#### The assert statement
什么是断言?应用场景?

assert(断言)用于判断一个表达式,在表达式条件为false的时候触发异常。

解释一下python中pass语句的作用?

pass 是一个空操作,它作为占位符很有用

Compound statements

The while statement

如何用Python输出一个Fibonacci数列?

    def fib(n):    # write Fibonacci series up to n
        a, b = 0, 1
        while a < n:
            print(a, end=' ')
            a, b = b, a+b
        print()
    

The with statement

有用过with statement吗?它的好处是什么?

它确保在处理资源后立即关闭资源。

Function

Arguments

*args和**kwargs是什么参数?

位置参数:位置参数可以出现在参数列表的开头和/或作为前面带有 * 的可迭代元素进行传递。当你不确定你的函数里将要传递多少参数时你可以用`*args`.例如,它可以传递任意数量的参数。

关键字参数:函数调用中以标识符(例如 name= )开头的参数,或作为字典中以 ** 开头的值传递的参数。**kwargs允许你使用没有事先定义的参数名。

当调用函数时如何使用`*`和`**`语法传递参数?

>>> mylist = ['aardvark', 'baboon', 'cat']
>>> print_three_things(*mylist)
    
什么是面向切面编程AOP?

面向方面的编程(AOP)是一种编程范式,旨在通过允许分离横切关注点来提高模块化性。它通过向现有代码添加行为(建议)而不修改代码本身来实现这一点,而是通过“切入点”规范单独指定修改哪些代码,这允许将不属于业务逻辑核心的行为(例如日志记录)添加到程序中,而不会扰乱功能的代码核心。

面向切面的目的在于解耦和复用。

python中的装饰器就是设计来实现切面注入功能的。

什么是装饰器?

装饰器是一个很著名的设计模式,经常被用于有切面需求的场景,较为经典的有插入日志、性能测试、事务处理等。装饰器是解决这类问题的绝佳设计,有了装饰器,我们就可以抽离出大量函数中与函数功能本身无关的雷同代码并继续重用。概括的讲,装饰器的作用就是为已经存在的对象添加额外的功能。

装饰器是返回另一个函数的函数,通常用作使用 @wrapper 语法的函数转换。装饰器语法只是语法糖。

装饰器是一个工厂函数,接受一个函数作为参数,然后返回一个新函数,其闭包中包含被装饰的函数。有了装饰器,可以提取大量函数中与本身功能无关的类似代码,达到代码重用的目的。可应用于插入日志、性能测试、事务处理等方面。


def deco(func):
    def warpper(*args, **kwargs):
        print('start')
        func(*args, **kwargs)
        print('end')
    return warpper
@deco
def myfunc(parameter):
    print("run with %s" % parameter)
myfunc("something")
    

Errors and Exceptions

python如何捕获异常?

Python中的try和except块用于捕获和处理异常。

介绍一下python的异常处理机制和自己开发过程中的体会
  • 仅在需要时使用try-except 块。
  • 保持try块小且集中,以正确处理异常。
  • 捕获特定异常而不是通用异常类来区分错误。
  • 失败时从except块中打印自定义错误消息
  • 使用finally子句可靠地执行清理代码的各个部分
  • 定义自定义异常类来匹配应用场景

Standard Library

列举5个Python中的标准模块

datetime,os,sys,copy,random,itertools,subprocess

Built-in Functions

什么是Python自省?可以用什么方法?

自省是在运行时确定对象类型的能力。可以使用isinstance方法。比如type(),dir(),getattr(),hasattr(),isinstance().

请写出python的常用内置函数(至少3个),并描述它们具体含义
  • all()
  • any()
  • enumerate()
  • eval()
  • exec()
  • hasattr()
  • isinstance()
  • next()
  • range()
  • reversed()
  • sorted()
range(100)是什么意思?

返回0到99的可迭代对象

写一个函数, 输入一个字符串, 返回倒序排列的结果: 如: string_reverse(‘abcdef’), 返回: ‘fedcba’
s[::-1]
filter方法求出列表所有奇数并构造新列表,a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

list(filter(lambda x: x % 2 == 1, a))
    
举例说明zip()函数用法

并行迭代多个可迭代对象,返回元组的迭代器。默认情况下, zip() 在最短迭代耗尽时停止。它将忽略较长迭代中的剩余项目,将结果截断为最短迭代的长度。

求三个方法打印结果: comma-separated, percentage, format method
>>> print(*range(5), sep=", ")
>>> f"{1/3:.0%}"
>>> "{:.0%}".format(1/3)
简述any()和all()方法
r、r+、rb、rb+文件打开模式区别?

模式可以是'r'、'w'、'x'或'a' 用于读取(默认)、写入、独占创建或附加。在模式中添加'+'以允许同时读写。模式中使用'b'创建二进制流用于读取或写入。

说出几个比较难的内置函数?
  • map
  • filter
  • reduce
  • all
  • any
map、reduce原理, 多个reduce的输出,但是要统计的是uv,怎么做?

Python中的map-reduce原理是指常用于处理和生成大型数据集的编程框架。 map 函数将指定的函数应用于可迭代对象(如列表)中的每个项目,然后使用 reduce 函数将结果缩减为单个值。 这种方法通过将计算分解为可以分布在多个处理器或机器上的较小任务,实现大数据的并行处理和高效处理。 在Python中,map()和reduce()函数在内置的functools模块中可用。

UV是Unique visitor,至少访问过该网站一次的人,去重统计和。

open和with open的区别,平常用哪个比较多?

with open可以自动关闭文件描述符。

在Python中,read,readline和readlines的区别是什么?
  • read() 返回整个文件的内容或指定数量的字符。
  • readline() 一次读取一行。
  • readlines() 读取所有行并将它们作为列表返回。
@staticmethod和@classmethod的区别是什么?

Python其实有3个方法,即静态方法(staticmethod),类方法(classmethod)和实例方法,如下:


def foo(x):
    print "executing foo(%s)"%(x)
class A(object):
    def foo(self,x):
        print "executing foo(%s,%s)"%(self,x)
    @classmethod
    def class_foo(cls,x):
        print "executing class_foo(%s,%s)"%(cls,x)
    @staticmethod
    def static_foo(x):
        print "executing static_foo(%s)"%x
a=A()
    

self和cls是命名约定。

实例方法的参数self是对实例绑定。因为实例方法的调用离不开实例,我们需要把实例自己传给函数,调用的时候是这样的a.foo(x)(其实是foo(a, x))。

类方法的参数cls是对类的绑定。类方法可以使用A.class_foo(x)或者a.class_foo(x)进行调用。

静态方法没有与类或实例进行绑定,唯一的区别是调用的时候需要使用a.static_foo(x)或者A.static_foo(x)来调用.

dir()是干什么用的?

查看对象存在属性和方法

isinstance 作用以及应用场景?

测试对象是否时某个类的实例

了解enumerate么?

返回一个枚举对象。参数时可迭代对象对象。返回一个元组,其中包含一个计数(从 start 开始,默认为 0)以及通过迭代 iterable 获得的值。

简述你对input()函数的理解

输入中读取一行,将其转换为字符串(去除尾随换行符),然后返回该字符串。

hasattr() getattr() setattr()的用法

hasattr测试对象是否存在某个属性。getattr返回对象的某个属性。setattr设置对象的某个属性的值

Built-in Types

Python是如何进行类型转换的?

在Python中,类型转换是使用内置函数执行的,这些函数允许您将变量从一种数据类型转换为另一种数据类型。

列举Python中的基本数据类型?
  • boolean types: bool
  • numeric types: int, float, complex
  • sequence types: list, tuple, range
  • text sequence type: str
  • binary sequence types: bytes, bytearray
  • set types: set
  • mapping type: dict
如何区别可变数据类型和不可变数据类型?

list、set和dict是Python中一些可变数据类型的示例。

不可变数据类型的示例有 int、str、bool、float、tuple 等。

在Python中, list, tuple, dict, set有什么区别, 主要应用在什么样的场景?

使用Set测试存在,使用字典进行查找,使用列表顺序遍历。元组作为存储不可变的数据。

Do you know what is the difference between lists and tuples? Can you give me an example for their usage?

列表用于遍历,元组用于保存不可变数据。

字典、元组、列表的in方法哪个更快?

Dict: 字典的 in 方法检查成员资格的平均情况时间复杂度为 O(1)。 这是因为字典使用基于哈希表的实现来进行键查找,无论字典的大小如何,都可以提供恒定时间的平均情况性能。 因此,字典的操作往往非常快,即使对于大型集合也是如此。

Tuple: 对于元组, in方法通过迭代元组中的每个元素来检查成员资格,直到找到匹配项或到达元组末尾。 因此,元组的in方法的时间复杂度在最坏的情况下为 O(n),其中 n 是元组中元素的数量。这意味着随着元组大小的增加,执行成员资格检查所需的时间线性增长。

List: 与元组类似,列表的 in 方法在最坏情况下的时间复杂度也为 O(n)。 它迭代列表中的每个元素以检查成员资格,从而导致所需时间随着列表大小的增加而线性增长。

当需要频繁执行成员资格检查时,特别是对于大型集合,使用字典可以提供显着的性能优势。

Python 常用的数据结构的类型及其特性?

list作为顺序遍历和索引的数据结构。set作为无重复的数据结构。dict作为键值对的数据结构。tuple作为不可变的数据结构。

Logical operations

Python中的逻辑运算符

and, or, not

Bitwise Operations

讲讲Python中的位运算符
  • 按位或 x | y
  • 按位异或 x ^ y
  • 按位与 x & y
  • 左移 x << n
  • 右移 x >> n
  • 位反转 ~x

Boolean Operations

解释一下python的and-or-not语法?

and、or、not是逻辑运算符。最高优先级属于not ,其次是and,最后是or,not 的优先级低于非布尔运算符,另外分组优先。其中and和or都是短路操作。x and y当第一个参数为true时才计算第二个参数。x or y如果第一个参数为 false,它只会计算第二个参数。

Numeric Types

在Python中如何使用多进制数字?

int(string, base), hex(), oct(), bin()进行转化

如何保留两位小数?

使用字符串格式化print("%.2f" % 12.345)

使用round内置函数round(12.345, 2)

八进制如何转为二进制?

八进制先转为十进制,int(octal_number, 8)

然后十进制转为二进制,bin(decimal_number)

Strings

如何用Python来进行查询和替换一个文本字符串?

要在Python中查询和替换文本字符串,可以使用正则表达式的re模块。


import re
text = "This is a sample text with some example words."
# Query for a specific word or pattern
query = "example"
result = re.sub(query, "replacement", text)
print(result)
    
a = "你好 中国 ",去除多余空格只留一个空格。

' '.join(a.split())


import re
_RE_COMBINE_WHITESPACE = re.compile(r"\s+")
my_str = _RE_COMBINE_WHITESPACE.sub(" ", my_str).strip()
        

怎样将字符串转换为小写?

str.lower()

一个编码为GBK的字符串 S,要将其转成UTF-8编码的字符串,应如何操作?

S.encode('gbk').decode('utf-8', 'ignore')

获取字符串”123456“最后的两个字符。

"123456"[-2:]

有一个字符串开头和末尾都有空格,要求写一个函数把这个字符串的前后空格都去掉。

" adabdw ".strip()

Python中的字符串格式化方式你知道哪些?

Using the % operator: "Name: %s, Age: %d" % ("Alice", 25)

Using the str.format() method: "Name: {}, Age: {}".format("Bob", 30)

Using f-strings (formatted string literals):


name = "Charlie"
age = 35
formatted_string = f"Name: {name}, Age: {age}"
        

将字符串"ilovechina"进行反转

"ilovechina"[::-1]

''.join(reversed("ilovechina"))

如何检测字符串中只含有数字?

在Python中,可以使用isdigit()方法来判断一个字符串中是否只包含数字。

将"hello world"转换为首字母大写"Hello World"

'hello world'.title()

x=”abc”,y=”def”,z=[“d”,”e”,”f”],分别求出x.join(y)和x.join(z)返回的结果

x.join(y): dabceabcf

x.join(z): dabceabcf

如何实现 "1,2,3" 变成 ["1","2","3"]

"1,2,3".split(',')

a = ” hehheh “,去除收尾空格

a.strip()

a=”hello”和b=”你好”编码成bytes类型

a.encode('utf-8')

字符串格式化:%和.format

对于`%`最烦人的是它无法同时传递一个变量和元组."hi there %s" % name 但是,如果name恰好是(1,2,3),它将会抛出一个TypeError异常.为了保证它总是正确的,你必须这样做: "hi there %s" % (name,)

Iterator Types

什么是迭代器?什么是可迭代对象?

可迭代对象是一种能够一次返回一个成员的对象。迭代器是代表数据流的对象。重复调用迭代器的__next__() 方法会返回流中的连续项。

python的迭代器和生成器,有什么区别和特性

迭代器是表示数据流的对象。它们实现了迭代器协议,该协议由__iter__()和__next__()方法组成。可以使用iter()函数创建迭代器,并使用next()函数生成值。它们允许通过仅在需要时获取项目来进行惰性评估。

生成器是一种特殊类型的迭代器,它简化了迭代器的创建。 它们是使用带有yield关键字的函数来定义的,该关键字在挂起函数状态时返回一个值。 生成器也可以使用生成器表达式创建,类似于列表推导式,但使用括号而不是方括号。 它们的内存效率很高,因为它们动态生成值,而不是将它们存储在内存中。

总之,迭代器和生成器都用于迭代项目集合,但生成器提供了一种更简洁、更高效的方式来创建迭代器,特别是在处理不需要完全加载到内存中的大型数据集或序列时。

Generator Types

什么是生成器?

生成器是返回generator iterator的函数。generator iterator是由生成器函数创建的对象。生成器是迭代器,是一种只能迭代一次的可迭代对象。生成器不会将所有值存储在内存中,它们会动态生成值。生成器,也称为半协程,生成器中的yield语句并没有指定要跳转到的协程,而是将一个值传回给调用者并将控制权转移回生成器的调用者。,而真正的协程是可以切换到其它协程。

什么是异步生成器函数?如何定义?
将列表生成式中[]改成() 之后数据结构是否改变?

是,从列表变为生成器


>>> L = [x*x for x in range(10)]
>>> L
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
>>> g = (x*x for x in range(10))
>>> g
 at 0x0000028F8B774200>
    
迭代器和生成器的区别是什么?

通过列表生成式,可以直接创建一个列表。但是,受到内存限制,列表容量肯定是有限的。而且,创建一个包含百万元素的列表,不仅是占用很大的内存空间,如:我们只需要访问前面的几个元素,后面大部分元素所占的空间都是浪费的。因此,没有必要创建完整的列表(节省大量内存空间)。在Python中,我们可以采用生成器:边循环,边计算的机制—>generator


>>> mylist = [x*x for x in range(3)]        # Iterables
>>> mygenerator = (x*x for x in range(3))     # Generators
    

You cannot perform for i in my generator a second time since generators can only be used once

yield表达式有什么用?

yield is a keyword that is used like `return`, except the function will return a generator.

带有yield的函数不再是一个普通函数,而是一个生成器。当函数被调用时,返回一个生成器对象。不像一般函数在生成值后退出,生成器函数在生成值后会自动挂起并暂停他们的执行状态。

请将[i for i in range(3)]改成生成器

(i for i in range(3))

生成器推导式

(i for i in range(3))

Set

举一个你在以往项目中用到set数据结构的问题,并说明为什么当时选择了 set 这种数据结构。

测试是否存在,测试是否是成员,去重,都会用到set。

List

list和tuple的区别是什么?

list是可变数据结构,tuple是不可变数据结构。

list如何去重?

用集合:转化set去重再转化为list.

用字典:{}.fromkeys(l1).keys()

保留顺序:list(set(l1)).sort(key=l1.index)

列表推导式: l2 = []; [l2.append(i) for i in l1 if not i in l2]

list和字典的区别是什么?

list是按位置索引并允许重复的有序集合,而dict是唯一键对的无序集合。

python的list底层是怎么实现的?各种操作复杂度?

Python列表的底层被实现为指向列表元素的指针数组。 这意味着 Python 列表本质上是内存中对象的引用数组。

至于操作复杂度,以下是Python列表的各种操作的复杂度:

  • 通过索引访问元素:O(1)
  • 将元素追加到列表末尾:平均 O(1),但在最坏情况下,当底层数组需要调整大小时,O(n)
  • 在列表的开头或中间插入或删除元素:O(n),因为可能需要移动元素来适应更改
  • 按值删除元素:O(n),因为它可能涉及搜索元素 这些复杂性基于底层数组的动态调整大小以及在更改列表时需要移动元素。
  • 列表嵌套元组,分别按字母和数字排序
    
    a = [("Amana", 28), ("Zenat", 30), ("Abhishek", 29), ("Nikhil", 21), ("B", 3)]
    b = sorted(a, key = lambda x: x[0])
    # sort in place
    a.sort(key = lambda x: x[0])
        
    
    a.sort(key = lambda x: x[1])
        
    列表推导式

    [x for x in l]

    根据字符串长度排序

    sorted(['fdsal', 'fa', 'faksjfks'], key=lambda x: len(x))

    举例sort和sorted对列表排序,list=[0,-1,3,-10,5,9],使用lambda函数

    sort原址排序 sorted返回排序结果

    [[1,2],[3,4],[5,6]]一行代码展开该列表,得出[1,2,3,4,5,6]

    [x for l in a for x in l]

    [1,2,3]+[4,5,6]的结果是多少?

    [1, 2, 3, 4, 5, 6]

    使用pop和del删除字典中的"name"字段,dic = {"name":"zs","age":18}

    name = dic.pop('name')

    del dic['name']

    求两个列表的交集、差集、并集

    交集方法一:[value for value in lst1 if value in lst2]

    交集方法二:list(set(lst1) & set(lst2)

    交集方法三:set(lst1).intersection(lst2)

    差集:set(first_list) - set(second_list)

    并集:set(first_list) | set(second_list)

    python中list和tuple有什么区别?怎么转化?

    list是可变序列,tuple是不可变序列

    tuple(lst)

    list(tup)

    如何合并两个list

    相加

    如何打乱一个列表的元素?

    random.shuffle(mylist)

    有一个排好序地 list 对象 alist,查找其中是否有某元素 a(尽可能地使用标准库函数)
    
    try:
        alist.index(a)
    except ValueError:
        return False
    return True
        
    现在有一个list对象alist,里面的所有元素都是字符串,编写一个函数对它实现一个大小写无关的排序。

    alist.sort(key=lambda x:x.lower())

    list的内存布局是怎样的?内存布局时如何影响append、insert、pop、remove、search、sort的时间复杂度的。
    • 通过索引访问元素:时间复杂度:O(1), 通过列表中的索引访问元素具有恒定的时间复杂度。 这是因为列表是作为数组实现的,允许根据元素的索引直接访问元素。
    • 追加元素:时间复杂度:O(1)(摊销)。由于动态数组调整大小和摊销分析,将元素附加到列表末尾通常具有平均恒定时间复杂度。 但是,有时可能需要调整底层数组的大小,从而导致偶尔的追加操作的线性时间复杂度。
    • 在末尾插入或删除元素:时间复杂度:O(1)。在列表末尾插入或删除元素也具有恒定时间复杂度,因为它涉及修改列表的长度而不需要重新定位其他元素。
    • 在开头或中间插入或删除元素:时间复杂度:O(n)。在列表的开头或中间插入或删除元素具有线性时间复杂度,因为它可能需要移动后续元素以适应更改。
    • 搜索元素(使用 in):时间复杂度:O(n)。使用in运算符在列表中搜索元素具有线性时间复杂度,因为它涉及迭代列表,直到找到目标元素或到达列表末尾。
    • 对列表进行排序:时间复杂度:O(n log n) 到 O(n^2)。对列表进行排序的时间复杂度取决于所使用的排序算法。 Python内置的排序方法是基于Timsort实现的,一般情况下平均时间复杂度为O(n log n)。 然而,在最坏的情况下,对于某些输入分布,它可能会降级为 O(n^2)。

    了解各种列表操作的时间复杂度对于编写高效代码至关重要,尤其是在处理大型数据集或性能关键型应用程序时。它有助于根据预期的数据访问和操作模式就使用哪些数据结构和算法做出明智的选择。

    Can you sum all of the elements in the list, how about to multiply them and get the result?

    sum([2, 3, 5])

    math.prod(list1)

    reduce((lambda x, y: x * y), list1)

    dict

    Does python dictionary maintain order?

    从Python3.6开始,常规字典将其items按照插入底层字典的顺序保留。

    Why are python dictionaries ordered?

    本质上,通过保留两个数组。第一个数组dk_entries按插入顺序保存字典的条目(类型为PyDictKeyEntry)。保留顺序是通过这是一个仅附加数组来实现的,其中新项目始终插入在末尾(插入顺序)。第二个数组dk_indices保存dk_entries数组的索引,该数组充当哈希表。

    根据键对字典排序
    
    >>> d = {2:3, 1:89, 4:5, 3:0}
    >>> dict(sorted(d.items()))
        
    
    sorted(zipped, key=lambda x: x[1])
        
    python字典和json字符串相互转化方法

    json.loads('{ "name":"John", "age":30, "city":"New York"}')

    json.dumps({"name": "John", "age": 30, "city": "New York"})

    字典推导式

    d = {key: value for (key, value) in iterable}

    python的dict底层是如何实现的?

    在Python中,dict数据结构的底层通常使用哈希表来实现。

    哈希表:Python字典的底层实现涉及哈希表,它是一种允许高效查找、插入和删除键值对的数据结构。散列用于将键映射到数组中的索引,为这些操作提供恒定时间的平均情况性能。

    键散列:当一个键被添加到字典中时,它的哈希值是使用内置的哈希函数计算的。 然后,该哈希值用于确定存储键值对的底层数组中的索引。

    碰撞处理:由于不同的键可能具有相同的哈希值(冲突),因此哈希表实现包括处理冲突的机制,例如使用单独的链接或带有探测的开放寻址来解决冲突并将多个项目存储在同一索引处。

    动态调整大小:为了保持高效的性能,Python 字典采用动态调整大小策略。 随着字典中键值对数量的增长,底层数组会定期调整大小和重新散列,以确保负载因子(项与数组大小的比率)保持在一定范围内,从而避免过度冲突并保持最佳查找次。

    python的dict底层是什么哈希算法?

    哈希函数:用于计算键的哈希值的哈希函数被实现为hash()方法。 此方法旨在为每个不同的对象生成唯一的整数哈希值,从而允许在底层哈希表中进行高效的存储和检索。

    开放寻址:Python的dict使用开放寻址作为冲突解决策略。当发生冲突时(即,当多个键映射到相同的哈希值时),开放寻址涉及检查哈希表中的其他位置以找到用于存储键值对的空槽。

    二次探测:为了解决冲突,Python的dict采用了一种称为二次探测的开放寻址变体。 这意味着,如果哈希表中的特定索引发生冲突,算法将使用探测偏移的二次序列系统地搜索下一个可用槽,直到找到空槽。

    通过使用散列、开放寻址和二次探测,Python 的 dict 实现了键值对的高效存储和检索,同时处理冲突并保持良好的性能特征,特别是对于查找和插入。 这有助于提高 Python 字典数据结构的整体有效性。

    如何更新字典,如果key有重复用哪个value

    Python字典不能有重复的键。如果key已经存在,覆盖之前存储的值。

    判断字典键是否存在的方法
    • key in d
    字典怎么删除键值?

    del d[key]

    val = d.pop(key)

    现在有一个dict对象adict,里面包含了一百万个元素,查找其中的某个元素需要多少次比较?一千万个元素呢?

    O(1)常量时间。

    字典操作中del和pop有什么区别

    都能删除字典的键值对。pop会返回值。

    dl = [{'name':'alice', 'age':38}, {'name':'bob', 'age':18}],按照字典的内的年龄排序

    sorted_dict = dict(sorted(dl.items(), key=operator.itemgetter(1)))

    请合并下面两个字典 a = {"A":1,"B":2},b = {"C":3,"D":4}

    a.update(b)

    a | b

    如何把元组("a","b")和元组(1,2),变为字典{"a":1,"b":2}

    dict(zip(("a", "b"),(1,2)))

    创建字典有哪些方法?

    直接创建: dict = {'name':'earth', 'port':'80'}

    工厂方法: dict([('name','earth'),('port','80')])

    fromkeys()方法: dict.fromkeys(('x','y'), -1)

    对比一下dict中items与iteritems

    items(): 返回字典的(键,值)对列表的新视图。不会构建数值,占用大量内存。

    iteritems(): 返回字典的(键,值)对的迭代器。在Python3中去除了。

    Built-in Exceptions

    IOError、AttributeError、ImportError、IndentationError、IndexError、KeyError、SyntaxError、NameError分别代表什么异常

    IOError: 输入输出异常。

    AttributeError: 当引用对象的属性失败时引发。

    ImportError: import语句尝试加载模块时遇到问题时引发。

    IndentationError:与不正确缩进相关的语法错误。

    IndexError:当访问序列超出范围时引发。

    KeyError: 在映射或字典中找不到相关键时引发。

    SyntaxError: 当解析器遇到语法错误时引发。

    NameError: 当未找到本地或全局名称时引发。

    写一段自定义异常代码

    异常通常应该直接或间接地从Exception类派生。大多数异常都是使用以“Error”结尾的名称来定义的,类似于标准异常的命名。

    
    class CustomError(Exception):
        def __init__(self, message):
            self.message = message
    try:
        raise(CustomError("This is a custom exception."))
    except CustomError as e:
        print("A New Exception occurred: ", e.message)
        
    举例说明异常模块中try except else finally的相关意义

    
    def divide(x, y):
        try:
            result = x / y
        except ZeroDivisionError:
            print("Division by zero!")
        else:
            print("Division is successful. Result:", result)
        finally:
            print("Executing finally block")
    # Example usage
    divide(6, 2)  # This will execute the else and finally block
           

    try块尝试执行相关代码。如果发生异常并且匹配except块的异常,它将被except块捕获。如果没有发生异常,则执行else块。最后,无论是否发生异常,finally块都会被执行,这对于执行清理操作或释放资源非常有用,确保无论是否发生异常,某些代码都会运行。

    raise语句有什么用途?

    raise语句允许程序员强制发生指定的异常。

    datetime

    请用datetime模块打印当前时间戳 “2018-04-01 11:38:54”

    datetime.now().strftime('%Y-%m-%d %H:%M:%S')

    如果当前的日期为 20190530,要求写一个函数输出 N 天后的日期,(比如 N 为 2,则输出 20190601)

    operator

    python里is和==的区别?a=1,b=1,a is b是啥?

    is是测试对象身份,是对比地址。==是对比值

    json

    json 序列化时,默认遇到中文会转换成 unicode,如果想要保留中文怎么办?

    json.dumps({"ddf": "你好"}, ensure_ascii=False)

    json序列化时,可以处理的数据类型有哪些?

    数值、布尔值、空值、字符串、数组、对象(嵌套键值对集合)

    json序列化时,如何定制支持datetime类型?

    自定义JSONEncoder。

    io

    read,readline和readlines有什么区别?
    • read 读取整个文件
    • readline 读取下一行,使用生成器方法
    • readlines 读取整个文件到一个迭代器以供我们遍历

    copy

    python中copy和deepcopy区别是什么?

    在Python中,copy和deepcopy函数分别用于创建对象的浅拷贝和深拷贝。

    copy函数创建对象的浅表副本。这意味着它创建一个新对象,但不会在原始对象中创建嵌套对象的新副本。 如果原始对象包含对其他对象的引用,则浅拷贝也将引用相同的对象。

    deepcopy函数创建对象的深层副本。它递归地创建原始对象内所有嵌套对象的新副本,以便复制的对象在结构和内容方面完全独立于原始对象。

    
    import copy
    original_list = [1, [2, 3], 4]
    # Shallow copy
    shallow_copied_list = copy.copy(original_list)
    shallow_copied_list[1][0] = 'changed'
    print(original_list)  # Output: [1, ['changed', 3], 4]
    # Deep copy
    deep_copied_list = copy.deepcopy(original_list)
    deep_copied_list[1][0] = 'not changed'
    print(original_list)  # Output: [1, ['changed', 3], 4]
        

    在此示例中,对浅复制列表进行更改后,原始列表也会受到影响,因为它们共享对嵌套对象的引用。然而,对于深度复制列表,原始列表保持不变,因为它是完全独立的。

    shutil

    Python如何copy一个文件?

    shutil.copyfile(src, dst)

    os

    说明os,sys模块不同,并列举常用的模块方法?

    os模块负责与操作系统交互,提供对操作系统底层接口的访问。sys模块负责程序与Python解释器的交互,提供一系列的功能和功能用于操作Python运行时环境的变量。

    os Common methods
    os.remove()
    os.rename()
    os.walk()
    os.chdir()
    os.mkdir/makedirs
    os.rmdir/removedirs
    os.listdir()
    os.getcwd()
    os.chmod()
    os.path.basename()
    os.path.dirname()
    os.path.join()
    os.path.split()
    os.path.splitext()
    os.path.getatime\ctime\mtime
    os.path.getsize()
    os.path.exists()
    os.path.isabs()
    os.path.isdir()
    os.path.isfile()
        
    如何用Python删除一个文件?

    os.remove("demofile.txt")

    sys

    sys common methods
    sys.argv
    sys.modules.keys()
    sys.exc_info()
    sys.exit(n)
    sys.hexversion
    sys.maxint
    sys.maxunicode
    sys.modules
    sys.path
    sys.platform
    sys.stdout
    sys.stdin
    sys.stderr
    sys.exc_clear()
    sys.byteorder
    sys.api_version
    sys.version_info
        
    命令行启动程序并传参,sys.argv是什么,sys.argv[0]是什么?

    socket

    写一个简单的python socket编程
    
    # Echo server program
    import socket
    HOST = ''                 # Symbolic name meaning all available interfaces
    PORT = 50007              # Arbitrary non-privileged port
    with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
        s.bind((HOST, PORT))
        s.listen(1)
        conn, addr = s.accept()
        with conn:
            print('Connected by', addr)
            while True:
                data = conn.recv(1024)
                if not data: break
                conn.sendall(data)
        
    
    # Echo client program
    import socket
    HOST = 'daring.cwi.nl'    # The remote host
    PORT = 50007              # The same port as used by the server
    with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
        s.connect((HOST, PORT))
        s.sendall(b'Hello, world')
        data = s.recv(1024)
    print('Received', repr(data))
        
    通常在python编写tcp服务时,我们使用拆、粘包的模块是什么?如何加载这个模块?

    TCP本来就是基于字节流而不是消息包的协议,要自己搞定字节流解析,本质上就是如何设计应用层协议的问题。可以用struct模块将字节解释为打包的二进制数据。

    假设fd是一个socket,read(fd, buf, 1024),可能返回哪些值?其代表什么含义?

    返回一个非负整数,指示实际读取的字节数。否则,函数返回 -1 并设置 errno 来指示错误。

    random

    如何生成0-100的随机数?
    random.randrange(101)

    re

    s="info:xiaoZhang 33 shandong",用正则切分字符串输出['info', 'xiaoZhang', '33', 'shandong']
    
    import re
    s = "info:xiaoZhang 33 shandong"
    re.split("[\s:]", s)
        
    正则表达式匹配中,(.*)和(.*?)匹配区别?

    *匹配0次或多次重复, +匹配1次或多次重复,?匹配重复0或1次

    *、 +和?量词都是贪婪的;它们匹配尽可能多的文本。?是非贪婪修饰符后缀

    正则匹配以163.com结尾的邮箱

    re.search('[a-zA-Z0-9]+@163.com', "csyezheng@gmail.com csyezheng@163.com")

    正则re.compile()作用?

    将正则表达式模式编译成正则表达式对象,可以使用其match()、search()等方法进行匹配

    a = "张明 98分",用re.sub,将98替换为100

    re.sub('98', '100', a)

    python正则中search和match有什么区别?

    match()仅检查字符串开头是否匹配,匹配成功才会返回结果,否则返回None。re.search() 检查字符串中任何位置的匹配,只到找到第一个匹配然后返回一个包含匹配信息的对象。

    itertools

    我们知道对于列表可以使用切片操作进行部分元素的选择,那么如何对生成器类型的对象实现相同的功能呢?

    无法使用普通切片操作来切片生成器对象或迭代器。相反,您需要使用 itertools.islice。

    
    from itertools import islice    
    g = (i for i in range(100))
    for num in islice(g, 95, None):
        print num
        

    pdb

    你调试python代码的方法有哪些?

    打断点、打印、断言、日志、二分查找、注释代码

    heapq

    python 里关于“堆”这种数据结构的模块是哪个?“堆”有什么优点和缺点?举一个游戏开发中可能会用到堆的问题。

    堆是二叉树,堆分为大顶堆和小顶堆,小顶堆的每个父节点的值都小于或等于其任何子节点的值。Python里的模块是heapq。

    堆可以用于定时器。假设我们要设计一个定时器,定时器中维护了很多定时任务,每个任务都设定了一个要触发执行的时间点。定时器每过一个很小的单位时间(比如 1 秒),就扫描一遍任务,看是否有任务到达设定的执行时间。如果到达了,就拿出来执行。像这样每次扫描的时候,把所有任务都扫描一遍,肯定很低效,如果任务比较少还好,任务比较多的话,就比较耗时。那有更高效的办法呢?答案是有的。我们可以把每个任务都存储在优先级队列中(以触发时间为优先级的小顶堆),这样最先执行的任务就在堆顶。每次扫描的时候只需取出堆顶任务,拿对于任务的定时时间和当前时间比较。

    假设任务执行时间与当前时间的差为T。如果T小于0,就从队列中删除任务,并执行。否则定时器就可以设定在T秒之后再执行任务。从当前时间到T-1秒的时间内定时器不需要做任何事情。

    inspect

    inspect模块有什么用?

    inspect 模块提供了几个有用的函数来帮助获取有关活动对象的信息,例如模块、类、方法、函数、回溯、框架对象和代码对象。

    subprocess

    python如何执行Linux命令?

    使用subprocess模块执行Linux命令。

    smtplib

    如何用Python来发送邮件?

    使用smtplib模块发送邮件。

    pprint模块是干什么的?

    pretty-print 漂亮打印数据结构

    typing

    什么是鸭子类型(duck-typing)?

    “当看到一只鸟走起来像鸭子、游泳起来像鸭子、叫起来也像鸭子,那么这只鸟就可以被称为鸭子。”

    一种编程风格,不查看对象的类型来确定它是否具有正确的接口;相反,方法或属性只是被简单地调用或使用。通过强调接口而不是特定类型,精心设计的代码通过允许多态性取代。我们可以编写一个函数,它接受一个类型为鸭的对象,并调用它的走和叫方法。在使用鸭子类型的语言中,这样的一个函数可以接受一个任意类型的对象,并调用它的走和叫方法。我们并不关心对象是什么类型,到底是不是鸭子,只关心行为

    鸭子类型在动态语言中经常使用,非常灵活,使得python不像java那样专门去弄一大堆的设计模式。

    有没有一个工具可以帮助查找python的bug和进行静态的代码分析?

    PyLint: It checks for errors in Python code, enforces a coding standard, looks for code smells, and offers simple refactoring suggestions.

    Flake8: This tool combines the linting capabilities of PyFlakes, pycodestyle (formerly known as Pep8), and McCabe complexity checking.

    MyPy: It is a static type checker for Python that aims to combine the benefits of dynamic typing and static typing.

    Bandit: Focused specifically on security, Bandit is designed to find common security issues in Python code.

    Pyright: A fast type checker for Python that supports gradual typing.

    Prospector: Combines the capabilities of several Python static analysis tools to provide a comprehensive overview of your codebase.

    了解类型注解么?

    文档和可读性:明确声明变量和函数参数的预期类型可以通过为开发人员和用户提供额外的上下文来提高代码的可读性。

    静态类型检查:像 mypy 这样的工具可以根据类型注释执行静态类型检查,帮助在运行前识别潜在的类型相关错误。

    IDE支持:集成开发环境 (IDE) 可以利用类型注释来提供增强的代码完成、错误检测和其他功能。

    
    def greeting(name: str) -> str:
        return "Hello, " + name
        

    codecs

    python程序中文输出问题怎么解决?

    Python中默认的编码格式是ASCII格式,解决方法为只要在文件开头加入 # -*- coding: UTF-8 -*- 或者 # coding=utf-8就行了。

    2to3

    说说你知道的Python3和Python2之间的区别?
    • 打印语句:括号
    • 整数除法:产生浮点数
    • 编码支持:原生支持unicode
    • 语法差异:range和xrange
    • 异常捕获:增加as
    • next函数
    xrange 和 range 的区别?

    range和xrange都是在循环中使用,输出结果一样。range返回的是一个list对象,而xrange返回的是一个生成器对象(xrange object)。在python3中没有xrange,只有range,和python2中的xrange()一样。

    Python3和Python2中int和long区别?

    python3中不存在long类型。int即Python2中的long。

    webbrowser

    介绍一下Python中webbrowser的用法?

    webbrowser模块可以用于在Python程序中打开浏览器。它提供了一个跨平台的接口,用于在Python代码中启动系统默认浏览器来打开指定网页或文件。

    Functions

    递归太深会怎样?答栈溢出。为什么会栈溢出?python函数中的临时变量存在哪?那很深的时候,用循环会怎样呢?为什么不会栈溢出?

    在计算机中,函数调用是通过栈(stack)这种数据结构实现的,每当程序执行进入一个函数调用,栈就会加一层栈帧,每当函数返回,栈就会减一层栈帧。 由于栈的大小不是无限的,所以,递归调用的次数过多,就会导致栈溢出。如果递归太深,调用栈可能会耗尽空间,从而导致栈溢出。

    Python中的内存管理涉及一个包含所有Python对象和数据结构的私有堆。在CPython中,所有对象都位于堆上。栈仅保存对此类对象的引用。

    用循环,函数只调用一次,局部变量存储在堆,并且很快就销毁了。

    什么是lambda函数?它有什么好处?

    其实就是一个匿名函数。lambda函数是返回表达式求值结果的单表达式函数。

    简明,创建简单的单行函数。可读性和清晰度。函数式编程可以作为参数传递给高阶函数,如映射、过滤器和排序。对于需要简单的一次性函数的操作更方便。

    它的第一个重要意义是可以在表达式当中直接定义一个函数,而不需要将定义函数和表达式分开,这样有助于将逻辑用更紧凑的方式表达出来。

    它的第二个重要意义是引入了闭包。基本上来说常见的支持lambda表达式的语言里,不存在不支持闭包的lambda表达式;从函数式编程的角度来说,支持闭包也是很重要的。闭包是指将当前作用域中的变量通过值或者引用的方式封装到lambda表达式当中,成为表达式的一部分,它使你的lambda表达式从一个普通的函数变成了一个带隐藏参数的函数。

    Python为什么不需要函数重载?

    函数重载主要是为了解决两个问题。可变参数类型和可变参数个数。python是动态类型语言,支持鸭子类型,不需要可变参数类型。Python支持缺省函数,也就不需要可变参数个数了。

    Python递归求和
    
    def custom_sum(l):
    	if not l:
    		return 0
    	else:
    		return l[0] + custom_sum(l[1:])
        
    Python如何进行函数式编程?

    高阶函数:利用高阶函数,它可以将其他函数作为参数或将它们作为结果返回。 示例包括map()、filter() 和reduce()。

    lambda函数: 利用lambda函数为简短的一次性操作创建匿名函数。 将简单功能传递给高阶函数时,Lambda函数特别有用。

    列表推导: 使用列表推导式和生成器表达式来基于现有列表或可迭代对象创建新列表或可迭代对象。 这允许采用功能性方法进行数据转换。

    递归:以函数方式使用递归进行迭代和解决问题

    函数一等公民:将函数视为一等公民,这意味着它们可以分配给变量,作为参数传递,并从其他函数返回。 这使得可以使用函数作为要操作和组合的数据。

    标准库:探索函数式编程库,例如 functools 和 itertools,它们提供了以函数式风格处理函数、迭代器和数据操作的工具。

    装饰者:实现装饰器来修改或扩展函数的行为,从而实现函数式编程的各个方面,例如记忆、日志记录或验证。

    如何在函数中设置一个全局变量

    使用global关键字

    Arguments

    How are arguments passed – by reference or by value?

    Remember that arguments are passed by assignment in Python.

    参数通过赋值传递。传入的参数实际上是对象的引用(但引用是按值传递的)。都不是,按赋值传参,根据可变对象就类似于传引用,根据不可变对象就类似于传值。

    python参数*和**区别

    都属于可变参数,*是可变数量位置参数,**是可变数量键值参数。

    Decorators and closures

    说说decorator的用法和它的应用场景?请举例

    Python 的装饰器是一个强大的功能,用于修改或扩展函数或方法的行为,而无需直接修改其代码。 装饰器广泛应用于各种应用场景,包括:

    • 日志记录和分析:装饰器可用于向函数添加日志记录和分析功能,从而允许自动跟踪函数调用、输入、输出和执行时间。
    • 认证与授权:装饰器可以通过向函数或方法添加身份验证和授权检查来强制执行访问控制,确保某些操作仅由授权用户执行。
    • 缓存:装饰器可以实现缓存机制来根据输入参数存储和检索函数结果,从而通过避免冗余计算来提高性能。
    • 验证和数据转换:装饰器可以在函数处理数据之前验证输入参数或转换数据,从而确保数据的完整性和一致性。
    • 重试和错误处理:装饰器可以自动重试失败的函数调用或在多个函数中以一致的方式处理异常。
    • 依赖注入:装饰器可用于将依赖项注入到函数中,从而更轻松地管理外部资源或服务。
    • API端点注册:在 Web 框架中,装饰器通常用于将函数注册为处理 HTTP 请求的端点,从而提供一种干净且有组织的方式来定义路由和相关行为。
    • 面向切面编程(AOP):装饰器可用于以模块化和可重用的方式将横切关注点(例如日志记录、错误处理或安全性)应用于多个函数或方法。
    • 性能监控:装饰器可用于监视和收集函数的性能指标,帮助识别瓶颈并优化代码。
    python装饰器的输入类型和输出类型是什么?

    都是函数

    写一个decorator

    下面是一个简单的 Python 装饰器示例,用于测量函数的执行时间:

    
    import time
    def measure_time(func):
        def wrapper(*args, **kwargs):
            start_time = time.time()
            result = func(*args, **kwargs)
            end_time = time.time()
            print(f"Execution time for {func.__name__}: {end_time - start_time} seconds")
            return result
        return wrapper
    # Applying the decorator to a function
    @measure_time
    def some_function(n):
        total_sum = 0
        for i in range(n):
            total_sum += i
        return total_sum
    # Calling the decorated function
    result = some_function(1000000)
    print(result)
        
    装饰器(用函数实现,和类实现)
    
    def f1(func):
        def f2(*args,**kwargs):
            ...
            return func(*args,**kwargs)
        return f2
    class fn1:
        def __init__(self,func):
            self.func=func
        def __call__(self, *args, **kwargs):
            ...
            return self.func(*args,**kwargs)
        
    什么是闭包?

    内部函数访问外部函数的作用域。

    闭包(closure)是函数式编程的重要的语法结构。闭包也是一种组织代码的结构,它同样提高了代码的可重复使用性。闭包可以实现先将一个参数传递给一个函数,而并不立即执行,以达到延迟求值的目的。当一个内嵌函数引用其外部作作用域的变量,我们就会得到一个闭包. 总结一下,创建一个闭包必须满足以下几点:

    • 1. 必须有一个内嵌函数
    • 2. 内嵌函数必须引用外部函数中的变量
    • 3. 外部函数的返回值必须是内嵌函数
    什么是面向切面编程?

    面向方面编程(AOP)是一种编程范型,将交叉切入关注与作为业务主体的核心关注进行分离,以提高程序代码的模块化程度。

    日志功能即是交叉切入关注的一个典型案例。

    python装饰器、有参数的装饰器和没参数的装饰器有什么区别?
    
    def decorator_factory(argument):
        def decorator(function):
            def wrapper(*args, **kwargs):
                funny_stuff()
                something_with_argument(argument)
                result = function(*args, **kwargs)
                more_funny_stuff()
                return result
            return wrapper
        return decorator
        
    functools.wraps的原理

    functools.wraps 旨在消除装饰器对原函数造成的影响,即对原函数的相关属性进行拷贝,已达到装饰器不修改原函数的目的。

    wraps内部通过partial对象和update_wrapper函数实现。

    https://zhuanlan.zhihu.com/p/45535784

    Classes and Object Oriented

    分别简述OO,OOA

    面向对象编程是一种围绕对象和类概念的编程范式。OOP的关键原则包括封装、继承、多态性和抽象。 封装涉及将数据与操作该数据的方法捆绑在一起。 继承允许类从其他类继承属性和行为。 多态性使对象能够被视为其父类或接口的实例。 抽象允许表示基本特征而不包括背景细节。

    面向对象分析是从面向对象的角度检查问题域并定义系统需求的过程。在 OOA 期间,分析师使用用例图、类图、序列图和状态图等技术来收集需求并对其进行建模,以捕获系统的动态和静态方面。OOA 通过将现实世界的实体建模为对象并定义它们的关系和交互来帮助理解问题域。

    Python类中的self的具体含义是什么?

    引用实例对象

    super()函数的用途

    super() 可以让您避免显式引用基类,特别是多重继承时。

    新式类和旧式类有什么区别?

    旧式类和新式类是指定义和实现类的两种不同方式,其区别主要与继承、方法解析顺序以及某些语言功能的使用有关。

    • 继承:旧式类仅支持经典类继承,其中所有类都被视为内置对象类的子类。 新型类支持一致的继承机制,启用适当的继承链并允许使用内置描述符和元类。旧式类多继承时子类调用通过深度优先查找继承而来的方法
    • 方法解析顺序 (MRO):新型类引入了方法解析顺序 (MRO),该方法遵循一致且可预测的模式(称为 C3 线性化)。 这解决了旧式类使用的多重继承方法中存在的歧义。
    • super函数:super() 函数在新型类中可靠地工作,提供了一种直观的方式来调用继承层次结构中父类的方法。在旧式类中, super() 的行为不太可预测,并且它可能无法在所有情况下按预期工作。
    • 魔法方法:新型类提供了对特殊方法(通常称为“魔术方法”)的改进支持,使自定义行为(例如迭代、比较和字符串表示)变得更加容易。虽然旧式类也支持魔术方法,但在某些情况下它们的行为可能不太一致。
    • 实例属性:新型类为管理实例属性和属性提供了更好的支持,提供了对属性访问、修改和删除的更大灵活性和控制。旧式类在处理实例属性和特性时可能会表现出局限性和不一致。
    旧式类:class OldStyleClass():
    新式类:class NewStyleClass(object):

    Python 3 不支持旧样式类,因此上述任何一种形式都会生成新样式类。

    类变量和实例变量的区别

    类变量:是可在类的所有实例之间共享的值(也就是说,它们不是单独分配给每个实例的)。

    实例变量:实例化之后,每个实例单独拥有的变量。

    __init__和__new__的区别是什么?

    __new__用于创建对象,__init__用于实例化对象

    __new__是一个静态方法,而__init__是一个实例方法.

    __new__`法会返回一个创建的实例,而__init__什么都不返回.

    只有在__new__返回一个cls的实例时后面的__init__才能被调用.

    我们可以分别使用__metaclass__,__new__和__init__来分别在类创建,实例创建和实例初始化的时候做一些小手脚

    使用Python写一个类,并让它尽可能多的支持操作符
    
    class MyClass:
        def __init__(self, value):
            self.value = value
        # Arithmetic Operators
        def __add__(self, other):
            return self.value + other
        def __sub__(self, other):
            return self.value - other
        def __mul__(self, other):
            return self.value * other
        def __truediv__(self, other):
            return self.value / other
        def __floordiv__(self, other):
            return self.value // other
        def __mod__(self, other):
            return self.value % other
        # Comparison Operators
        def __eq__(self, other):
            return self.value == other
        def __ne__(self, other):
            return self.value != other
        def __lt__(self, other):
            return self.value < other
        def __gt__(self, other):
            return self.value > other
        def __le__(self, other):
            return self.value <= other
        def __ge__(self, other):
            return self.value >= other
        # Unary Operators
        def __neg__(self):
            return -self.value
        def __pos__(self):
            return +self.value
        def __abs__(self):
            return abs(self.value)
        # String Representation
        def __str__(self):
            return str(self.value)
    # Create an instance of the class and demonstrate the supported operators
    obj = MyClass(10)
    print(obj + 5)   # Output: 15
    print(obj - 3)   # Output: 7
    print(obj * 2)   # Output: 20
    print(obj / 4)   # Output: 2.5
    print(obj == 10) # Output: True
    print(obj != 10) # Output: False
    print(-obj)      # Output: -10
    print(abs(obj))  # Output: 10
    print(str(obj))  # Output: '10'
        
    python的多态怎么实现的?

    Python中的多态性可以通过使用继承和鸭子类型来实现,允许不同类的对象被视为公共超类的实例或响应相同的方法调用。

    方法重写:子类可以重写父类的方法以提供专门的实现,同时保持一致的接口。

    鸭子类型:Python 中的多态性也可以通过鸭子类型来实现,而不是依赖继承,其中对象是根据其行为(方法和属性)而不是其显式类型或继承层次结构来接受的。

    使用抽象基类 (ABC):Python 的 abc 模块提供对定义抽象基类的支持,它可以定义子类必须遵守的公共接口,从而促进跨不同实现的多态行为。

    函数参数多态性:函数和方法可以接受不同类型或对象的参数,从而根据传递的参数类型允许不同的行为。

    实例方法、类方法、静态方法的区别?

    实例方法是对类的实例进行操作并可以访问该实例的属性。定义实例方法时,会自动传递通常名为self 的第一个参数,提供对调用该方法的实例的引用。实例方法可以访问和修改特定于实例的数据,并且可以直接访问其他实例方法和属性。

    类方法:类方法与类本身相关联,而不是与类的实例相关联。它可以访问和修改特定于类的数据,并执行与整个类相关的操作。类方法是使用@classmethod装饰器定义的,并接受名为cls的常规第一个参数,该参数引用类本身。类方法可用于创建工厂方法、修改类属性以及执行涉及类但不依赖于特定实例的操作等任务。

    静态方法:静态方法不绑定到类或其实例,并且不接收隐式第一个参数(即既不是 self 也不是 cls)。静态方法是使用 @staticmethod 装饰器定义的,通常用于与类相关但不需要访问实例或类数据的实用函数或操作。它们提供了一种在类的命名空间内组织相关函数的方法,同时明确指示该方法不依赖于实例或类状态。

    @property 和 @setter的用法

    @property负责把一个方法变成属性调用。在对实例操作时,不暴露接口,而是通过getter和setter方法实现。

    什么是面向对象的MRO

    方法解析顺序

    Control flow

    Concurrency

    什么是阻塞?Blocking I/O,对于阻塞IO如何提高性能。

    “阻塞”是指程序或线程等待I/O操作完成才能继续执行其他任务的情况。当读取或写入文件、网络套接字或其他 I/O 设备时,可能会发生阻塞 I/O 操作。 在阻塞 I/O 操作期间,程序通常会等待数据传输。

    
    with open('example.txt', 'r') as file:
        data = file.read()  # Blocking read operation
        process_data(data)  # This line will not execute until the read operation completes
        

    可以采用多种策略来减轻对性能和响应能力的潜在负面影响:

    • 异步 I/O:异步 I/O 技术,例如使用非阻塞 I/O 调用或使用异步 I/O 库(例如 Python 中的 asyncio),可以帮助避免在等待 I/O 操作完成时发生阻塞。
    • 多线程和多处理:使用线程或进程并发执行 I/O 操作有助于防止一个 I/O 操作阻塞整个程序。 Python 中的线程和多处理等库可以促进这种方法。
    • 事件驱动编程:在事件驱动系统中,例如基于reactor模式的系统,I/O操作通过事件循环异步处理,允许程序在等待I/O事件的同时继续执行其他任务。

    threading

    简述我们使用多线程编程时,互斥锁与信号量之间的关系。

    在Python多线程编程中,互斥锁和信号量都用于管理多个线程之间对共享资源的访问。

    互斥锁:互斥体(互斥的缩写)是一种锁定机制,一次只允许一个线程执行特定的代码部分,确保对共享资源的并发访问得到正确协调。在Python中,互斥锁可以使用threading.Lock类来实现。线程在访问共享资源之前获取锁,并在访问完成后释放锁。

    信号量:信号量是更通用的同步对象,可以允许多个线程访问共享资源,但对并发访问的最大数量有限制。在Python中,信号量可以使用threading.Semaphore类来实现。 信号量维护一个表示可用许可数量的计数器,线程可以获取或释放许可来控制对共享资源的访问。

    总之,互斥锁用于强制一次由一个线程对资源进行独占访问,而信号量可用于控制对资源的访问,并指定并发访问数量的限制。两者都是管理多线程Python程序中并发的重要工具。

    自旋锁适合哪些场合应用,不适合哪些场合?

    在Python编程中,自旋锁适用于代码关键部分(一次只需要一个线程访问的部分)预计将保持很短持续时间的应用程序。 自旋锁旨在“自旋”或连续检查锁是否可用,而不会将CPU交给其他线程。

    使用自旋锁的适合场景:低争用和短临界区:当锁争用较低且临界区预计非常短时,自旋锁可以非常高效,因为它们避免了上下文切换和线程挂起的开销。在支持高效自旋的系统上:某些系统可能提供有效的线程自旋机制,使自旋锁在这些环境中更加实用。

    不适合使用自旋锁的情况:高争用:在多个线程激烈争用锁的情况下,自旋锁可能会导致CPU使用率过高,因为线程在等待锁可用时不断自旋。长关键部分:如果预计代码的关键部分需要花费大量时间来执行,则使用自旋锁可能会因线程自旋和重复检查锁而导致不必要的CPU使用。在单核或轻负载系统上:在CPU资源有限或并发性较低的系统上,自旋锁可能不是最有效的选择,因为它们可能会导致CPU周期浪费。

    综上所述,自旋锁适用于关键部分较短的低争用场景,特别是在具有高效自旋支持的系统上。 但是,它们不适合高争用场景或关键部分预计需要很长时间才能执行的情况,特别是在 CPU 资源有限的系统上。

    python死锁怎么处理?怎么避免?

    小心使用锁定机制:使用锁、互斥体或其他同步原语时,请确保以一致且安全的方式获取和释放它们。 即使发生异常,也始终在finally块内释放锁以保证它们的释放。倒序解锁。

    避免嵌套锁定:如果可能,请避免嵌套锁定场景,即线程在尝试获取另一个锁时持有一个锁。 这可能会导致潜在的僵局。

    超时和重新评估:获取锁时考虑使用超时来防止无限期等待,并在达到超时时重新评估是否需要锁。

    锁层次结构:实施锁层次结构以确保始终按特定顺序获取锁,从而防止循环依赖和死锁情况。

    使用高级同步抽象:利用asyncio等库提供的更高级别的同步抽象,这些库通常在内部处理同步并降低死锁的风险。

    并发模式:考虑使用并发模式,例如参与者、消息传递或事件驱动编程,这可以最大限度地减少对低级锁定的需求并降低死锁的可能性。

    写出Python一个线程的示例
    
    import threading
    # Define a simple function to be executed by the thread
    def print_numbers():
        for i in range(5):
            print(i)
    # Create a new thread
    thread = threading.Thread(target=print_numbers)
    # Start the thread
    thread.start()
        

    multiprocessing

    Python多进程和多线程在哪些情况下使用?

    多进程适用于CPU密集型任务,利用多个核心。多线程适用于I/O密集型任务。

    在Python编程中,多进程和多线程的区别是什么?

    多进程和多线程是实现并发执行的两种不同方法。

    进程是资源分配的最小单位,创建和销毁开销较大。线程:是CPU调度的最小单位,开销小,切换速度快。

    多进程:在多进程中,会创建多个进程,每个进程都有自己的内存空间和资源。 进程默认不共享内存,进程之间的通信通常会涉及更多的开销,例如进程间通信(IPC)。 Python的多进程模块提供对创建和管理多个进程的支持,允许跨多个CPU核心并行执行代码。 多进程适用于CPU密集型任务,利用多个核心,并且可以更灵活地应对某些类型的问题,例如一个进程中的内存泄漏或崩溃,而不影响其他进程。多进程中同一个变量各自有一份拷贝在每个进程中,互不影响。

    多线程:在多线程中,多个线程存在于同一个进程中并共享相同的内存空间。 线程可以更轻松地通信和共享数据,但必须协调对共享资源的访问,以避免竞争条件和其他并发问题。Python的线程模块支持在单个进程中创建和管理多个线程,从而实现代码的并行执行。 多线程适用于I/O密集型任务,其中线程可以在等待响应时重叠I/O操作,从而更有效地利用CPU资源。多线程中,所有变量都由所有线程共享,任何一个变量都可被任何一个线程修改。线程之间共享数据的最大危险在于多个线程同时更改一个变量,造成竞争。

    差异:内存空间:多进程涉及每个进程的单独内存空间,而多线程在进程内共享相同的内存空间。通信和同步:由于内存空间独立,多进程通常需要更明确的通信和同步机制,例如IPC。 在多线程中,线程可以更轻松地通信和共享数据,但需要仔细同步以避免冲突。资源开销:创建和管理进程通常会比在单个进程中创建和管理线程产生更多的资源开销。使用案例:多处理通常用于CPU密集型任务,这些任务可以从跨多个内核的并行执行中受益,而多线程通常用于I/O密集型任务,可以从重叠I/O操作中受益。

    python的异步方式有哪些

    async def and await: async def 关键字用于定义异步函数(协程),而await 关键字在协程中使用以暂停其执行并等待另一个协程或异步操作的结果。

    asyncio module: asyncio 模块为异步 I/O、事件循环管理以及用 Python 编写异步代码的高级抽象提供了基础。 它包括 asyncio.Task、asyncio.Future 和用于运行异步代码的 asyncio.run() 函数等功能。asyncio.create_task() 函数用于将协程的执行安排为事件循环中的并发任务,从而允许多个协程并发执行。

    async for and async with:for 循环和 with 语句的异步版本(表示为 async for 和 async with)分别用于迭代异步迭代器和管理异步资源。

    AIOHTTP and AsyncIO Libraries: AIOHTTP库和AsyncIO标准库提供了用于构建异步HTTP客户端和服务器的工具,利用异步I/O来提高性能和可扩展性。

    Concurrent.futures module: concurrent.futures 模块提供了用于异步执行可调用对象和管理线程或进程池的高级接口,从而提供了执行并行性和并发性的简单方法。

    Async Context Managers: 可以使用 async with 语法定义自定义异步上下文管理器,从而允许以异步方式进行资源管理和清理。

    写出Python一个进程的示例
    
    import multiprocessing
    # Define a function to calculate the square of a number
    def calculate_square(number):
        return number * number
    if __name__ == "__main__":
        # Create a list of numbers
        numbers = [1, 2, 3, 4, 5]
        # Create a pool of worker processes
        with multiprocessing.Pool(processes=3) as pool:
            # Apply the calculate_square function to each number in parallel
            results = pool.map(calculate_square, numbers)
        # Print the results
        print(results)
        

    asyncio

    什么是协程?

    按照标准,协程不是异步的,但使用await和async关键字可以使它们异步。

    在Python编程中,协程是生成器函数的特殊版本,可以暂停和恢复其执行,从而允许协作多任务处理。 协程允许编写可以自愿将控制权交给其他协程的代码,从而可以编写异步和协作并发代码。

    Python 中协程的主要特征包括:

    • 异步执行:协程可以在执行过程中的特定点暂停和恢复,从而实现非阻塞操作并有效利用 CPU 资源。
    • async 和await 关键字:在Python 3.5 及更高版本中,引入了async 和await 关键字来支持协程的异步编程。 async将函数定义为协程,而await用于暂停协程的执行,直到满足某个条件。
    • 事件循环:异步框架(例如asyncio)提供事件循环来管理多个协程的执行,使它们能够协作运行而不会互相阻塞。
    • 并发性:协程可以在不依赖多个线程或进程的情况下并发执行任务,因此非常适合I/O密集型操作,例如网络请求或文件操作。

    总体而言,Python 中的协程为编写异步和协作代码提供了强大的机制,可以高效处理并发任务和I/O操作,而无需传统多线程或多处理的开销。进程和线程都面临着内核态和用户态的切换问题而耗费许多切换时间,而协程就是用户自己控制切换的时机,不再需要陷入系统的内核态。

    python协程怎么使用?

    在Python中,您可以通过使用async关键字定义协程,然后使用wait暂停其执行来使用协程。

    
    import asyncio
    # Define a coroutine using the async keyword
    async def greet(name):
        print("Hello, " + name)
        # Pause the coroutine's execution for 1 second
        await asyncio.sleep(1)
        print("Goodbye, " + name)
    # Call the coroutine using asyncio.run() (Python 3.7+)
    asyncio.run(greet("Alice"))
        

    在协程内部,await关键字用于暂停执行1秒,模拟I/O等异步操作。

    执行时,这段代码将打印“Hello, Alice”,暂停1秒,然后打印“Goodbye, Alice”。

    协程通常与asyncio提供的事件循环结合使用,以处理异步I/O操作、并发任务和其他异步编程模式。

    python的协程和go的goroutine有什么区别?

    coroutine适用于IO密集程序中,而goroutine在IO密集和CPU密集中都有很好的表现。Python是单线程内的协程。

    并发模型:coroutine的运行机制属于协作式任务处理,程序需要主动交出控制权,宿主才能获得控制权并将控制权交给其他coroutine。goroutine属于抢占式任务处理。

    语言特点:Python 的协程是建立在生成器函数之上的一项功能,利用async和wait关键字来启用异步编程。Go对goroutine具有原生支持,这些goroutine是轻量级线程,是该语言核心并发模型的一部分。

    同步和通讯:在Python中,协程通常使用异步原语、事件循环和asyncio等库进行同步和通信。Go提供了channel和select语句作为内置工具,用于安全地协调goroutine之间的通信和同步。

    Python Runtime

    garbage collection

    Python是如何进行内存管理的?Python垃圾回收机制是怎样的?

    Python GC主要使用引用计数(reference counting)来跟踪和回收垃圾。在引用计数的基础上,通过“标记-清除”(mark and sweep)解决容器对象可能产生的循环引用问题,通过“分代回收”(generation collection)以空间换时间的方法提高垃圾回收效率。

    引用计数:PyObject是每个对象必有的内容,其中`ob_refcnt`就是做为引用计数。当一个对象有新的引用时,它的`ob_refcnt`就会增加,当引用它的对象被删除,它的`ob_refcnt`就会减少.引用计数为0时,该对象生命就结束了。

    标记-清除机制:基本思路是先按需分配,等到没有空闲内存的时候从寄存器和程序栈上的引用出发,遍历以对象为节点、以引用为边构成的图,把所有可以访问到的对象打上标记,然后清扫一遍内存空间,把所有没标记的对象释放。

    分代技术: 分代回收的整体思想是:将系统中的所有内存块根据其存活时间划分为不同的集合,每个集合就成为一个“代”,垃圾收集频率随着“代”的存活时间的增大而减小,存活时间通常利用经过几次垃圾回收来度量。Python默认定义了三代对象集合,索引数越大,对象存活时间越长。

    python回收内存溢出情况,怎么检查以及处理

    使用resource模块:Python中的资源模块可用于检索有关进程资源利用率的信息,包括内存使用情况。 您可以使用resource.getrusage()来获取内存使用统计信息。

    使用psutil库:psutil库提供了一种跨平台的方式来检索系统和进程信息,包括内存使用情况。您可以使用psutil.Process(pid).memory_info()获取特定进程的内存使用详细信息。

    垃圾收集:Python内置的垃圾收集器会自动回收不再被引用的对象所占用的内存。 但是,您可以使用gc.collect()手动触发垃圾收集以尝试释放内存。

    内存分析:使用内存分析工具(例如 memory_profiler)来识别代码中的内存密集型部分并分析内存使用模式。 这可以帮助查明内存消耗可能存在问题的区域。

    提高代码效率:重构代码以最大程度地减少不必要的内存分配,避免冗余数据副本,并优化代码关键部分的内存使用。

    限制并发和并行性:当使用并发和并行性(例如,使用多处理)时,请仔细控制并发任务的数量,以避免因并行处理而消耗过多的内存。

    python中的回收对象怎么快速确定内存位置

    在Python中,您可以使用内置的id()函数来确定回收对象的内存位置,该函数返回对象的标识(内存地址)。

    Debugging and Profiling

    Python如何计算多个函数花费的时间

    使用 time.time() 进行基本计时: start_time = time.time()end_time = time.time()

    使用装饰器实现可重用性:

    
    import time
    from functools import wraps
    def measure_time(func):
        @wraps(func)
        def wrapper(*args, **kwargs):
            start_time = time.time()
            result = func(*args, **kwargs)
            end_time = time.time()
            duration = end_time - start_time
            print(f"{func.__name__} took {duration} seconds")
            return result
        return wrapper
    @measure_time
    def my_function():
        # Function logic
        pass
        

    使用 timeit 模块(用于精确计时):

    
    import timeit
    setup_code = "from my_module import my_function"
    duration = timeit.timeit("my_function()", setup=setup_code, number=1000)
    print(f"my_function() took an average of {duration/1000} seconds per call")
        

    Algorithms

    用Python实现一个二分查找
    
    def binary_search(arr, target):
        left, right = 0, len(arr) - 1
        while left <= right:
            mid = (left + right) // 2
            # Check if the target is found at the midpoint
            if arr[mid] == target:
                return mid
            # If the target is less than the value at the midpoint, search the left half
            elif arr[mid] > target:
                right = mid - 1
            # If the target is greater than the value at the midpoint, search the right half
            else:
                left = mid + 1
        # If the target is not found in the list, return -1
        return -1
    # Example usage
    arr = [1, 3, 5, 7, 9, 11, 13]
    target = 7
    result = binary_search(arr, target)
    if result != -1:
        print(f"Element found at index {result}")
    else:
        print("Element not found")
        

    Coding style

    What is PEP 8?

    PEP8是Python增强提案8,PEP8是一个为Python代码提供编码约定的文档。

    说说你对zen of python(Python 之禅)的理解,你有什么办法看到它
    例举你知道Python对象的命名规范,例如方法或者类等

    比如方法以行为功能命名。不需要前缀get,类驼峰大小写命名,Base基类和Abstract抽象类和具体意义的类

    了解docstring么?

    作为类、函数或模块中第一个表达式出现的字符串文字。

    如何优雅的给函数或类加注释

    使用docstring

    Python代码缩进中是否支持Tab键和空格混用

    不建议在 Python 中混合使用制表符和空格进行缩进,这可能会导致行为不一致和语法错误。PEP 8是Python代码的官方风格指南,建议每个缩进级别使用4个空格,并明确不鼓励混合使用制表符和空格。

    为了确保代码的清晰度和可维护性,最佳实践是将文本编辑器或 IDE 配置为用空格替换制表符,并在整个Python代码库中一致使用空格进行缩进。

    是否可以在一句 import 中导入多个库?

    可以但是不推荐。因为一次导入多个模块可读性不是很好。

    在给Py文件命名的时候需要注意什么?

    尽可能使用全拼,并且有意义的。小写和下划线连接。

    例举几个规范Python代码风格的工具

    PyLint、PEP8

    Design patterns

    Python如何实现单例模式?其他23种设计模式python如何实现?
    
    class Singleton(object):
        def __new__(cls, *args, **kw):
            if not hasattr(cls, '_instance'):
                orig = super(Singleton, cls)
                cls._instance = orig.__new__(cls, *args, **kw)
            return cls._instance
    class MyClass(Singleton):
        a = 1
    	
    
    class Borg(object):
        _state = {}
        def __new__(cls, *args, **kw):
            ob = super(Borg, cls).__new__(cls, *args, **kw)
            ob.__dict__ = cls._state
            return ob
    class MyClass2(Borg):
        a = 1
        
    
    def singleton(cls):
        instances = {}
        def getinstance(*args, **kw):
            if cls not in instances:
                instances[cls] = cls(*args, **kw)
            return instances[cls]
        return getinstance
    @singleton
    class MyClass:
      ...
        
    
    # mysingleton.py
    class My_Singleton(object):
        def foo(self):
            pass
    my_singleton = My_Singleton()
    # to use
    from mysingleton import my_singleton
    my_singleton.foo()
        

    Third-party Libraries

    说出你常用的几个库

    requests,lxml,bs4,pandas

    说出python中间件Sqlalchemy的具体声明方式?以及模块与MySQLdb之间的区别?
    描述出python常用框架,并简要描述这些框架的优缺点
    python,使用过的包,用过哪些python的库
    python中读取Excel文件的方法

    使用pandas

    平时有用到 Python 的文本开发环境吗?NLTK, spacy

    Programming question

    请用自己的算法, 按升序合并如下两个list, 并去除重复的元素。list1 = [2, 3, 8, 4, 9, 5, 6] list2 = [5, 6, 10, 17, 11, 2]
    实现一个 stack。
    
    class Stack:
        """
        Last in first out (LIFO) stack implemented using array.
        """
        def __init__(self, capacity=4):
            """
            Initialize an empty stack array with default capacity of 4.
            """
            self.data = [None] * capacity
            self.capacity = capacity
            self.top  = -1
        def is_empty(self):
            """
            Return true if the size of stack is zero.
            """
            if self.top == -1:
                return True
            return False
        def push(self, element):
            """
            Add element to the top.
            """
            self.top += 1
            if self.top >= self.capacity:
                raise IndexError('Stack overflow!')
            else:
                self.data[self.top] = element
        def pop(self):
            """
            Return and remove element from the top.
            """
            if self.is_empty():
                raise Exception('Stack underflow!')
            else:
                stack_top = self.data[self.top]
                self.top -= 1
                return stack_top
        def peek(self):
            """
            Return element at the top.
            """
            if self.is_empty():
                raise Exception('Stack is empty.')
                return None
            return self.data[self.top]
        def size(self):
            """
            Return the number of items present.
            """
            return self.top + 1
        
    编写一个简单的ini文件解释器。
    
    class IniParser(object):
        def __init__(self, iniFile):
            self.iniFile = iniFile
            with open(self.iniFile) as f:
                ini = []
                for i in f:
                    if self.isSession(i):
                    l = i[2:-2].strip()
                    i = self.str2session(l)
                    ini.append(i.strip())
                self.ini = self._format(ini)
        
    有两个序列a,b,大小都为n,序列元素的值任意整形数,无序;要求:通过交换a,b中的元素,使[序列a元素的和]与[序列b元素的和]之间的差最小
    现有 N 个纯文本格式的英文文件,实现一种检索方案,即做一个小搜索引擎。