java面试常问问题问题

&>&java问题提问
java问题提问
上传大小:2KB
JFrame 中的方法
setVisible();设置窗体是否显示
setTitle;设置窗体标题
setSize;设置窗体大小
setLocation ;设置窗体初始显示的位置
setResizable;设置窗体是否可以改变大小
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE)设置窗体关闭方式,关闭窗体时同时结束程序
JOptionPame
showMessageDialog(mf,&我的信息&);显示一个消息对话框,主要用来提示信息
showConfirmDialog(mf,&我的确认信息,现在要开始游戏吗&);显示一个确认对话框;用户选择后根据返回结果进行判断。
showInputDialog(&请输入你的姓名&);显示的是一个信息输入的对话框,作用是用来保存用户的输入信息
综合评分:0
{%username%}回复{%com_username%}{%time%}\
/*点击出现回复框*/
$(".respond_btn").on("click", function (e) {
$(this).parents(".rightLi").children(".respond_box").show();
e.stopPropagation();
$(".cancel_res").on("click", function (e) {
$(this).parents(".res_b").siblings(".res_area").val("");
$(this).parents(".respond_box").hide();
e.stopPropagation();
/*删除评论*/
$(".del_comment_c").on("click", function (e) {
var id = $(e.target).attr("id");
$.getJSON('/index.php/comment/do_invalid/' + id,
function (data) {
if (data.succ == 1) {
$(e.target).parents(".conLi").remove();
alert(data.msg);
$(".res_btn").click(function (e) {
var parentWrap = $(this).parents(".respond_box"),
q = parentWrap.find(".form1").serializeArray(),
resStr = $.trim(parentWrap.find(".res_area_r").val());
console.log(q);
//var res_area_r = $.trim($(".res_area_r").val());
if (resStr == '') {
$(".res_text").css({color: "red"});
$.post("/index.php/comment/do_comment_reply/", q,
function (data) {
if (data.succ == 1) {
var $target,
evt = e || window.
$target = $(evt.target || evt.srcElement);
var $dd = $target.parents('dd');
var $wrapReply = $dd.find('.respond_box');
console.log($wrapReply);
//var mess = $(".res_area_r").val();
var mess = resS
var str = str.replace(/{%header%}/g, data.header)
.replace(/{%href%}/g, 'http://' + window.location.host + '/user/' + data.username)
.replace(/{%username%}/g, data.username)
.replace(/{%com_username%}/g, data.com_username)
.replace(/{%time%}/g, data.time)
.replace(/{%id%}/g, data.id)
.replace(/{%mess%}/g, mess);
$dd.after(str);
$(".respond_box").hide();
$(".res_area_r").val("");
$(".res_area").val("");
$wrapReply.hide();
alert(data.msg);
}, "json");
/*删除回复*/
$(".rightLi").on("click", '.del_comment_r', function (e) {
var id = $(e.target).attr("id");
$.getJSON('/index.php/comment/do_comment_del/' + id,
function (data) {
if (data.succ == 1) {
$(e.target).parent().parent().parent().parent().parent().remove();
$(e.target).parents('.res_list').remove()
alert(data.msg);
//填充回复
function KeyP(v) {
var parentWrap = $(v).parents(".respond_box");
parentWrap.find(".res_area_r").val($.trim(parentWrap.find(".res_area").val()));
评论共有0条
VIP会员动态
热门资源标签
CSDN下载频道资源及相关规则调整公告V11.10
下载频道用户反馈专区
下载频道积分规则调整V1710.18
spring mvc+mybatis+mysql+maven+bootstrap 整合实现增删查改简单实例.zip
资源所需积分/C币
当前拥有积分
当前拥有C币
输入下载码
为了良好体验,不建议使用迅雷下载
java问题提问
会员到期时间:
剩余下载个数:
剩余积分:0
为了良好体验,不建议使用迅雷下载
积分不足!
资源所需积分/C币
当前拥有积分
您可以选择
程序员的必选
绿色安全资源
资源所需积分/C币
当前拥有积分
当前拥有C币
为了良好体验,不建议使用迅雷下载
资源所需积分/C币
当前拥有积分
当前拥有C币
为了良好体验,不建议使用迅雷下载
资源所需积分/C币
当前拥有积分
当前拥有C币
您的积分不足,将扣除 10 C币
为了良好体验,不建议使用迅雷下载
无法举报自己的资源
你当前的下载分为234。
你还不是VIP会员
开通VIP会员权限,免积分下载
你下载资源过于频繁,请输入验证码
您因违反CSDN下载频道规则而被锁定帐户,如有疑问,请联络:!
若举报审核通过,可返还被扣除的积分
被举报人:
liuxuanjun1993
请选择类型
资源无法下载 ( 404页面、下载失败、资源本身问题)
资源无法使用 (文件损坏、内容缺失、题文不符)
侵犯版权资源 (侵犯公司或个人版权)
虚假资源 (恶意欺诈、刷分资源)
含色情、危害国家安全内容
含广告、木马病毒资源
*投诉人姓名:
*投诉人联系方式:
*版权证明:
*详细原因:
java问题提问面试官就问了一个Java问题,几十号人集体蒙圈?【java吧】_百度贴吧
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&签到排名:今日本吧第个签到,本吧因你更精彩,明天继续来努力!
本吧签到人数:0成为超级会员,使用一键签到本月漏签0次!成为超级会员,赠送8张补签卡连续签到:天&&累计签到:天超级会员单次开通12个月以上,赠送连续签到卡3张
关注:725,083贴子:
面试官就问了一个Java问题,几十号人集体蒙圈?收藏
昨天面试Java,面试官就问了一个问题,几十号人集体蒙圈?有的时候面试官的问题真的层出不穷,今天就又遇到了一个奇葩的问题(你是面试官你说了算)。面试时候,直接给拿出了一个特别“复杂”的异常(虽然代码并不多),但是全部去面试的人直接就蒙圈了。事后我赶紧恶补了一下Java异常方面的所有资料,整理一番,分享给大家,希望大家能够引以为戒。别再犯错。介绍知识点之前,我要先说明一点,大家遇到异常一定要自己动手解决Java的各种异常。一个合格的Java程序员,必须要对Java项目开发中各种常见的问题和各种异常有自己的见解。而且关于Java各种异常的全部说明,在api里都可以查的到。新手遇到这些异常的时候一定要自己动手处理异常,并且快速地记住这些异常的特点和解决方案。如果大家只是一直死写程序,遇到异常也不看重的话,对你未来的发展也不太好。异常类基本就那两种类型:ErrorExceptionJava异常类结构图如果说Error类代表了系统和编译的错误;那Exception类就代表了标准Java库方法所激发的异常。Error类的异常是不允许捕获的,而发生Exception异常的程序可以通过捕获处理后正常运行保持程序的可读性及可靠性。这其中Exception类还包含运行异常类(Runtime_Exception)和非运行异常类(Non_RuntimeException)这两个直接的子类。运行异常类对应于编译错误,它是指Java程序在运行时产生的由解释器引发的各种异常。运行异常可能出现在任何地方,且出现频率很高,出现运行错误往往表示代码有错误,如:算数异常(如被0除)、下标异常(如数组越界)等。非运行异常又称为可检测异常。Java编译器利用分析方法或构造方法中可能产生的结果来检测Java程序中是否含有检测异常的处理程序,对于每个可能的可检测异常,方法或构造方法的throws子句必须列出该异常对应的类。如:java.lang java.util 、 java.net 中定义的异常都是非运行异常。整理的异常在这个链接里面,最后希望我整理的这些东西能给大家带来一点点帮助最后再给大家一个提醒:不要怕异常,困难只是我们成功路上的垫脚石,困难越多,我们就会爬的越高。谁在学习Java过程中都不会是一帆风顺的。
51CTO学院12年行业品牌,1600万用户选择,中国专业IT技能学习平台,java.java资深大牛授课,0基础从入门到精通,java报名与培训中心.
可以的老铁,对我帮助很大的
那么问题来了,spring的默认事务是运行期异常回滚还是非运行期异常回滚?
可以的老铁,对我帮助很大的
收藏了!楼主好人
恕我直言,你的理解很深刻,给的资料也很好
链接点进去还要注册搜狐号啊有没有老哥转载一下啊
看完了没看到面试官问的什么问题
你说错一个地方, error也是可以捕捉的
楼主题目呢
所以面试官到底考了什么问题?
登录百度帐号对于这个系列里的问题,每个学Java的人都应该搞懂。当然,如果只是学Java玩玩就无所谓了。如果你认为自己已经超越初学者了,却不很懂这些问题,请将你自己重归初学者行列。
问题一:我声明了什么!String s = "Hello world!";许多人都做过这样的事情,但是,我们到底声明了什么?回答通常是:一个String,内容是&Hello world!&。这样模糊的回答通常是概念不清的根源。如果要准确的回答,一半的人大概会回答错误。这个语句声明的是一个指向对象的引用,名为&s&,可以指向类型为String的任何对象,目前指向"Hello world!"这个String类型的对象。这就是真正发生的事情。我们并没有声明一个String对象,我们只是声明了一个只能指向String对象的引用变量。所以,如果在刚才那句语句后面,如果再运行一句:String string =我们是声明了另外一个只能指向String对象的引用,名为string,并没有第二个对象产生,string还是指向原来那个对象,也就是,和s指向同一个对象。问题二:"=="和equals方法究竟有什么区别?==操作符专门用来比较变量的值是否相等。比较好理解的一点是:int a=10;int b=10;则a==b将是true。但不好理解的地方是:
String a=new String("foo");
String b=new String("foo");
则a==b将返回false。根据前一帖说过,对象变量其实是一个引用,它们的值是指向对象所在的内存地址,而不是对象本身。a和b都使用了new操作符,意味着将在内存中产生两个内容为"foo"的字符串,既然是&两个&,它们自然位于不同的内存地址。a和b的值其实是两个不同的内存地址的值,所以使用"=="操作符,结果会是false。诚然,a和b所指的对象,它们的内容都是"foo",应该是&相等&,但是==操作符并不涉及到对象内容的比较。对象内容的比较,正是equals方法做的事。看一下Object对象的equals方法是如何实现的:
boolean equals(Object o){
return this==o;
Object对象默认使用了==操作符。所以如果你自创的类没有覆盖equals方法,那你的类使用equals和使用==会得到同样的结果。同样也可以看出,Object的equals方法没有达到equals方法应该达到的目标:比较两个对象内容是否相等。因为答案应该由类的创建者决定,所以Object把这个任务留给了类的创建者。看一下一个极端的类:
Class Monster{
boolean equals(Object another){
我覆盖了equals方法。这个实现会导致无论Monster实例内容如何,它们之间的比较永远返回true。所以当你是用equals方法判断对象的内容是否相等,请不要想当然。因为可能你认为相等,而这个类的作者不这样认为,而类的equals方法的实现是由他掌握的。如果你需要使用equals方法,或者使用任何基于散列码的集合(HashSet,HashMap,HashTable),请察看一下java doc以确认这个类的equals逻辑是如何实现的。问题三:String到底变了没有?没有。因为String被设计成不可变(immutable)类,所以它的所有对象都是不可变对象。请看下列代码:
String s = "Hello";
s = s + " world!";
s所指向的对象是否改变了呢?从本系列第一篇的结论很容易导出这个结论。我们来看看发生了什么事情。在这段代码中,s原先指向一个String对象,内容是"Hello",然后我们对s进行了+操作,那么s所指向的那个对象是否发生了改变呢?答案是没有。这时,s不指向原来那个对象了,而指向了另一个String对象,内容为"Hello world!",原来那个对象还存在于内存之中,只是s这个引用变量不再指向它了。通过上面的说明,我们很容易导出另一个结论,如果经常对字符串进行各种各样的修改,或者说,不可预见的修改,那么使用String来代表字符串的话会引起很大的内存开销。因为String对象建立之后不能再改变,所以对于每一个不同的字符串,都需要一个String对象来表示。这时,应该考虑使用StringBuffer类,它允许修改,而不是每个不同的字符串都要生成一个新的对象。并且,这两种类的对象转换十分容易。同时,我们还可以知道,如果要使用内容相同的字符串,不必每次都new一个String。例如我们要在构造器中对一个名叫s的String引用变量进行初始化,把它设置为初始值,应当这样做:
public class Demo {
public Demo {
s = "Initial Value";
s = new String("Initial Value");
后者每次都会调用构造器,生成新对象,性能低下且内存开销大,并且没有意义,因为String对象不可改变,所以对于内容相同的字符串,只要一个String对象来表示就可以了。也就说,多次调用上面的构造器创建多个对象,他们的String类型属性s都指向同一个对象。上面的结论还基于这样一个事实:对于字符串常量,如果内容相同,Java认为它们代表同一个String对象。而用关键字new调用构造器,总是会创建一个新的对象,无论内容是否相同。至于为什么要把String类设计成不可变类,是它的用途决定的。其实不只String,很多Java标准类库中的类都是不可变的。在开发一个系统的时候,我们有时候也需要设计不可变类,来传递一组相关的值,这也是面向对象思想的体现。不可变类有一些优点,比如因为它的对象是只读的,所以多线程并发访问也不会有任何问题。当然也有一些缺点,比如每个不同的状态都要一个对象来代表,可能会造成性能上的问题。所以Java标准类库还提供了一个可变版本,即StringBuffer。
问题四:final关键字到底修饰了什么?final使得被修饰的变量"不变",但是由于对象型变量的本质是&引用&,使得&不变&也有了两种含义:引用本身的不变,和引用指向的对象不变。引用本身的不变:
final StringBuffer a=new StringBuffer("immutable");
final StringBuffer b=new StringBuffer("not immutable");
a=b;//编译期错误引用指向的对象不变:
final StringBuffer a=new StringBuffer("immutable");
a.append(" broken!"); //编译通过
可见,final只对引用的&值&(也即它所指向的那个对象的内存地址)有效,它迫使引用只能指向初始指向的那个对象,改变它的指向会导致编译期错误。至于它所指向的对象的变化,final是不负责的。这很类似==操作符:==操作符只负责引用的&值&相等,至于这个地址所指向的对象内容是否相等,==操作符是不管的。理解final问题有很重要的含义。许多程序漏洞都基于此----final只能保证引用永远指向固定对象,不能保证那个对象的状态不变。在多线程的操作中,一个对象会被多个线程共享或修改,一个线程对对象无意识的修改可能会导致另一个使用此对象的线程崩溃。一个错误的解决方法就是在此对象新建的时候把它声明为final,意图使得它&永远不变&。其实那是徒劳的。问题五:到底要怎么样初始化!本问题讨论变量的初始化,所以先来看一下Java中有哪些种类的变量。& && &1. 类的属性,或者叫值域。& && &2. 方法里的局部变量。& && &3. 方法的参数对于第一种变量,Java虚拟机会自动进行初始化。如果给出了初始值,则初始化为该初始值。如果没有给出,则把它初始化为该类型变量的默认初始值。int类型变量默认初始值为0float类型变量默认初始值为0.0double类型变量默认初始值为0.0boolean类型变量默认初始值为falsechar类型变量默认初始值为0(ASCII码)long类型变量默认初始值为0所有对象引用类型变量默认初始值为null,即不指向任何对象。注意数组本身也是对象,所以没有初始化的数组引用在自动初始化后其值也是null。对于两种不同的类属性,static属性与instance属性,初始化的时机是不同的。instance属性在创建实例的时候初始化,static属性在类加载,也就是第一次用到这个类的时候初始化,对于后来的实例的创建,不再次进行初始化。这个问题会在以后的系列中进行详细讨论。对于第二种变量,必须明确地进行初始化。如果再没有初始化之前就试图使用它,编译器会抗议。如果初始化的语句在try块中或if块中,也必须要让它在第一次使用前一定能够得到赋值。也就是说,把初始化语句放在只有if块的条件判断语句中编译器也会抗议,因为执行的时候可能不符合if后面的判断条件,如此一来初始化语句就不会被执行了,这就违反了局部变量使用前必须初始化的规定。但如果在else块中也有初始化语句,就可以通过编译,因为无论如何,总有至少一条初始化语句会被执行,不会发生使用前未被初始化的事情。对于try-catch也是一样,如果只有在try块里才有初始化语句,编译部通过。如果在catch或finally里也有,则可以通过编译。总之,要保证局部变量在使用之前一定被初始化了。所以,一个好的做法是在声明他们的时候就初始化他们,如果不知道要出事化成什么值好,就用上面的默认值吧!其实第三种变量和第二种本质上是一样的,都是方法中的局部变量。只不过作为参数,肯定是被初始化过的,传入的值就是初始值,所以不需要初始化。
问题六:instanceof是什么东东?
instanceof是Java的一个二元操作符,和==,&,&是同一类东东。由于它是由字母组成的,所以也是Java的保留关键字。它的作用是测试它左边的对象是否是它右边的类的实例,返回boolean类型的数据。举个例子:
String s = "I AM an Object!";
boolean isObject = s instanceof O
我们声明了一个String对象引用,指向一个String对象,然后用instancof来测试它所指向的对象是否是Object类的一个实例,显然,这是真的,所以返回true,也就是isObject的值为True。
instanceof有一些用处。比如我们写了一个处理账单的系统,其中有这样三个类:
public class Bill {...} //省略细节
public class PhoneBill extends Bill {...} //省略细节
public class GasBill extends Bill {...} //省略细节
在处理程序里有一个方法,接受一个Bill类型的对象,计算金额。假设两种账单计算方法不同,而传入的Bill对象可能是两种中的任何一种,所以要用instanceof来判断:
public double calculate(Bill bill) {
if (bill instanceof PhoneBill) {...}
//计算电话账单
if (bill instanceof GasBill) {...}
//计算燃气账单
这样就可以用一个方法处理两种子类。然而,这种做法通常被认为是没有好好利用面向对象中的多态性。其实上面的功能要求用方法重载完全可以实现,这是面向对象变成应有的做法,避免回到结构化编程模式。只要提供两个名字和返回值都相同,接受参数类型不同的方法就可以了:
public double calculate(PhoneBill bill) {...} //计算电话账单
public double calculate(GasBill bill) {...} //计算燃气账单
所以,使用instanceof在绝大多数情况下并不是推荐的做法,应当好好利用多态。
阅读(...) 评论()Java是目前最流行的编程语言之一&&它可以用来编写Windows程序或者是Web应用,移动应用,网络程序,消费电子产品,机顶盒设备,它无处不在。
有超过30亿的设备是运行在Java之上的。根据Oracle的统计数据,光是使用中的Java Card就有有50亿。
超过900万选择使用Java进行开发,它是最受开发人员欢迎的语言,同时也是最流行的开发平台。
本文为那些准Java程序员们准备了一系列广为流传的Java最佳编程实践
优先返回空集合而非null
如果程序要返回一个不包含任何值的集合,确保返回的是空集合而不是null。这能节省大量的&if else&检查。
public class getLocationName {
return (null==cityName ? "": cityName);
谨慎操作字符串
如果两个字符串在for循环中使用+操作符进行拼接,那么每次循环都会产生一个新的字符串对象。这不仅浪费内存空间同时还会影响性能。类似的,如果初始化字符串对象,尽量不要使用构造方法,而应该直接初始化。比方说:
//Slower Instantiation
String bad = new String("Yet another string object");
//Faster Instantiation
String good = "Yet another string object"
避免无用对象
创建对象是Java中最昂贵的操作之一。因此最好在有需要的时候再进行对象的创建/初始化。如下:
import java.util.ArrayL
import java.util.L
public class Employees {
private List E
public List getEmployees() {
//initialize only when required
if(null == Employees) {
Employees = new ArrayList();
数组与ArrayList之争
开发人员经常会发现很难在数组和ArrayList间做选择。它们二者互有优劣。如何选择应该视情况而定。
import java.util.ArrayL
public class arrayVsArrayList {
public static void main(String[] args) {
int[] myArray = new int[6];
myArray[7]= 10; // ArraysOutOfBoundException
//Declaration of ArrayList. Add and Remove of elements is easy.
ArrayList&Integer& myArrayList = new ArrayList&&();
myArrayList.add(1);
myArrayList.add(2);
myArrayList.add(3);
myArrayList.add(4);
myArrayList.add(5);
myArrayList.remove(0);
for(int i = 0; i & myArrayList.size(); i++) {
System.out.println("Element: " + myArrayList.get(i));
//Multi-dimensional Array
int[][][] multiArray = new int [3][3][3];
数组是定长的,而ArrayList是变长的。由于数组长度是固定的,因此在声明数组时就已经分配好内存了。而数组的操作则会更快一些。另一方面,如果我们不知道数据的大小,那么过多的数据便会导致ArrayOutOfBoundException,而少了又会浪费存储空间。
ArrayList在增删元素方面要比数组简单。
数组可以是多维的,但ArrayList只能是一维的。
try块的finally块没有被执行
看下下面这段代码:
public class shutDownHooksDemo {
public static void main(String[] args) {
for(int i=0;i&5;i++)
if(i==4) {
System.out.println("Inside Try Block.Exiting without executing Finally block.");
System.exit(0);
System.out.println("Inside Finally Block.");
从代码来看,貌似finally块中的println语句应该会被执行5次。但当程序运行后,你会发现finally块只执行了4次。第5次迭代的时候会触发exit函数的调用,于是这第5次的finally便永远也触发不到了。原因便是&&System.exit会挂起所有线程的执行,包括当前线程。即便是try语句后的finally块,只要是执行了exit,便也无力回天了。
在调用System.exit时,JVM会在关闭前执行两个结束任务:
首先,它会执行完所有通过Runtime.addShutdownHook注册进来的终止的钩子程序。这一点很关键,因为它会释放JVM外部的资源。
接下来的便是Finalizer了。可能是System.runFinalizersOnExit也可能是Runtime.runFinalizersOnExit。finalizer的使用已经被废弃有很长一段时间了。finalizer可以在存活对象上进行调用,即便是这些对象仍在被其它线程所使用。而这会导致不可预期的结果甚至是死锁。
public class shutDownHooksDemo {
public static void main(String[] args) {
for(int i=0;i&5;i++)
final int final_i =
Runtime.getRuntime().addShutdownHook(
new Thread() {
public void run() {
if(final_i==4) {
System.out.println("Inside Try Block.Exiting without executing Finally block.");
System.exit(0);
System.out.println("Inside Finally Block.");
看下这几行代码,看看它们是否能用来准确地判断一个数是奇数?
public boolean oddOrNot(int num) {
return num % 2 == 1;
看似是对的,但是每执行四便会有一个错误的结果(用数据说话)。考虑到负奇数的情况,它除以2的结果就不会是1。因此,返回值是false,而这样是不对的。
代码可以修改成这样:
public boolean oddOrNot(int num) {
return (num & 1) != 0;
这么写不光是负奇数的问题解决了,并且还是经过充分优化过的。因为算术运算和逻辑运行要比乘除运算更高效,计算的结果也会更快。
单引号与双引号的区别
public class Haha {
public static void main(String args[]) {
System.out.print("H" + "a");
System.out.print('H' + 'a');
看起来这段代码会返回&Haha&,但实际返回的是Ha169。原因就是用了双引号的时候,字符会被当作字符串处理,而如果是单引号的话,字符值会通过一个叫做基础类型拓宽的操作来转换成整型值。然后再将值相加得到169。
一些防止内存泄露的小技巧
内存泄露会导致软件的性能降级。由于Java是自动管理内存的,因此开发人员并没有太多办法介入。不过还是有一些方法能够用来防止内存泄露的。
查询完数据后立即释放数据库连接
尽可能使用finally块
释放静态变量中的实例
死锁出现的原因有很多。避免死锁不是一句话就能解决的。通常来说,当某个同步对象在等待另一个同步对象所拥有的资源上的锁时,便会产生死锁。
试着运行下下面的程序。它会告诉你什么是死锁。这个死锁是由于两个线程都在等待对方所拥有的资源,因此会产生死锁。它们会一直等待,没有谁会先放手。
public class DeadlockDemo {
public static Object addLock = new Object();
public static Object subLock = new Object();
public static void main(String args[]) {
MyAdditionThread add = new MyAdditionThread();
MySubtractionThread sub = new MySubtractionThread();
add.start();
sub.start();
private static class MyAdditionThread extends Thread {
public void run() {
synchronized (addLock) {
int a = 10, b = 3;
int c = a +
System.out.println("Addition Thread: " + c);
System.out.println("Holding First Lock...");
try { Thread.sleep(10); }
catch (InterruptedException e) {}
System.out.println("Addition Thread: Waiting for AddLock...");
synchronized (subLock) {
System.out.println("Threads: Holding Add and Sub Locks...");
private static class MySubtractionThread extends Thread {
public void run() {
synchronized (subLock) {
int a = 10, b = 3;
int c = a -
System.out.println("Subtraction Thread: " + c);
System.out.println("Holding Second Lock...");
try { Thread.sleep(10); }
catch (InterruptedException e) {}
System.out.println("Subtraction
Thread: Waiting for SubLock...");
synchronized (addLock) {
System.out.println("Threads: Holding Add and Sub Locks...");
Addition Thread: 13
Subtraction Thread: 7
Holding First Lock...
Holding Second Lock...
Addition Thread: Waiting for AddLock...
Subtraction
Thread: Waiting for SubLock...
但如果调用的顺序变一下的话,死锁的问题就解决了。
public class DeadlockSolutionDemo {
public static Object addLock = new Object();
public static Object subLock = new Object();
public static void main(String args[]) {
MyAdditionThread add = new MyAdditionThread();
MySubtractionThread sub = new MySubtractionThread();
add.start();
sub.start();
private static class MyAdditionThread extends Thread {
public void run() {
synchronized (addLock) {
int a = 10, b = 3;
int c = a +
System.out.println("Addition Thread: " + c);
System.out.println("Holding First Lock...");
try { Thread.sleep(10); }
catch (InterruptedException e) {}
System.out.println("Addition Thread: Waiting for AddLock...");
synchronized (subLock) {
System.out.println("Threads: Holding Add and Sub Locks...");
private static class MySubtractionThread extends Thread {
public void run() {
synchronized (addLock) {
int a = 10, b = 3;
int c = a -
System.out.println("Subtraction Thread: " + c);
System.out.println("Holding Second Lock...");
try { Thread.sleep(10); }
catch (InterruptedException e) {}
System.out.println("Subtraction
Thread: Waiting for SubLock...");
synchronized (subLock) {
System.out.println("Threads: Holding Add and Sub Locks...");
Addition Thread: 13
Holding First Lock...
Addition Thread: Waiting for AddLock...
Threads: Holding Add and Sub Locks...
Subtraction Thread: 7
Holding Second Lock...
Subtraction
Thread: Waiting for SubLock...
Threads: Holding Add and Sub Locks...
替Java省点内存
某些Java程序是CPU密集型的,但它们会需要大量的内存。这类程序通常运行得很缓慢,因为它们对内存的需求很大。为了能提升这类应用的性能,可得给它们多留点内存。因此,假设我们有一台拥有10G内存的Tomcat服务器。在这台机器上,我们可以用如下的这条命令来分配内存:
export JAVA_OPTS="$JAVA_OPTS -Xms5000m -Xmx6000m -XX:PermSize=1024m -XX:MaxPermSize=2048m"
Xms = 最小内存分配
Xmx = 最大内存分配
XX:PermSize = JVM启动时的初始大小
XX:MaxPermSize = JVM启动后可分配的最大空间
如何计算Java中操作的耗时
在Java中进行操作计时有两个标准的方法:System.currentTimeMillis()和System.nanoTime()。问题就在于,什么情况下该用哪个。从本质上来讲,他们的作用都是一样的,但有以下几点不同:
System.currentTimeMillis()的精度在千分之一秒到千分之15秒之间(取决于系统)而System.nanoTime()则能到纳秒级。
System.currentTimeMillis读操作耗时在数个CPU时钟左右。而System.nanoTime()则需要上百个。
System.currentTimeMillis对应的是绝对时间(1970年1 月1日所经历的毫秒数),而System.nanoTime()则不与任何时间点相关。
Float还是double
在对精度要求高的场景下,double类型相对float要更流行一些,理由如下:
大多数处理器在处理float和double上所需的时间都是差不多的。而计算时间一样的前提下,double类型却能提供更高的精度。
Java是通过异或操作来进行幂运算的。Java对于幂运算有两种处理方式:
double square = double a *
// Optimized
double cube = double a * double a *
// Non-optimized
double cube = double a *
// Optimized
double quad = double a * double a * double a *
// Non-optimized
double quad = double square *
// Optimized
pow方法:在无法使用乘积的情况下可以使用pow方法。
double cube = Math.pow(base, exponent);
不到万不得已不要使用Math.pow。比方说,当指数是小数的时候。因为Math.pow要比乘积慢300-600倍左右。
如何处理空指针异常
空指针异常是Java中很常见的异常。当你尝试调用一个null对象上的方法时便会抛出这个异常。比如:
int noOfStudents = school.listStudents().
在上述例子中,school为空或者listStudents()为空都可能会抛出了NullPointerException。因此最好检查下对象是否为空以避免类似情况。
private int getListOfStudents(File[] files) {
if (files == null)
throw new NullPointerException("File list cannot be null");
JSON是数据存储及传输的一种协议。与XML相比,它更易于使用。由于它非常轻量级以及自身的一些特性,现在JSON在网络上已经是越来越流行了。常见的数据结构都可以编码成JSON然后在各个网页间自由地传输。不过在开始编码前,你得先安装一个JSON解析器。在下面的例子中,我们将使用json.simple库来完成这项工作 (https://code.google.com/p/json-simple/)。
下面是编码成JSON串的一个简单的例子。
import org.json.simple.JSONO
import org.json.simple.JSONA
public class JsonEncodeDemo {
public static void main(String[] args) {
JSONObject obj = new JSONObject();
obj.put("Novel Name", "Godaan");
obj.put("Author", "Munshi Premchand");
JSONArray novelDetails = new JSONArray();
novelDetails.add("Language: Hindi");
novelDetails.add("Year of Publication: 1936");
novelDetails.add("Publisher: Lokmanya Press");
obj.put("Novel Details", novelDetails);
System.out.print(obj);
{"Novel Name":"Godaan","Novel Details":["Language: Hindi","Year of Publication: 1936","Publisher: Lokmanya Press"],"Author":"Munshi Premchand"}
开发人员要想解析JSON串,首先你得知道它的格式。下面例子有助于你来理解这一点:
import java.io.FileNotFoundE
import java.io.FileR
import java.io.IOE
import java.util.I
import org.json.simple.JSONA
import org.json.simple.JSONO
import org.json.simple.parser.JSONP
import org.json.simple.parser.ParseE
public class JsonParseTest {
private static final String filePath = "//home//user//Documents//jsonDemoFile.json";
public static void main(String[] args) {
// read the json file
FileReader reader = new FileReader(filePath);
JSONParser jsonParser = new JSONParser();
JSONObject jsonObject = (JSONObject)jsonParser.parse(reader);
// get a number from the JSON object
(Long) jsonObject.get("id");
System.out.println("The id is: " + id);
// get a String from the JSON object
type = (String) jsonObject.get("type");
System.out.println("The type is: " + type);
// get a String from the JSON object
name = (String) jsonObject.get("name");
System.out.println("The name is: " + name);
// get a number from the JSON object
Double ppu =
(Double) jsonObject.get("ppu");
System.out.println("The PPU is: " + ppu);
// get an array from the JSON object
System.out.println("Batters:");
JSONArray batterArray= (JSONArray) jsonObject.get("batters");
Iterator i = batterArray.iterator();
// take each value from the json array separately
while (i.hasNext()) {
JSONObject innerObj = (JSONObject) i.next();
System.out.println("ID "+ innerObj.get("id") +
" type " + innerObj.get("type"));
// get an array from the JSON object
System.out.println("Topping:");
JSONArray toppingArray= (JSONArray) jsonObject.get("topping");
Iterator j = toppingArray.iterator();
// take each value from the json array separately
while (j.hasNext()) {
JSONObject innerObj = (JSONObject) j.next();
System.out.println("ID "+ innerObj.get("id") +
" type " + innerObj.get("type"));
} catch (FileNotFoundException ex) {
ex.printStackTrace();
} catch (IOException ex) {
ex.printStackTrace();
} catch (ParseException ex) {
ex.printStackTrace();
} catch (NullPointerException ex) {
ex.printStackTrace();
jsonDemoFile.json
"id": 0001,
"type": "donut",
"name": "Cake",
"ppu": 0.55,
"batters":
{ "id": 1001, "type": "Regular" },
{ "id": 1002, "type": "Chocolate" },
{ "id": 1003, "type": "Blueberry" },
{ "id": 1004, "type": "Devil's Food" }
"topping":
{ "id": 5001, "type": "None" },
{ "id": 5002, "type": "Glazed" },
{ "id": 5005, "type": "Sugar" },
{ "id": 5007, "type": "Powdered Sugar" },
{ "id": 5006, "type": "Chocolate with Sprinkles" },
{ "id": 5003, "type": "Chocolate" },
{ "id": 5004, "type": "Maple" }
The id is: 1
The type is: donut
The name is: Cake
The PPU is: 0.55
ID 1001 type Regular
ID 1002 type Chocolate
ID 1003 type Blueberry
ID 1004 type Devil's Food
ID 5001 type None
ID 5002 type Glazed
ID 5005 type Sugar
ID 5007 type Powdered Sugar
ID 5006 type Chocolate with Sprinkles
ID 5003 type Chocolate
ID 5004 type Maple
简单字符串查找
Java提供了一个库函数叫做indexOf()。这个方法可以用在String对象上,它返回的是要查找的字符串所在的位置序号。如果查找不到则会返回-1。
列出目录下的文件
你可以用下面的代码来列出目录下的文件。这个程序会遍历某个目录下的所有子目录及文件,并存储到一个数组里,然后通过遍历数组来列出所有文件。
import java.io.*;
public class ListContents {
public static void main(String[] args) {
File file = new File("//home//user//Documents/");
String[] files = file.list();
System.out.println("Listing contents of " + file.getPath());
for(int i=0 ; i & files. i++)
System.out.println(files[i]);
一个简单的IO程序
Java提供了FileInputStream以及FileOutputStream类来进行文件的读写操作。FileInputStream的构造方法会接收输入文件的路径作为入参然后创建出一个文件的输入流。同样的,FileOutputStream的构造方法也会接收一个文件路径作为入参然后创建出文件的输出流。在处理完文件之后,一个很重要的操作就是要记得&close&掉这些流。
import java.io.*;
public class myIODemo {
public static void main(String args[]) throws IOException {
FileInputStream in =
FileOutputStream out =
in = new FileInputStream("//home//user//Documents//InputFile.txt");
out = new FileOutputStream("//home//user//Documents//OutputFile.txt");
while((c = in.read()) != -1) {
out.write(c);
} finally {
if(in != null) {
in.close();
if(out != null) {
out.close();
在Java中执行某个shell命令
Java提供了Runtime类来执行shell命令。由于这些是外部的命令,因此异常处理就显得异常重要。在下面的例子中,我们将通过一个简单的例子来演示一下。我们会在shell命令行中打开一个pdf文件。
import java.io.BufferedR
import java.io.InputS
import java.io.InputStreamR
public class ShellCommandExec {
public static void main(String[] args) {
String gnomeOpenCommand = "gnome-open //home//user//Documents//MyDoc.pdf";
Runtime rt = Runtime.getRuntime();
Process processObj = rt.exec(gnomeOpenCommand);
InputStream stdin = processObj.getErrorStream();
InputStreamReader isr = new InputStreamReader(stdin);
BufferedReader br = new BufferedReader(isr);
String myoutput = "";
while ((myoutput=br.readLine()) != null) {
myoutput = myoutput+"/n";
System.out.println(myoutput);
catch (Exception e) {
e.printStackTrace();
正则表达式的结构摘录如下(来源: Oracle官网)
8进制值为0n的字符(0&=n&=7)
8进制值为0mnn的字符(0 &= m &= 3, 0&=n&=7)
16进制值为0xhh的字符
16进制值为0xhhhh的字符
16进制值为0xh&h的字符(Character.MINCODEPOINT &= 0xh&h &= Character.MAXCODEPOINT)
制表符(&/u0009&)
换行符(&/u000A&)
回车(&/u000D&)
分页符(&/u000C&)
警告符(&/u0007&)
ESC(&/u001B&)
abc以外的任意字符
a到z以及A到Z
[a-d[m-p]]
a到d或者m到p[a-dm-p]则是取并集
[a-z&&[def]]
d,e或f(交集)
[a-z&&[^bc]]
a到z但不包括b和c
[a-z&&[^m-p]]
a到z但不包括mp:也就是[a-lq-z]
预定义字符
任意字符,有可能包括换行符
0到9的数字
0到9以外的字符
空格符[ /t/n/x0B/f/r]
非空格符[^/s]
字母[a-zA-Z_0-9]
非字母[^/w]
输入的起始位置
前一个匹配的末尾
输入的结束位置,仅用于最后的结束符
输入的结束位置
import java.util.regex.M
import java.util.regex.P
public class RegexMatches
private static String pattern =
"^[_A-Za-z0-9-]+(//.[_A-Za-z0-9-]+)*@[A-Za-z0-9]+(//.[A-Za-z0-9]+)*(//.[A-Za-z]{2,})$";
private static Pattern mypattern = Pattern.compile(pattern);
public static void main( String args[] ){
String valEmail1 = "";
String invalEmail1 = "....@domain.com";
String invalEmail2 = ".$$%%@domain.com";
String valEmail2 = "test.";
System.out.println("Is Email ID1 valid? "+validateEMailID(valEmail1));
System.out.println("Is Email ID1 valid? "+validateEMailID(invalEmail1));
System.out.println("Is Email ID1 valid? "+validateEMailID(invalEmail2));
System.out.println("Is Email ID1 valid? "+validateEMailID(valEmail2));
public static boolean validateEMailID(String emailID) {
Matcher mtch = mypattern.matcher(emailID);
if(mtch.matches()){
Java Swing的简单示例
有了Java的swing,你便可以编写GUI应用了。Java所提供的javax包中就包含了swing。使用swing来编写GUI程序首先需要继承下JFrame。然后在里面添加Box,然后便可以往里面添加诸如按钮,多选按钮,文本框等控件了。这些Box是放在Container的最外层的。
import java.awt.*;
import javax.swing.*;
public class SwingsDemo extends JFrame
public SwingsDemo()
String path = "//home//user//Documents//images";
Container contentPane = getContentPane();
contentPane.setLayout(new FlowLayout());
Box myHorizontalBox = Box. createHorizontalBox();
Box myVerticleBox = Box. createVerticalBox();
myHorizontalBox.add(new JButton("My Button 1"));
myHorizontalBox.add(new JButton("My Button 2"));
myHorizontalBox.add(new JButton("My Button 3"));
myVerticleBox.add(new JButton(new ImageIcon(path + "//Image1.jpg")));
myVerticleBox.add(new JButton(new ImageIcon(path + "//Image2.jpg")));
myVerticleBox.add(new JButton(new ImageIcon(path + "//Image3.jpg")));
contentPane.add(myHorizontalBox);
contentPane.add(myVerticleBox);
setVisible(true);
public static void main(String args[]) {
new SwingsDemo();
使用Java播放音频
在Java中,播放音频是一个很常见的需求,尤其是在游戏开发里面。
下面这个DEMO演示了如何在Java中播放音频。
import java.io.*;
import java.net.URL;
import javax.sound.sampled.*;
import javax.swing.*;
// To play sound using Clip, the process need to be alive.
// Hence, we use a Swing application.
public class playSoundDemo extends JFrame {
// Constructor
public playSoundDemo() {
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setTitle("Play Sound Demo");
this.setSize(300, 200);
this.setVisible(true);
URL url = this.getClass().getResource("MyAudio.wav");
AudioInputStream audioIn = AudioSystem.getAudioInputStream(url);
Clip clip = AudioSystem.getClip();
clip.open(audioIn);
clip.start();
} catch (UnsupportedAudioFileException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (LineUnavailableException e) {
e.printStackTrace();
public static void main(String[] args) {
new playSoundDemo();
导出PDF文件
将表格导出成pdf也是一个比较常见的需求。通过itextpdf,导出pdf也不是什么难事。
import java.io.FileOutputS
import com.itextpdf.text.D
import com.itextpdf.text.P
import com.itextpdf.text.pdf.PdfPC
import com.itextpdf.text.pdf.PdfPT
import com.itextpdf.text.pdf.PdfW
public class DrawPdf {
public static void main(String[] args) throws Exception {
Document document = new Document();
PdfWriter.getInstance(document, new FileOutputStream("Employee.pdf"));
document.open();
Paragraph para = new Paragraph("Employee Table");
para.setSpacingAfter(20);
document.add(para);
PdfPTable table = new PdfPTable(3);
PdfPCell cell = new PdfPCell(new Paragraph("First Name"));
table.addCell(cell);
table.addCell("Last Name");
table.addCell("Gender");
table.addCell("Ram");
table.addCell("Kumar");
table.addCell("Male");
table.addCell("Lakshmi");
table.addCell("Devi");
table.addCell("Female");
document.add(table);
document.close();
在Java中发送邮件也很简单。你只需装一下Java Mail这个jar包,放到你的类路径里即可。在下面的代码中,我们设置了几个基础属性,然后便可以发送邮件了:
import java.util.*;
import javax.mail.*;
import javax.mail.internet.*;
public class SendEmail
public static void main(String [] args)
String to = "";
String from = "";
String host = "localhost";
Properties properties = System.getProperties();
properties.setProperty("mail.smtp.host", host);
Session session = Session.getDefaultInstance(properties);
MimeMessage message = new MimeMessage(session);
message.setFrom(new InternetAddress(from));
message.addRecipient(Message.RecipientType.TO,new InternetAddress(to));
message.setSubject("My Email Subject");
message.setText("My Message Body");
Transport.send(message);
System.out.println("Sent successfully!");
catch (MessagingException ex) {
ex.printStackTrace();
许多程序都需要精确的时间计量。Java提供了一个System的静态方法来支持这一功能:
currentTimeMillis():返回当前时间自新纪元时间以来的毫秒值,long类型。
long startTime = System.currentTimeMillis();
long estimatedTime = System.currentTimeMillis() - startT
nanoTime():返回系统计时器当前的精确时间,纳秒值,这也是long类型。nanoTime()主要是用于计算相对时间而非绝对时间。
long startTime = System.nanoTime();
long estimatedTime = System.nanoTime() - startT
图片缩放可以通过AffineTransform来完成。首先要生成一个输入图片的图片缓冲,然后通过它来渲染出缩放后的图片。
import java.awt.Graphics2D;
import java.awt.geom.AffineT
import java.awt.image.BufferedI
import java.io.F
import javax.imageio.ImageIO;
public class RescaleImage {
public static void main(String[] args) throws Exception {
BufferedImage imgSource = ImageIO.read(new File("images//Image3.jpg"));
BufferedImage imgDestination = new BufferedImage(100, 100, BufferedImage.TYPE_INT_RGB);
Graphics2D g = imgDestination.createGraphics();
AffineTransform affinetransformation = AffineTransform.getScaleInstance(2, 2);
g.drawRenderedImage(imgSource, affinetransformation);
ImageIO.write(imgDestination, "JPG", new File("outImage.jpg"));
捕获鼠标动作
实现了MouseMotionListner接口后,便可以捕获鼠标事件了。 当鼠标进入到某个特定区域时便会触发MouseMoved事件,你便能捕获到这个移动的动作了。通过一个例子来看下:
import java.awt.event.*;
import javax.swing.*;
public class MouseCaptureDemo extends JFrame implements MouseMotionListener
public JLabel mouseHoverS
public static void main(String args[])
new MouseCaptureDemo();
MouseCaptureDemo()
setSize(500, 500);
setTitle("Frame displaying Coordinates of Mouse Motion");
mouseHoverStatus = new JLabel("No Mouse Hover Detected.", JLabel.CENTER);
add(mouseHoverStatus);
addMouseMotionListener(this);
setVisible(true);
public void mouseMoved(MouseEvent e)
mouseHoverStatus.setText("Mouse Cursor Coordinates =& X:"+e.getX()+" | Y:"+e.getY());
public void mouseDragged(MouseEvent e)
FileOutputStream Vs. FileWriter
在Java中有两种写文件的方式:FileOutputStream与FileWriter。开发人员经常会在它们之间犹豫不决。下面这个例子能帮忙你更好地理解在不同的场景下应该选择何种方案。首先我们来看一下实现:
使用FileOutputStream:
File foutput = new File(file_location_string);
FileOutputStream fos = new FileOutputStream(foutput);
BufferedWriter output = new BufferedWriter(new OutputStreamWriter(fos));
output.write("Buffered Content");
使用FileWriter:
FileWriter fstream = new FileWriter(file_location_string);
BufferedWriter output = new BufferedWriter(fstream);
output.write("Buffered Content");
根据Java的接口规范:
FileOutputStream是用于写入原始字节流比如图片流数据。如果是要写入字符流,则应该考虑使用FileWriter。
这样就很清楚了,写图片应该使用FileOutputStream而写文本则应该选择FileWriter。
集合的使用
Java提供了许多集合类&&比如,Vector,Stack,Hashtable等。所以鼓励开发人员尽可能地使用这些集合类有如下原因:
使用集合使得代码的可重用度更高。
集合类使得代码的结构更良好,更易于理解与维护。
最重要的是这些集合类都经过充分的测试,代码质量很高。
1-50-500规则
在大型软件系统中,代码的可维护性是件很有挑战的工作。新加入的开发人员经常会抱怨这些情况:单片代码(Monolithic Code),意大利面式代码(spaghetti code, 常用于描述捆绑在一起并且低内聚的类和方法)。保持代码的整洁与可维护有一条很简单的规则:
10:包内的类不超过10个
50:方法的代码行数不超过50
500:类的代码行数不超过500
SOLID设计准则
SOLID是Robert Martin提出的一套设计准则的简称。根据他的准则:
一个类应当有仅只有一个任务/职责。执行多个任务的类会让人觉得困惑。
单一职责原则
开发人员应当优先考虑扩展现有的软件功能,而不是是修改它。
里氏替换原则
子类必须能够替换掉他们的父类型
接口隔离原则
和单一职责原则类似,但它特指的是接口层。每个接口都应当只负责一项任务。
依赖反转原则
依赖抽象而不是具体实现。也就是说每个模块都应当通过一个抽象层与其它模块进行解耦。
设计模式能帮助开发人员更好地在软件中应用软件的设计准则。它还为开发人员提供了跨语言的通用平台。设计模式中的标准术语能让开发人员更容易进行沟通。
不要上来就开始写代码。制定计划,准备,编写文档,检查然后再去实现。首先,先把需求记下来。然后去准备设计文档。合理地去假设举证。互相review方案然后进行确认。
使用equals而非==
==是用来比较对象引用的,它会检查两个操作数指向的是不是同一个对象(不是相同的对象,而是同一个对象)。而&equals&则比较的是两个字符串是不是相同(假设是字符串对象)。
只有当确实有必要的时候才使用浮点数。比方说,使用浮点数来表示卢比或者派萨就很容易产生问题&&这种情况应当使用BigDecimal。而浮点数更多地是用于测量。
阅读(...) 评论()

我要回帖

更多关于 提一个java问题 的文章

 

随机推荐