Java面试题和解答(三)
1、这段代码大多数情况下运行正常,但是某些情况下会出问题。什么时候会出现什么问题?如何修正?
public class MyStack {
private List<String> list = new ArrayList<String>(); public synchronized void push(String value) {
synchronized (this) {
list.add(value);
notify();
}
} public synchronized String pop() throws InterruptedException {
synchronized (this) {
if (list.size() <= 0) {
wait();
}
return list.remove(list.size() - 1);
}
}
}
list.remove(list.size() - 1);这句代码有可能引发数组下标越界
原因(答案来源互联网,非本人回答):
假设其中一种情形呵!出问题的情形可能很多,但原理都差不多。下面的标号代表程序时序的先后顺序。
1,初始化时list的值为0,然后线程1调用了pop,于是被wait了,然后释放了锁。
2,线程2调用push,在notify之前有线程3调用pop(记住这时候线程1还没有被唤醒,还在wait住),此时线程3会因为等待锁而挂起,或自旋,反正就是在等待锁可用。
3,然后线程2继续往下执行,notify被执行(但这时候线程1是不会唤醒的,因为锁还在线程2占用),线程2退出push方法,释放内置锁,此时,线程1和线程3都在内置锁等待队列里面。由于synchronized是没法保证线程竞争的公平性,所以线程1和线程3都可能得到锁。
4,假设线程1竞争到了锁,不会出问题,正常去除list值,然后remove,执行完后线程3执行,同样被wait住。
5,假设线程3竞争到了锁,问题来了,线程3会判断到list的size不为0,于是remove,所以list的size就为0了,然后线程 3释放锁,这时候,线程1就得到锁,于是从wait中醒来,继续执行,然后直接调用list的remove,由于list的size=0,那么remove(-1),越界错误就产生了。
改进:
改进1,——最小代码改动,就在remove之前再检查list.size==0
改进2,——去掉push和pop方法内的第二重锁检查,我确实没有发现这个锁会有什么用,反而耗性能。 当然这里还是要有方案1的判断(谢谢一楼提醒)。
改进3,——重新设计,如果是我来设计这么一个生产者,消费者模式。我更愿意用LinkedBlockingQueue,它有take方法阻塞消费者直到队列可用。而且还有offer方法阻塞生产者直到队列可以插入,可以有效的阻止OOM。
2、写一段代码实现银行转帐功能,从转出帐号中扣除转帐金额,给转入帐号增加转帐金额,保证两个操作 要么同时成功,要么同时失败
public interface ITransfer {
/**
* fromAccountId 转出帐号 toAccountId 转入帐号 amount 转帐金额
**/ public void transferInner(String fromAccountId, String toAccountId, BigDecimal amount); /**
* 外部转帐-转出,从转出帐号中扣除转帐金额 fromAccountId 转出帐号 amount 转帐金额
**/
public void transferOut(String fromAccountId, BigDecimal amount); /**
* 外部转帐-转入,给转入帐号增加转帐金额 toAccountId 转入帐号 amount 转帐金额
*/ public void transferIn(String toAccountId, BigDecimal amount);
}
这道题考察对事务的理解。如果转出和转入操作都在同一个应用里面进行,使用数据库的事务特性就可以做到“要么同时成功,要么同时失败”;否则就要用分布式事务的方案来解决,先消化一下这篇文章《分布式系统事务一致性解决方案》。
3、实现统计某一目录下每个文件中出现的字母个数、数字个数、空格个数及行数?
/*文本内容仅限数字,字母,及空格*/
import java.io.*;
class Ex6_5 {
public static void main ( String[] args ) {
String fileName = "C:/Hello.txt" , line;
int i,j,f,k;
try {
BufferedReader in = new BufferedReader(new FileReader( fileName ) );
line = in.readLine(); //读取一行内容
while ( line != null ) {
if(Character.isLetter(line))
i++;
else if(Character.isDigit(line))
j++;
else
f++;
line = in.readLine();
k++
}
in.close();
System.out.println("字母"+i+"数字"+j+"空格"+j+"行数"+k)
}
catch ( IOException iox ) {
System.out.println("Problem reading " + fileName );
}
}
}
4、假如有字符串“6sabcsfs33” ,用最有快速的方法去掉字符“ab3”,不能用java内置字符串方法(indeOf,substring,replaceAll等)
String regx = "[^a|b|3]";
String temp = "6sabcsssfsfs33";
Pattern p = Pattern.compile(regx);
Matcher m = p.matcher(temp);
while (m.find()) {
System.out.print(m.group());
}
Java面试题和解答(三)的更多相关文章
- Java面试题和解答(五)
1.在Java中Executor和Executors的区别? Executor是线程池的顶层接口,它的实现类如下图所示: Executors是一个类,提供了多个静态方法,用于生成不同类型的线程池,如下 ...
- Java面试题集(三)
Jdk与jre的区别? Java运行是环境(jre)是将要执行java程序的java虚拟机. Java开发工具包(jdk)是完整的java软件开发包,包含jre,编译器和其他工具如javaDoc,ja ...
- Java面试题_第三阶段(Spring、MVC、IOC、AOP、DI、MyBatis、SSM、struts2)
1.1 何为Spring Bean容器?Spring Bean容器与Spring IOC 容器有什么不同吗? 答:1)用于创建bean对象,管理bean对象的那个容器. 2)Spring IOC 容器 ...
- Java面试题大全(三)
81.如何设定的weblogic的热启动模式(开发模式)与产品发布模式? 可以在管理控制台中修改对应服务器的启动模式为开发或产品模式之一.或者修改服务的启动文件或者commenv文件,增加set PR ...
- Java面试题精选(三) JSP/Servlet Java面试逻辑题
-- JSP/Servlet Java面试逻辑题 -- 很显然,Servlet/JSP的WEB前端动态制作的重要性比HTML/CSS/JS的价值高很多,但我们都知道他们都是建立在HT ...
- Java面试题之数据库三范式是什么
为了建立冗余较小.结构合理的数据库,设计数据库时必须遵循一定的规则.在关系型数据库中这种规则就称为范式.范式是符合某一种设计要求的总结.要想设计一个结构合理的关系型数据库,必须满足一定的范式. 在实际 ...
- Java面试题和解答(四)
1.JVM什么情况下会GC,GC策略有哪些 当应用程序分配新的对象,GC的代的预算大小已经达到阈值,比如GC的第0代已满:代码主动显式调用System.GC.Collect():其他特殊情况,比如,系 ...
- Java面试题和解答(二)
1.字符流和字节流的区别,使用场景是什么,相关类有哪些 http://blog.csdn.net/zj8692286/article/details/126507312.线程安全的概念,实现线程安全的 ...
- Java面试题和解答(一)
1.说说JVM原理?内存泄露与溢出区别,何时产生内存泄露? JVM原理 :http://www.cnblogs.com/jiayi/archive/2010/06/08/1753863.html 内存 ...
随机推荐
- jsp 安全
一. 身份验证和授权 认证是检验某人真正是他/她自称的那个人的过 程.在一个Servlet/JSP应用程序中,身份验证一般通过 检查用户名密码是否正确.授权是检查该级别的用户是 否具备访问权限.它适 ...
- 如何破解Excel VBA密码
首先,如果文件格式是(.xslm),需要先打开Excel文件,另存为2003版格式(.xls). 然后用普通的文本编辑器(我用的是NotePad++)打开这个文件,注意文件类型选“所有文件”. 然后在 ...
- Tornado之异步authenticated
authenticated是tornado自带的登录验证装饰器,它的实现比较简单,验证比较简易,无法做到真正意义的前后端分离并且是同步的方式,所以这里我对它进行了重写,以适应异步JWT方式的登录验证. ...
- Redis学习笔记二 (BitMap算法分析与BitCount语法)
Redis学习笔记二 一.BitMap是什么 就是通过一个bit位来表示某个元素对应的值或者状态,其中的key就是对应元素本身.我们知道8个bit可以组成一个Byte,所以bitmap本身会极大的节省 ...
- eclipse下启动tomcat访问网址报404错误
问题: 解决步骤 首先检查一遍自己tomcat的相关配置,如果无误,则继续下面的操作 1.打开server视图,双击tomcat进入编辑页面 选择其中的第二个选项,并且修改Server path中的内 ...
- 删除jar包
public class TestDelete { private static List<File> files = new ArrayList(); public static voi ...
- asp.net 页面生命周期事件详细
(1)请求页面:页请求发生在页生命周期开始之前. (2)开始:在开始阶段,将设置页属性,如Request和Response.在此阶段,页还将确定请求是回发请求还是新请求,并设置IsPostBack属性 ...
- HDU 3949 XOR [线性基|高斯消元]
目录 题目链接 题解 代码 题目链接 HDU 3949 XOR 题解 hdu3949XOR 搞死消元找到一组线性无关组 消出对角矩阵后 对于k二进制拆分 对于每列只有有一个1的,显然可以用k的二进制数 ...
- XVIII Open Cup named after E.V. Pankratiev. GP of Romania
A. Balance 不难发现确定第一行第一列后即可确定全部,列不等式单纯形求解线性规划即可. #include<cstdio> #include<algorithm> usi ...
- # Do—Now——团队冲刺博客_总结篇
Do-Now--团队冲刺博客_总结篇 目录 博客链接 作者 1. 第一篇(领航篇) @仇夏 2. 第二篇 @侯泽洋 3. 第三篇 @仇夏 4. 第四篇 @周亚杰 5. 第五篇 @唐才铭 6. 第六篇 ...