1. 如何找出整数数组中第二大的数
-
要点
-
定义一个函数用于在整数数组里找出第二大的数。
-
若数组元素少于 2 个,则返回
None
。 -
借助两个变量
first
和second
来跟踪最大数和第二大数。 -
可以添加异常处理,以应对输入非整数数组的情况。
-
若数组包含重复元素,可考虑返回去重后第二大的数。
-
示例
python
def find_second_largest(arr):
if len(arr) < 2:
return None
first = second = float('-inf')
for num in arr:
if num > first:
second = first
first = num
elif num > second and num != first:
second = num
return second if second != float('-inf') else None
# 测试
arr = [12, 35, 1, 10, 34, 1]
print(find_second_largest(arr))
2. 写出如下代码的输出结果并分析
- 要点
-
代码中的
multi
函数返回一个包含 4 个lambda
函数的列表。 -
这些
lambda
函数形成闭包,捕获外部变量i
。 -
当调用这些
lambda
函数时,i
的值为其最终值3
,所以输出为[9, 9, 9, 9]
。 -
若要实现预期的
[0, 3, 6, 9]
输出,可使用默认参数来固定i
的值,修改为[lambda x, i=i: i*x for i in range(4)]
。
- 示例
python
def multi():
return [lambda x : i*x for i in range(4)]
print([m(3) for m in multi()])
3. 统计字符串中字符出现的次数
- 要点
-
利用字典来统计字符串中每个字符的出现次数。
-
遍历字符串,若字符已在字典中则计数加 1,否则将其添加到字典并初始化为 1。
-
可使用
collections.Counter
类来简化代码,Counter(s)
即可实现相同功能。 -
统计时可忽略大小写,将字符串统一转换为大写或小写后再进行统计。
- 示例
python
def count_characters(s):
char_count = {}
for char in s:
if char in char_count:
char_count[char] += 1
else:
char_count[char] = 1
return char_count
# 测试
s = "hello world"
print(count_characters(s))
4. super
函数的用法和场景
- 要点
-
super
函数用于调用父类的方法。 -
在单继承中,可在子类的
__init__
方法里调用父类的__init__
方法,实现代码复用。 -
在多继承中,能确保按正确的方法解析顺序(MRO)调用父类方法。
- 示例
python
class Parent:
def __init__(self):
print("Parent __init__")
class Child(Parent):
def __init__(self):
super().__init__()
print("Child __init__")
c = Child()
5. 类方法、类实例方法、静态方法的区别
- 要点
-
实例方法:第一个参数是
self
,代表实例对象,通过实例对象调用,用于操作实例的属性和方法。 -
类方法:使用
@classmethod
装饰器,第一个参数是cls
,代表类本身,可通过类名或实例对象调用,常用于创建工厂方法。 -
静态方法:使用
@staticmethod
装饰器,无默认第一个参数,可通过类名或实例对象调用,用于组织代码,与类和实例无直接关系。
- 示例
python
class MyClass:
def instance_method(self):
return 'Instance method called', self
@classmethod
def class_method(cls):
return 'Class method called', cls
@staticmethod
def static_method():
return 'Static method called'
obj = MyClass()
print(obj.instance_method())
print(MyClass.class_method())
print(MyClass.static_method())
6. 遍历对象的所有属性
- 要点
-
使用
dir
函数获取对象的所有属性名。 -
通过过滤掉以
__
开头的内置属性,打印出用户自定义的属性名。 -
若要获取属性的值,可结合
getattr
函数。 -
可将属性名和属性值以字典形式存储,方便后续处理。
- 示例
python
class MyClass:
def __init__(self):
self.name = "John"
self.age = 30
obj = MyClass()
for attr in dir(obj):
if not attr.startswith('__'):
print(attr)
7. 如何定义支持多种操作符的类
- 要点
-
通过定义特殊方法,使类支持加法、减法、乘法等操作符。
-
对于不同类型的操作数,可进行类型判断并执行相应操作。
-
可以添加更多操作符支持,如除法、取模等。
-
可以考虑实现反向操作符,如
__radd__
等,以支持不同顺序的操作。
- 示例
python
class MyNumber:
def __init__(self, value):
self.value = value
# 加法
def __add__(self, other):
if isinstance(other, MyNumber):
return MyNumber(self.value + other.value)
return MyNumber(self.value + other)
# 减法
def __sub__(self, other):
if isinstance(other, MyNumber):
return MyNumber(self.value - other.value)
return MyNumber(self.value - other)
# 乘法
def __mul__(self, other):
if isinstance(other, MyNumber):
return MyNumber(self.value * other.value)
return MyNumber(self.value * other)
# 字符串表示
def __str__(self):
return str(self.value)
# 测试
a = MyNumber(5)
b = MyNumber(3)
print(a + b)
print(a - b)
print(a * b)
8. 比较Cython、Pypy、CPython、Numba 的缺点
- 要点
-
Cython:学习成本高,需掌握特定语法;代码可移植性受影响;调试复杂。
-
Pypy:与 CPython 兼容性有问题;启动时间长;内存占用高。
-
CPython:执行速度慢,尤其是 CPU 密集型任务;存在全局解释器锁(GIL),限制多线程并行性能。
-
Numba:支持的 Python 语法和数据类型有限;需提前确定输入数据类型;编译时间可能较长。
9. 抽象类和接口类的区别和联系
- 要点
-
联系:都不能实例化,用于定义规范和约束子类行为;都可包含抽象方法,要求子类实现。
-
区别:抽象类可包含抽象方法、具体方法和属性;接口类通常只含抽象方法,无具体实现和属性。
10. 如何动态获取和设置对象的属性
- 要点
-
使用
getattr
函数动态获取对象的属性。 -
使用
setattr
函数动态设置对象的属性。 -
可结合
hasattr
函数先检查属性是否存在,再进行获取或设置操作。
- 示例
python
class MyClass:
def __init__(self):
self.name = "John"
obj = MyClass()
attr_value = getattr(obj, 'name')
print(attr_value)
class MyClass2:
pass
obj2 = MyClass2()
setattr(obj2, 'age', 30)
print(obj2.age)