编程语言面试题(一)
1、Java反射机制的作用是什么?
Java反射(Reflection)是Java语言的一个强大特性,它允许程序在运行时动态地获取类的信息并操作类或对象的属性、方法和构造器。Java反射机制的主要作用是为程序提供运行时动态操作类或对象的能力,打破了传统编程中"编译时确定"的限制。
反射机制的详细作用 | |
运行时获取类信息 | 动态获取类的完整结构:包括类名、父类、接口、修饰符等 |
获取类的成员信息:字段(属性)、方法、构造器等详细信息 | |
获取泛型信息:可以获取类、方法、字段的泛型类型参数 | |
获取注解信息:读取类、方法、字段上的注解及其属性值 | |
运行时操作类或对象 | 动态创建对象:即使编译时不知道具体类名 |
动态调用方法:可以调用任意方法,包括私有方法(需设置accessible) | |
动态访问/修改字段值:可以读写任意字段,包括私有字段 | |
突破访问限制 | 访问私有成员:通过setAccessible(true)可以突破private限制 |
调用私有方法:可以调用类的私有方法 | |
操作final字段:可以修改final修饰的字段值(但有风险) | |
动态代理 | 实现AOP编程:如Spring的@Transactional注解就是通过动态代理实现的 |
接口代理:为接口动态生成实现类 | |
框架开发的核心支撑 | 依赖注入:如Spring通过反射实现IoC容器 |
ORM框架:如Hibernate/MyBatis通过反射实现对象-关系映射 | |
序列化/反序列化:如Jackson/Gson通过反射实现JSON转换 | |
单元测试:测试框架通过反射调用测试方法 | |
注解处理:运行时处理各种注解 | |
通用工具开发 | 对象拷贝工具:如BeanUtils.copyProperties() |
动态验证工具:运行时验证对象属性 | |
插件系统:动态加载和执行插件 | |
动态类型操作 | 操作数组:动态创建和操作各种类型数组 |
处理不确定类型:编写通用代码处理各种类型对象 | |
反射的优缺点 | |
优点 | 缺点 |
提高代码的灵活性和扩展性 可以在运行时动态操作类或对象适合开发通用框架和工具 | 性能开销较大(比直接调用慢) 破坏了封装性(可以访问private成员) 增加了代码复杂度安全问题(可以突破private限制) |
2、反射机制与直接调用函数有什么区别?
由于反射涉及动态解析类型,其性能通常低于直接代码调用。在性能敏感的场景中,应谨慎使用反射或考虑缓存反射操作的结果。
反射是Java语言的一个强大特性,合理使用可以极大增强程序的灵活性,但过度使用也可能带来维护和性能问题。
3、Python中__init__方法的作用是什么?
在 Python 中,__init__方法是一个特殊的方法,用于在创建类的实例时进行初始化操作。它是类的构造函数(constructor),在对象被实例化时自动调用。
__init__方法的作用:
- 初始化对象的属性:通常用于给对象的属性赋初始值。
- 执行必要的设置:例如打开文件、建立数据库连接等初始化操作。
- 接受参数:可以在实例化对象时传入参数,用于定制对象的初始状态。
class Person:
def __init__(self, name, age):
self.name = name # 初始化 name 属性
self.age = age # 初始化 age 属性
# 创建 Person 的实例,自动调用 __init__
person1 = Person("Alice", 30)
print(person1.name) # 输出: Alice
print(person1.age) # 输出: 30
关键点:
- self 参数:代表类的实例,必须是第一个参数,但调用时不需要手动传递。
- 自动调用:在创建对象时(如 obj = MyClass())自动执行。
- 可以有参数:可以在 __init__ 中定义参数,实例化时传入(如 Person("Alice", 30))。
- 不是必须的:如果不需要初始化,可以不定义 __init__,Python 会提供默认的空实现。
4、Python中初始化方法的区别?
初始化方式 | 适用场景 |
__init__ | 标准初始化方法,用于设置实例属性 |
__new__ | 控制实例创建过程(如单例模式) |
类变量 | 定义所有实例共享的属性 |
默认参数 | 提供可选初始化参数 |
提供替代构造方法(如 from_birth_year) | |
__post_init__ | dataclasses的额外初始化逻辑 |
6、Python中__new__和__init__区别?
__new__ 控制实例的创建,__init__控制实例的初始化
方法 | __new__ | __init__ |
作用 | 创建并返回类的实例(构造方法) | 初始化实例(初始化方法) |
调用时机 | 在__init__之前调用 | 在__new__之后调用 |
返回值 | 必须返回一个实例(通常是cls的实例) | 无返回值(None) |
参数 | cls(类本身) | self(实例本身) |
是否必须 | 通常不需要定义(除非自定义实例创建逻辑) | 可选(但常用于初始化) |
用途 | 单例模式、不可变类型(如str,tuple)子类化 | 初始化实例属性 |
7、什么情况下重写new方法?
1)单例模式(Singleton)
确保一个类只有一个实例,并提供一个全局访问点。
实现方式:在 __new__ 中检查是否已存在实例,若存在则返回该实例,否则创建新实例。
class Singleton:
_instance = None
def __new__(cls, *args, **kwargs):
if cls._instance is None:
cls._instance = super().__new__(cls)
return cls._instance
obj1 = Singleton()
obj2 = Singleton()
print(obj1 is obj2) # True(两个变量指向同一个实例)
2)继承不可变类型(如 str, tuple, int)
不可变类型(immutable)的实例在创建后不能修改,因此需要在 __new__ 中控制其创建方式。
class UpperStr(str):
def __new__(cls, value):
# 在创建实例前修改值
modified_value = value.upper()
return super().__new__(cls, modified_value)
s = UpperStr("hello")
print(s) # "HELLO"(实例化时自动转为大写)
3) 对象池(Object Pooling)
复用已创建的对象以减少资源消耗(如数据库连接、线程池等)。
实现方式:在 __new__ 中维护一个对象池,返回已存在的对象而非创建新实例。
class DatabaseConnection:
_pool = []
def __new__(cls):
if cls._pool:
return cls._pool.pop()
else:
new_conn = super().__new__(cls)
new_conn._initialize() # 模拟初始化连接
return new_conn
def _initialize(self):
print("New connection created")
self.is_active = True
def close(self):
self.is_active = False
self.__class__._pool.append(self) # 放回池中
# 使用
conn1 = DatabaseConnection() # 输出: New connection created
conn1.close()
conn2 = DatabaseConnection() # 无输出,复用 conn1
print(conn1 is conn2) # True
4) 动态修改实例属性(在 __init__ 之前)
如果需要在实例创建时动态修改属性(例如根据参数决定实例类型),可以在 __new__ 中处理。
class Animal:
def __new__(cls, animal_type, *args, **kwargs):
if animal_type == "dog":
return super().__new__(Dog)
elif animal_type == "cat":
return super().__new__(Cat)
else:
return super().__new__(cls)
class Dog(Animal):
def speak(self):
return "Woof!"
class Cat(Animal):
def speak(self):
return "Meow!"
pet = Animal("dog")
print(pet.speak()) # "Woof!"(实际返回的是 Dog 的实例)
5) 自定义元类(Metaclass)的辅助
在元类编程中,__new__ 可以拦截类的创建过程(注意:这里是类的 __new__,不是实例的 __new__)。
class UpperAttrMeta(type):
def __new__(cls, name, bases, attrs):
uppercase_attrs = {
k.upper(): v for k, v in attrs.items()
}
return super().__new__(cls, name, bases, uppercase_attrs)
class MyClass(metaclass=UpperAttrMeta):
x = 1
print(hasattr(MyClass, "x")) # False
print(hasattr(MyClass, "X")) # True(属性名被转为大写)
#测试面试##测试#整理面试过程中的测试问答,常看常新,多多学习!有些问题是从其他人那里转载而来,会在文章下面注明出处,希望大家多多支持~~,觉得满意的话就送一朵小花花,谢谢! 内容目录:https://www.nowcoder.com/discuss/779856598809264128?sourceSSR=users