面试遇到了几个面试题 记录一下。

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));

    }
}