三道题,分别涉及反射、多线程处理、数字精度

反射

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 ShowMeBug {

    public interface IA{
        String getName();
    }

    public static void main(String[] args) {
        IA ia = (IA) checkName(IA.class.getName() + "&getName=Abc");
        System.out.println(ia.getName());
        IA ia2 = (IA) checkName(IA.class.getName() + "&getTest=ers");
        System.out.println(ia2.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);
    }

}

多线程处理

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.Method;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * 同时100个线程一起存钱,每次存1块钱
 * 1. 实现 deposit() 存钱方法
 * 2. 在 main() 中实现具体逻辑
 * 考点:
 *      1. 主线程和子线程之间的控制问题
 *      2. 反射方式获取方法执行(加分项)
 *      3. 线程池控制精细化控制子线程执行情况(加分项)
 */
public class ShowMeBug {
    private static final Logger LOGGER = LoggerFactory.getLogger(ShowMeBug.class);

    private double balance;

    public void deposit(double money){
        //实现具体的存钱逻辑
        synchronized (this){
            double nowBalance = getBalance();
            balance = nowBalance + money;
            LOGGER.warn("ID: " + String.valueOf(Thread.currentThread().getId())+" >>>>>> NAME: " + Thread.currentThread().getName());
        }
    }

    private double getBalance() {
        // 获取余额
        return balance;
    }

    public static void main(String[] args) {
        try {
            final Class<ShowMeBug> showMeBugClass = ShowMeBug.class;
            Object newInstance = showMeBugClass.newInstance();
            BlockingQueue<Runnable> blockingQueue = new LinkedBlockingDeque<>(10);
            ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(20, 100, 60, TimeUnit.SECONDS, blockingQueue);
            threadPoolExecutor.prestartAllCoreThreads();
            for (int i = 0; i < 100; i++) {
                threadPoolExecutor.execute(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            Method deposit = showMeBugClass.getMethod("deposit", double.class);
                            deposit.invoke(newInstance, 1);
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                });

            }
            threadPoolExecutor.shutdown();
            threadPoolExecutor.awaitTermination(Long.MAX_VALUE, TimeUnit.MINUTES);
            System.out.println(showMeBugClass.getDeclaredField("balance").get(newInstance));
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

}

数字精度

import java.math.BigDecimal;
import java.text.DecimalFormat;

/**
 * 保留 a/b 计算结果小数点后一位
 * 考点:
 *     1. 这题主要考虑到 double 精度问题导致计算显示不正确
 */
public class ShowMeBug {

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

}
Copyright © cnkj.site 2021 all right reserved,powered by Gitbook该文件修订时间: 2021-05-28 11:32:19

results matching ""

    No results matching ""