面试遇到了几个面试题 记录一下。
1. 反射 + 代理
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
* 1. IA 接口类中的getName()方法只是示例
* 2. 实现checkName方法,要求:
* 1. 当IA方法名等于 “&” 后的值的时候,输出 “=” 后的值
* 2. 否则输出 null
* 3. IA 接口类和 main 方法已实现
* 考点:
* 1. 使用代理模式实现具体的方法逻辑
*/
public class ShowMeBug3 {
public static void main(String[] args) {
IA ia = (IA) checkName(IA.class.getName() + "&getName=Abc");
System.out.println(ia.getName());//在此输出Abc
IA ia2 = (IA) checkName(IA.class.getName() + "&getTest=ers");
System.out.println(ia2.getName());//在此输出 null
}
//需要实现的具体逻辑
private static Object checkName(String str) {
}
}
public interface IA {
public String getName();
}
//需要实现的具体逻辑
private static Object checkName(String str) {
String[] split = str.split("&", -1);
String[] strings = split[1].split("=", -1);
String check = strings[0];
String result = strings[1];
InvocationHandler invocationHandler = new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if (method.getName().equals(check)) {
return result ;
}
return null;
}
};
return Proxy.newProxyInstance(IA.class.getClassLoader(), new Class[]{IA.class}, invocationHandler);
}
2. 反射+线程池
/**
* 同时100个线程一起存钱,每次存1块钱
* 1. 实现 deposit() 存钱方法
* 2. 在 main() 中实现具体逻辑
* 考点:
* 1. 主线程和子线程之间的控制问题
* 2. 反射方式获取方法执行(加分项)
* 3. 线程池控制精细化控制子线程执行情况(加分项)
*/
public class Test2 {
private static final Logger LOGGER = LoggerFactory.getLogger(ShowMeBug.class);
private double balance;
public void deposit(double money){
//实现具体的存钱逻辑
}
private double getBalance() {
// 获取余额
return balance;
}
public static void main(String[] args) {
}
}
public class Test2 {
private static final Logger LOGGER = LoggerFactory.getLogger(ShowMeBug.class);
private double balance;
public void deposit(double money) {
synchronized (this) {
double nowBalance = this.getBalance();
this.balance = nowBalance + money;
LOGGER.info("存钱成功");
}
}
private double getBalance() {
// 获取余额
return balance;
}
public static void main(String[] args) throws InstantiationException, IllegalAccessException, InterruptedException, NoSuchFieldException {
Class<Test2> test2Class = Test2.class;
Test2 test2 = test2Class.newInstance();
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(20, 100, 60, TimeUnit.SECONDS, new LinkedBlockingDeque<>(10));
threadPoolExecutor.prestartAllCoreThreads();
for (int i = 0; i < 100; i++) {
threadPoolExecutor.execute(() -> {
try {
Method deposit = test2Class.getMethod("deposit", double.class);
deposit.invoke(test2, 1.0);
} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
}
});
}
threadPoolExecutor.shutdown();
threadPoolExecutor.awaitTermination(Long.MAX_VALUE, TimeUnit.SECONDS);
System.out.println(test2Class.getDeclaredField("balance").get(test2));
}
}
3. 数字精度
public class Test3 {
public static void main(String[] args) {
double a = 3;
double b = 2222222222222222222222.0;
double i = a / b;
//计算结果为科学计数法表示
System.out.println(i);
//精度不足,超过一定位数后直接以0补全
DecimalFormat decimalFormat = new DecimalFormat("0.00000000000000000000000000000000000000000000000000000000000000");
System.out.println(decimalFormat.format(i));
//使用 BigDecimal 计算
BigDecimal bigDecimal = new BigDecimal(i);
String plainString = bigDecimal.toPlainString();
System.out.println(plainString);
//精度不足,保留小数点后位数不多的可以使用
String format = String.format("%.45f", Double.valueOf(plainString));
System.out.println(format);
//精度足够,但是不能四舍五入,需要单独处理
System.out.println(plainString.substring(0, 45));
}
}