反射
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));
}
}
网友评论