答题时,先答是什么,再答有什么作用和要注意什么(这部分最重要,展现自己的心得)
答案的段落分别,层次分明,条理清晰都非常重要,从这些表面的东西也可以看出一个人的习惯、办事风格、条理等。要讲你做出答案的思路过程,或者说你记住答案的思想都写下来。把答题想着是辩论赛。答题就是给别人讲道理、摆事实。答题不局限于什么格式和形式,就是要将自己的学识展现出来!别因为人家题目本来就模棱两可,你就心里胆怯和没底气了,不敢回答了。你要大胆地指出对方题目很模糊和你的观点,不要把面试官想得有多高,其实他和你就是差不多的,你想想,如果他把你招进去了,你们以后就是同事了,可不是差不多的吗?关于就业薪水,如果你是应届生,那不能要高工资,好比大饼的故事,没有文凭还想拿高工资,就去中关村缺什么补什么吧!少数人基础确实很好,在校期间确实又做过一些项目,那仍然是可以要到相对高的工资的。
1.公司想招什么样的人
2.公司面试会问什么
3.简历怎么写
4怎样达到简历上的标准(培训中心教项目的目的)
3、说说&和&&的区别。&和&&都可以用作逻辑与的运算符,表示逻辑与(and),当运算符两边的表达式的结果都为true时,整个运算结果才为true,否则,只要有一方为false,则结果为false。&&还具有短路的功能,即如果第一个表达式为false,则不再计算第二个表达式,例如,对于if(str!=null&&!str.equals(""))表达式,当str为null时,后面的表达式不会执行,所以不会出现NullPointerException如果将&&改为&,则会抛出NullPointerException异常。If(x==33&++y>0)y会增长,If(x==33&&++y>0)不会增长&还可以用作位运算符,当&操作符两边的表达式不是boolean类型时,&表示按位与操作,我们通常使用0x0f来与一个整数进行&运算,来获取该整数的最低4个bit位,例如,0x31&0x0f的结果为0x01。
备注:这道题先说两者的共同点,再说出&&和&的特殊之处,并列举一些经典的例子来表明自己理解透彻深入、实际经验丰富。
for(inti=0;i<10;i++){for(intj=0;j<10;j++){System.out.println("i="+i+",j="+j);if(j==5)breakok;}}另外,我个人通常并不使用标号这种方式,而是让外层的循环条件表达式的结果可以受到里层循环体代码的控制,例如,要在二维数组中查找到某个数字。intarr[][]={{1,2,3},{4,5,6,7},{9}};booleanfound=false;for(inti=0;i
2<<3,因为将一个数左移n位,就相当于乘以了2的n次方,那么,一个数乘以8只要将其左移3位即可,而位运算cpu直接支持的,效率最高,所以,2乘以8等於几的最效率的方法是2<<3。
inta=Integer.MAX_VALUE;intb=Integer.MAX_VALUE;intsum=a+b;System.out.println("a="+a+",b="+b+",sum="+sum);
先不考虑long类型,由于int的正数范围为2的31次方,表示的最大数值约等于2*1000*1000*1000,也就是20亿的大小,所以,要实现一个一百亿的计算器,我们得自己设计一个类可以用于表示很大的整数,并且提供了与另外一个整数进行加减乘除的功能,大概功能如下:(1)这个类内部有两个成员变量,一个表示符号,另一个用字节数组表示数值的二进制数(2)有一个构造方法,把一个包含有多位数值的字符串转换到内部的符号和字节数组中(3)提供加减乘除的功能
publicclassBigInteger{intsign;byte[]val;publicBiginteger(Stringval){sign=;val=;}publicBigIntegeradd(BigIntegerother){}publicBigIntegersubtract(BigIntegerother){}publicBigIntegermultiply(BigIntegerother){}publicBigIntegerdivide(BigIntegerother){}}
finalStringBuffera=newStringBuffer("immutable");执行如下语句将报告编译期错误:a=newStringBuffer("");但是,执行如下语句则可以通过编译:a.append("broken!");
有人在定义方法的参数时,可能想采用如下形式来阻止方法内部修改传进来的参数对象:
publicvoidmethod(finalStringBufferparam){}实际上,这是办不到的,在该方法内部仍然可以增加如下代码来修改参数对象:param.append("a");
Math类中提供了三个与取整有关的方法:ceil、floor、round,这些方法的作用与它们的英文名称的含义相对应,例如,ceil的英文意义是天花板,该方法就表示向上取整,所以,Math.ceil(11.3)的结果为12,Math.ceil(-11.3)的结果是-11;floor的英文意义是地板,该方法就表示向下取整,所以,Math.floor(11.6)的结果为11,Math.floor(-11.6)的结果是-12;最难掌握的是round方法,它表示"四舍五入",算法为Math.floor(x+0.5),即将原来的数字加上0.5后再向下取整,所以,Math.round(11.5)的结果为12,Math.round(-11.5)的结果为-11。
1.if(username.equals("zxx"){}2.intx=1;returnx==1true:false;
作用域当前类同一package子孙类其他packagepublic√√√√protected√√√×friendly√√××private√×××
备注:只要记住了有4种访问权限,4个访问范围,然后将全选和范围在水平和垂直方向上分别按排从小到大或从大到小的顺序排列,就很容易画出上面的图了。
陈yong,4000一个房子里有椅子,椅子有腿和背,房子与椅子是什么关系,椅子与腿和背是什么关系?如果房子有多个椅子,就是聚合关系,否则是一种关联关系,当然,聚合是一种特殊的关联。椅子与腿和背时组合关系。说说hasa与isa的区别。答:is-a表示的是属于得关系。比如兔子属于一种动物(继承关系)。has-a表示组合,包含关系。比如兔子包含有腿,头等组件;工厂模式的类图
classMyBeanimplementsComparable{publicintcompareTo(Objectobj){if(!objinstanceofMyBean)thrownewClassCastException()//具体异常的名称,我要查jdk文档。MyBeanother=(MyBean)obj;returnage>other.age1:age==other.age0:-1;}}classMyTreeSet{privateArrayListdatas=newArrayList();publicvoidadd(Objectobj){for(inti=0;i
新题目:编程:1.编写一个函数将一个十六进制数的字符串参数转换成整数返回。
Stringstr="13abf";intlen=str.length;intsum=0;for(inti=0;i其实,也可以用Integer.parseInt(str,16),但面试官很可能是想考我们的编码基本功。
intmonthMoney=T/N/12;floatmonthRate=R/12;inttotalMonth=N*12;floattotalRate=0;for(inti=1;i<=totalMonth;i++){totalRate+=monthMoney*monthRate*i;}intresult=monthMoney+totalRate/N/12;
几道题:1.****Spring的DI是什么(学员注:除了IOC,AOP这些概念,还不太清楚DI的概念)2.*任意数字序列"123456"之类,输出它们所有的排列组合3.*****什么是AOP(学员注:会用,但感觉说不清楚)我注:由上面这些题,可以看出,思想很重要,只有琢磨思想和原理的人才能很好地回答这些问题!2题的答案:
抽象:抽象就是找出一些事物的相似和共性之处,然后将这些事物归为一个类,这个类只考虑这些事物的相似和共性之处,并且会忽略与当前主题和目标无关的那些方面,将注意力集中在与当前目标有关的方面。例如,看到一只蚂蚁和大象,你能够想象出它们的相同之处,那就是抽象。抽象包括行为抽象和状态抽象两个方面。例如,定义一个Person类,如下:
classPerson{Stringname;intage;}人本来是很复杂的事物,有很多方面,但因为当前系统只需要了解人的姓名和年龄,所以上面定义的类中只包含姓名和年龄这两个属性,这就是一种抽像,使用抽象可以避免考虑一些与目标无关的细节。我对抽象的理解就是不要用显微镜去看一个事物的所有方面,这样涉及的内容就太多了,而是要善于划分问题的边界,当前系统需要什么,就只考虑什么。
继承:在定义和实现一个类的时候,可以在一个已经存在的类的基础之上来进行,把这个已经存在的类所定义的内容作为自己的内容,并可以加入若干新的内容,或修改原来的方法使之更适合特殊的需要,这就是继承。继承是子类自动共享父类数据和方法的机制,这是类之间的一种关系,提高了软件的可重用性和可扩展性。
多态:多态是指程序中定义的引用变量所指向的具体类型和通过该引用变量发出的方法调用在编程时并不确定,而是在程序运行期间才确定,即一个引用变量倒底会指向哪个类的实例对象,该引用变量发出的方法调用到底是哪个类中实现的方法,必须在由程序运行期间才能决定。因为在程序运行时才确定具体的类,这样,不用修改源程序代码,就可以让引用变量绑定到各种不同的类实现上,从而导致该引用调用的具体方法随之改变,即不修改程序代码就可以改变程序运行时所绑定的具体代码,让程序可以选择多个运行状态,这就是多态性。多态性增强了软件的灵活性和扩展性。例如,下面代码中的UserDao是一个接口,它定义引用变量userDao指向的实例对象由daofactory.getDao()在执行的时候返回,有时候指向的是UserJdbcDao这个实现,有时候指向的是UserHibernateDao这个实现,这样,不用修改源代码,就可以改变userDao指向的具体类实现,从而导致userDao.insertUser()方法调用的具体代码也随之改变,即有时候调用的是UserJdbcDao的insertUser方法,有时候调用的是UserHibernateDao的insertUser方法:
UserDaouserDao=daofactory.getDao();userDao.insertUser(user);
比喻:人吃饭,你看到的是左手,还是右手?
publicabstractclassBaseServletextendsHttpServlet{publicfinalvoidservice(HttpServletRequestrequest,HttpServletResponseresponse)throwsIOExcetion,ServletException{记录访问日志进行权限判断if(具有权限){try{doService(request,response);}catch(Excetpione){记录异常信息}}}protectedabstractvoiddoService(HttpServletRequestrequest,HttpServletResponseresponse)throwsIOExcetion,ServletException;//注意访问权限定义成protected,显得既专业,又严谨,因为它是专门给子类用的}publicclassMyServlet1extendsBaseServlet{protectedvoiddoService(HttpServletRequestrequest,HttpServletResponseresponse)throwsIOExcetion,ServletException{本Servlet只处理的具体业务逻辑代码}}
父类方法中间的某段代码不确定,留给子类干,就用模板方法设计模式。备注:这道题的思路是先从总体解释抽象类和接口的基本概念,然后再比较两者的语法细节,最后再说两者的应用区别。比较两者语法细节区别的条理是:先从一个类中的构造方法、普通成员变量和方法(包括抽象方法),静态变量和方法,继承性等6个方面逐一去比较回答,接着从第三者继承的角度的回答,特别是最后用了一个典型的例子来展现自己深厚的技术功底。
publicclassOuter{intout_x=0;publicvoidmethod(){Inner1inner1=newInner1();publicclassInner2//在方法体内部定义的内部类{publicmethod(){out_x=3;}}Inner2inner2=newInner2();}publicclassInner1//在方法体外面定义的内部类{}}
在方法体外面定义的内部类的访问类型可以是public,protecte,默认的,private等4种类型,这就好像类中定义的成员变量有4种访问类型一样,它们决定这个内部类的定义对其他类是否可见;对于这种情况,我们也可以在外面创建内部类的实例对象,创建内部类的实例对象时,一定要先创建外部类的实例对象,然后用这个外部类的实例对象去创建内部类的实例对象,代码如下:Outerouter=newOuter();Outer.Inner1inner1=outer.newInnner1();
在方法内部定义的内部类前面不能有访问类型修饰符,就好像方法中定义的局部变量一样,但这种内部类的前面可以使用final或abstract修饰符。这种内部类对其他类是不可见的其他类无法引用这种内部类,但是这种内部类创建的实例对象可以传递给其他类访问。这种内部类必须是先定义,后使用,即内部类的定义代码必须出现在使用该类之前,这与方法中的局部变量必须先定义后使用的道理也是一样的。这种内部类可以访问方法体中的局部变量,但是,该局部变量前必须加final修饰符。对于这些细节,只要在eclipse写代码试试,根据开发工具提示的各类错误信息就可以马上了解到。
在方法体内部还可以采用如下语法来创建一种匿名内部类,即定义某一接口或类的子类的同时,还创建了该子类的实例对象,无需为该子类定义名称:
publicclassOuter{publicvoidstart(){newThread(newRunable(){publicvoidrun(){};}).start();}}
备注:首先根据你的印象说出你对内部类的总体方面的特点:例如,在两个地方可以定义,可以访问外部类的成员变量,不能定义静态成员,这是大的特点。然后再说一些细节方面的知识,例如,几种定义方式的语法区别,静态内部类,以及匿名内部类。
classOuter{staticintx;staticclassInner{voidtest(){syso(x);}}}
答题时,也要能察言观色,揣摩提问者的心思,显然人家希望你说的是静态内部类不能访问外部类的成员,但你一上来就顶牛,这不好,要先顺着人家,让人家满意,然后再说特殊情况,让人家吃惊。
importjava.util.Date;publicclassTestextendsDate{publicstaticvoidmain(String[]args){newTest().test();}publicvoidtest(){System.out.println(super.getClass().getName());}}
很奇怪,结果是Test这属于脑筋急转弯的题目,在一个qq群有个网友正好问过这个问题,我觉得挺有趣,就研究了一下,没想到今天还被你面到了,哈哈。在test方法中,直接调用getClass().getName()方法,返回的是Test类名由于getClass()在Object类中定义成了final,子类不能覆盖该方法,所以,在test方法中调用getClass().getName()方法,其实就是在调用从父类继承的getClass()方法,等效于调用super.getClass().getName()方法,所以,super.getClass().getName()方法返回的也应该是Test。如果想得到父类的名称,应该用如下代码:getClass().getSuperClass().getName();
111、Strings="Hello";s=s+"world!";这两行代码执行后,原始的String对象中的内容到底变了没有?
没有。因为String被设计成不可变(immutable)类,所以它的所有对象都是不可变对象。在这段代码中,s原先指向一个String对象,内容是"Hello",然后我们对s进行了+操作,那么s所指向的那个对象是否发生了改变呢?答案是没有。这时,s不指向原来那个对象了,而指向了另一个String对象,内容为"Helloworld!",原来那个对象还存在于内存之中,只是s这个引用变量不再指向它了。通过上面的说明,我们很容易导出另一个结论,如果经常对字符串进行各种各样的修改,或者说,不可预见的修改,那么使用String来代表字符串的话会引起很大的内存开销。因为String对象建立之后不能再改变,所以对于每一个不同的字符串,都需要一个String对象来表示。这时,应该考虑使用StringBuffer类,它允许修改,而不是每个不同的字符串都要生成一个新的对象。并且,这两种类的对象转换十分容易。同时,我们还可以知道,如果要使用内容相同的字符串,不必每次都new一个String。例如我们要在构造器中对一个名叫s的String引用变量进行初始化,把它设置为初始值,应当这样做:
随即题目
接着要举一个具体的例子来说明,我们要把1到100的所有数字拼起来,组成一个串。
String覆盖了equals方法和hashCode方法,而StringBuffer没有覆盖equals方法和hashCode方法,所以,将StringBuffer对象存储进Java集合类中时会出现问题。
String[]result=orgStr.split(",");2.用StingTokenizer,代码为:
StringTokenizertokener=StringTokenizer(orgStr,",");String[]result=newString[tokener.countTokens()];Inti=0;while(tokener.hasNext(){result[i++]=toker.nextToken();}
答:对于如下代码:Strings1="a";Strings2=s1+"b";Strings3="a"+"b";System.out.println(s2=="ab");System.out.println(s3=="ab");第一条语句打印的结果为false,第二条语句打印的结果为true,这说明javac编译可以对字符串常量直接相加的表达式进行优化,不必要等到运行期去进行加法运算处理,而是在编译时去掉其中的加号,直接将其编译成一个这些常量相连的结果。题目中的第一行代码被编译器在编译时优化后,相当于直接定义了一个"abcd"的字符串,所以,上面的代码应该只创建了一个String对象。写如下两行代码,Strings="a"+"b"+"c"+"d";System.out.println(s=="abcd");最终打印的结果应该为true。
publicclassTest{/***@paramargsaddbyzxx,Dec9,2008*/publicstaticvoidmain(String[]args){//TODOAuto-generatedmethodstubSystem.out.println(newTest().test());;}staticinttest(){intx=1;try{returnx;}finally{++x;}}}
---------执行结果---------1
运行结果是1,为什么呢?主函数调用子函数并得到结果的过程,好比主函数准备一个空罐子,当子函数要返回结果时,先把结果放在罐子里,然后再将程序逻辑返回到主函数。所谓返回,就是子函数说,我不运行了,你主函数继续运行吧,这没什么结果可言,结果是在说这话之前放进罐子里的。7、下面的程序代码输出的结果是多少?
publicclasssmallT{publicstaticvoidmain(Stringargs[]){smallTt=newsmallT();intb=t.get();System.out.println(b);}publicintget(){try{return1;}finally{return2;}}}
返回的结果是2。我可以通过下面一个例子程序来帮助我解释这个答案,从下面例子的运行结果中可以发现,try中的return语句调用的函数先于finally中调用的函数执行,也就是说return语句先执行,finally语句后执行,所以,返回的结果是2。Return并不是让函数马上返回,而是return语句执行后,将把返回结果放置进函数栈中,此时函数并不是马上返回,它要执行finally语句后才真正开始返回。在讲解答案时可以用下面的程序来帮助分析:
publicclassTest{/***@paramargsaddbyzxx,Dec9,2008*/publicstaticvoidmain(String[]args){//TODOAuto-generatedmethodstubSystem.out.println(newTest().test());;}inttest(){try{returnfunc1();}finally{returnfunc2();}}intfunc1(){System.out.println("func1");return1;}intfunc2(){System.out.println("func2");return2;}}
-----------执行结果-----------------
func1func22
结论:finally中的代码比return和break语句后执行
finally是异常处理语句结构的一部分,表示总是执行。
finalize是Object类的一个方法,在垃圾收集器执行的时候会调用被回收对象的此方法,可以覆盖此方法提供垃圾收集时的其他资源回收,例如关闭文件等。JVM不保证此方法总被调用
提示答题者:就按照三个级别去思考:虚拟机必须宕机的错误,程序可以死掉也可以不死掉的错误,程序不应该死掉的错误;
newThread(newRunnable(){publicvoidrun(){}}).start();从java5开始,还有如下一些线程池创建多线程的方式:ExecutorServicepool=Executors.newFixedThreadPool(3)for(inti=0;i<10;i++){pool.execute(newRunable(){publicvoidrun(){}});}Executors.newCachedThreadPool().execute(newRunable(){publicvoidrun(){}});Executors.newSingleThreadExecutor().execute(newRunable(){publicvoidrun(){}});
有两种实现方法,分别使用newThread()和newThread(runnable)形式,第一种直接调用thread的run方法,所以,我们往往使用Thread子类,即newSubThread()。第二种调用runnable的run方法。
有两种实现方法,分别是继承Thread类与实现Runnable接口用synchronized关键字修饰同步方法反对使用stop(),是因为它不安全。它会解除由线程获取的所有锁定,而且如果对象处于一种不连贯状态,那么其他线程能在那种状态下检查和修改它们。结果很难检查出真正的问题所在。suspend()方法容易发生死锁。调用suspend()的时候,目标线程会停下来,但却仍然持有在这之前获得的锁定。此时,其他任何线程都不能访问锁定的资源,除非被"挂起"的线程恢复运行。对任何线程来说,如果它们想恢复目标线程,同时又试图使用任何一个锁定的资源,就会造成死锁。所以不应该使用suspend(),而应在自己的Thread类中置入一个标志,指出线程应该活动还是挂起。若标志指出线程应该挂起,便用wait()命其进入等待状态。若标志指出线程应当恢复,则用一个notify()重新启动线程。
//由于notify方法并不释放锁,即使thread2调用下面的sleep方法休息了10毫秒,但thread1仍然不会执行,因为thread2没有释放锁,所以Thread1无法得不到锁。
MultiThread.class.notify();System.out.println("thread2issleepingtenmillisecond...");try{Thread.sleep(10);}catch(InterruptedExceptione){//TODOAuto-generatedcatchblocke.printStackTrace();}System.out.println("thread2isgoingon...");System.out.println("thread2isbeingover!");}}}}
classTest{synchronizedstaticvoidsayHello3(){}synchronizedvoidgetX(){}}56、多线程有几种实现方法同步有几种实现方法多线程有两种实现方法,分别是继承Thread类与实现Runnable接口同步的实现方面有两种,分别是synchronized,wait与notifywait():使一个线程处于等待状态,并且释放所持有的对象的lock。sleep():使一个正在运行的线程处于睡眠状态,是一个静态方法,调用此方法要捕捉InterruptedException异常。notify():唤醒一个处于等待状态的线程,注意的是在调用此方法的时候,并不能确切的唤醒某一个等待状态的线程,而是由JVM确定唤醒哪个线程,而且不是按优先级。Allnotity():唤醒所有处入等待状态的线程,注意并不是给所有唤醒线程一个对象的锁,而是让它们竞争。
状态:就绪,运行,synchronize阻塞,wait和sleep挂起,结束。wait必须在synchronized内部调用。调用线程的start方法后线程进入就绪状态,线程调度系统将就绪状态的线程转为运行状态,遇到synchronized语句时,由运行状态转为阻塞,当synchronized获得锁后,由阻塞转为运行,在这种情况可以调用wait方法转为挂起状态,当线程关联的代码执行完后,线程变为结束状态。
packagecom.huawei.interview;importjava.util.concurrent.locks.Lock;importjava.util.concurrent.locks.ReentrantLock;publicclassThreadTest{/***@paramargs*/privateintj;privateLocklock=newReentrantLock();publicstaticvoidmain(String[]args){//TODOAuto-generatedmethodstubThreadTesttt=newThreadTest();for(inti=0;i<2;i++){newThread(tt.newAdder()).start();newThread(tt.newSubtractor()).start();}}privateclassSubtractorimplementsRunnable{@Overridepublicvoidrun(){//TODOAuto-generatedmethodstubwhile(true){/*synchronized(ThreadTest.this){System.out.println("j--="+j--);//这里抛异常了,锁能释放吗?}*/lock.lock();try{System.out.println("j--="+j--);}finally{lock.unlock();}}}}privateclassAdderimplementsRunnable{@Overridepublicvoidrun(){//TODOAuto-generatedmethodstubwhile(true){/*synchronized(ThreadTest.this){System.out.println("j++="+j++);}*/lock.lock();try{System.out.println("j++="+j++);}finally{lock.unlock();}}}}}
publicclassThreadTest1{privateintj;publicstaticvoidmain(Stringargs[]){ThreadTest1tt=newThreadTest1();Incinc=tt.newInc();Decdec=tt.newDec();for(inti=0;i<2;i++){Threadt=newThread(inc);t.start();t=newThread(dec);t.start();}}privatesynchronizedvoidinc(){j++;System.out.println(Thread.currentThread().getName()+"-inc:"+j);}privatesynchronizedvoiddec(){j--;System.out.println(Thread.currentThread().getName()+"-dec:"+j);}classIncimplementsRunnable{publicvoidrun(){for(inti=0;i<100;i++){inc();}}}classDecimplementsRunnable{publicvoidrun(){for(inti=0;i<100;i++){dec();}}}}
----------随手再写的一个-------------
classA{JMangerj=newJManager();main(){newA().call();}voidcall{for(inti=0;i<2;i++){newThread(newRunnable(){publicvoidrun(){while(true){j.accumulate()}}}).start();newThread(newRunnable(){publicvoidrun(){while(true){j.sub()}}}).start();}}}classJManager{privatej=0;publicsynchronizedvoidsubtract(){j--}publicsynchronizedvoidaccumulate(){j++;}}
最终的程序代码如下:
publicclassThreadTest{/***@paramargs*/publicstaticvoidmain(String[]args){//TODOAuto-generatedmethodstubnewThreadTest().init();}publicvoidinit(){finalBusinessbusiness=newBusiness();newThread(newRunnable(){publicvoidrun(){for(inti=0;i<50;i++){business.SubThread(i);}}}).start();for(inti=0;i<50;i++){business.MainThread(i);}}privateclassBusiness{booleanbShouldSub=true;//这里相当于定义了控制该谁执行的一个信号灯publicsynchronizedvoidMainThread(inti){if(bShouldSub)try{this.wait();}catch(InterruptedExceptione){//TODOAuto-generatedcatchblocke.printStackTrace();}for(intj=0;j<5;j++){System.out.println(Thread.currentThread().getName()+":i="+i+",j="+j);}bShouldSub=true;this.notify();}publicsynchronizedvoidSubThread(inti){if(!bShouldSub)try{this.wait();}catch(InterruptedExceptione){//TODOAuto-generatedcatchblocke.printStackTrace();}for(intj=0;j<10;j++){System.out.println(Thread.currentThread().getName()+":i="+i+",j="+j);}bShouldSub=false;this.notify();}}}
备注:不可能一上来就写出上面的完整代码,最初写出来的代码如下,问题在于两个线程的代码要参照同一个变量,即这两个线程的代码要共享数据,所以,把这两个线程的执行代码搬到同一个类中去:
packagecom.huawei.interview.lym;publicclassThreadTest{privatestaticbooleanbShouldMain=false;publicstaticvoidmain(String[]args){//TODOAuto-generatedmethodstub/*newThread(){publicvoidrun(){for(inti=0;i<50;i++){for(intj=0;j<10;j++){System.out.println("i="+i+",j="+j);}}}}.start();*///finalStringstr=newString("");newThread(newRunnable(){publicvoidrun(){for(inti=0;i<50;i++){synchronized(ThreadTest.class){if(bShouldMain){try{ThreadTest.class.wait();}catch(InterruptedExceptione){e.printStackTrace();}}for(intj=0;j<10;j++){System.out.println(Thread.currentThread().getName()+"i="+i+",j="+j);}bShouldMain=true;ThreadTest.class.notify();}}}}).start();for(inti=0;i<50;i++){synchronized(ThreadTest.class){if(!bShouldMain){try{ThreadTest.class.wait();}catch(InterruptedExceptione){e.printStackTrace();}}for(intj=0;j<5;j++){System.out.println(Thread.currentThread().getName()+"i="+i+",j="+j);}bShouldMain=false;ThreadTest.class.notify();}}}}
下面使用jdk5中的并发库来实现的:
3、Collection框架中实现比较要实现什么接口comparable/comparator3、ArrayList和Vector的区别答:这两个类都实现了List接口(List接口继承了Collection接口),他们都是有序集合,即存储在这两个集合中的元素的位置都是有顺序的,相当于一种动态的数组,我们以后可以按位置索引号取出某个元素,,并且其中的数据是允许重复的,这是HashSet之类的集合的最大不同处,HashSet之类的集合不可以按索引号去检索其中的元素,也不允许有重复的元素(本来题目问的与hashset没有任何关系,但为了说清楚ArrayList与Vector的功能,我们使用对比方式,更有利于说明问题)。
接着才说ArrayList与Vector的区别,这主要包括两个方面:.(1)同步性:Vector是线程安全的,也就是说是它的方法之间是线程同步的,而ArrayList是线程序不安全的,它的方法之间是线程不同步的。如果只有一个线程会访问到集合,那最好是使用ArrayList,因为它不考虑线程安全,效率会高些;如果有多个线程会访问到集合,那最好是使用Vector,因为不需要我们自己再去考虑和编写线程安全的代码。
备注:对于Vector&ArrayList、Hashtable&HashMap,要记住线程安全的问题,记住Vector与Hashtable是旧的,是java一诞生就提供了的,它们是线程安全的,ArrayList与HashMap是java2时才提供的,它们是线程不安全的。所以,我们讲课时先讲老的。(2)数据增长:ArrayList与Vector都有一个初始的容量大小,当存储进它们里面的元素的个数超过了容量时,就需要增加ArrayList与Vector的存储空间,每次要增加存储空间时,不是只增加一个存储单元,而是增加多个存储单元,每次增加的存储单元的个数在内存空间利用与程序效率之间要取得一定的平衡。Vector默认增长为原来两倍,而ArrayList的增长策略在文档中没有明确规定(从源代码看到的是增长为原来的1.5倍)。ArrayList与Vector都可以设置初始的空间大小,Vector还可以设置增长的空间大小,而ArrayList没有提供设置增长空间的方法。总结:即Vector增长原来的一倍,ArrayList增加原来的0.5倍。
就HashMap与HashTable主要从三方面来说。一.历史原因:Hashtable是基于陈旧的Dictionary类的,HashMap是Java1.2引进的Map接口的一个实现二.同步性:Hashtable是线程安全的,也就是说是同步的,而HashMap是线程序不安全的,不是同步的三.值:只有HashMap可以让你将空值作为一个表的条目的key或value
List以特定次序来持有元素,可有重复元素。Set无法拥有重复元素,内部排序。Map保存key-value值,value可多值。
HashSet按照hashcode值的某种运算方式进行存储,而不是直接按hashCode值的大小进行存储。例如,"abc"--->78,"def"--->62,"xyz"--->65在hashSet中的存储顺序不是62,65,78,这些问题感谢以前一个叫崔健的学员提出,最后通过查看源代码给他解释清楚,看本次培训学员当中有多少能看懂源码。LinkedHashSet按插入的顺序存储,那被存储对象的hashcode方法还有什么作用呢?学员想想!hashset集合比较两个对象是否相等,首先看hashcode方法是否相等,然后看equals方法是否相等。new两个Student插入到HashSet中,看HashSet的size,实现hashcode和equals方法后再看size。
同一个对象可以在Vector中加入多次。往集合里面加元素,相当于集合里用一根绳子连接到了目标对象。往HashSet中却加不了多次的。
LinkedList也是线程不安全的,LinkedList提供了一些方法,使得LinkedList可以被当作堆栈和队列来使用。4、去掉一个Vector集合中重复的元素
VectornewVector=newVector();For(inti=0;i还有一种简单的方式,HashSetset=newHashSet(vector);9、Collection和Collections的区别。Collection是集合类的上级接口,继承与他的接口主要有Set和List.Collections是针对集合类的一个帮助类,他提供一系列静态方法实现对各种集合的搜索、排序、线程安全化等操作。39、Set里的元素是不能重复的,那么用什么方法来区分重复与否呢是用==还是equals()它们有何区别Set里的元素是不能重复的,元素重复与否是使用equals()方法进行判断的。equals()和==方法决定引用值是否指向同一对象equals()在类中被覆盖,为的是当两个分离的对象的内容和类型相配的话,返回真值。
ArrayList/VectorListCollectionHashSet/TreeSetSetPropetiesHashTableMapTreemap/HashMap
我记的不是方法名,而是思想,我知道它们都有增删改查的方法,但这些方法的具体名称,我记得不是很清楚,对于set,大概的方法是add,remove,contains;对于map,大概的方法就是put,remove,contains等,因为,我只要在eclispe下按点操作符,很自然的这些方法就出来了。我记住的一些思想就是List类会有get(intindex)这样的方法,因为它可以按顺序取元素,而set类中没有get(intindex)这样的方法。List和set都可以迭代出所有元素,迭代时先要得到一个iterator对象,所以,set和list类都有一个iterator方法,用于返回那个iterator对象。map可以返回三个集合,一个是返回所有的key的集合,另外一个返回的是所有value的集合,再一个返回的key和value组合成的EntrySet对象的集合,map也有get方法,参数是key,返回值是key对应的value。
publicclassParentimplementsComparable{privateintage=0;publicParent(intage){this.age=age;}publicintcompareTo(Objecto){//TODOAuto-generatedmethodstubSystem.out.println("methodofparent");Parento1=(Parent)o;returnage>o1.age1:age
112、说出一些常用的类,包,接口,请各举5个要让人家感觉你对javaee开发很熟,所以,不能仅仅只列corejava中的那些东西,要多列你在做ssh项目中涉及的那些东西。就写你最近写的那些程序中涉及的那些类。
常用的类:BufferedReaderBufferedWriterFileReaderFileWirterStringIntegerjava.util.Date,System,Class,List,HashMap
讲解字节流与字符流关系的代码案例:
importjava.io.BufferedReader;importjava.io.FileInputStream;importjava.io.FileOutputStream;importjava.io.FileReader;importjava.io.FileWriter;importjava.io.InputStreamReader;importjava.io.PrintWriter;publicclassIOTest{publicstaticvoidmain(String[]args)throwsException{Stringstr="中国人";/*FileOutputStreamfos=newFileOutputStream("1.txt");fos.write(str.getBytes("UTF-8"));fos.close();*//*FileWriterfw=newFileWriter("1.txt");fw.write(str);fw.close();*/PrintWriterpw=newPrintWriter("1.txt","utf-8");pw.write(str);pw.close();/*FileReaderfr=newFileReader("1.txt");char[]buf=newchar[1024];intlen=fr.read(buf);StringmyStr=newString(buf,0,len);System.out.println(myStr);*//*FileInputStreamfr=newFileInputStream("1.txt");byte[]buf=newbyte[1024];intlen=fr.read(buf);StringmyStr=newString(buf,0,len,"UTF-8");System.out.println(myStr);*/BufferedReaderbr=newBufferedReader(newInputStreamReader(newFileInputStream("1.txt"),"UTF-8"));StringmyStr=br.readLine();br.close();System.out.println(myStr);}}
105、什么是java序列化,如何实现java序列化?或者请解释Serializable接口的作用。
我们有时候将一个java对象变成字节流的形式传出去或者从一个字节流中恢复成一个java对象,例如,要将java对象存储到硬盘或者传送给网络上的其他计算机,这个过程我们可以自己写代码去把一个java对象变成某个格式的字节流再传输,但是,jre本身就提供了这种支持,我们可以调用OutputStream的writeObject方法来做,如果要让java帮我们做,要被传输的对象必须实现serializable接口,这样,javac编译时就会进行特殊处理,编译的类才可以被writeObject方法操作,这就是所谓的序列化。需要被序列化的类必须实现Serializable接口,该接口是一个mini接口,其中没有需要实现的方法,implementsSerializable只是为了标注该对象是可被序列化的。
例如,在web开发中,如果对象被保存在了Session中,tomcat在重启时要把Session对象序列化到硬盘,这个对象就必须实现Serializable接口。如果对象要经过分布式系统进行网络传输或通过rmi等远程调用,这就需要在网络上传输对象,被传输的对象就必须实现Serializable接口。
54、描述一下JVM加载class文件的原理机制JVM中类的装载是由ClassLoader和它的子类来实现的,JavaClassLoader是一个重要的Java运行时系统组件。它负责在运行时查找和装入类文件的类。
18、heap和stack有什么区别。java的内存分为两类,一类是栈内存,一类是堆内存。栈内存是指程序进入一个方法时,会为这个方法单独分配一块私属存储空间,用于存储这个方法内部的局部变量,当这个方法结束时,分配给这个方法的栈会释放,这个栈中的变量也将随之释放。堆是与栈作用不同的内存,一般用于存放不放在当前方法栈中的那些数据,例如,使用new创建的对象都放在堆里,所以,它不会随方法的结束而消失。方法中的局部变量使用final修饰后,放在堆中,而不是栈中。
24、GC是什么为什么要有GCGC是垃圾收集的意思(GabageCollection),内存处理是编程人员容易出现问题的地方,忘记或者错误的内存回收会导致程序或系统的不稳定甚至崩溃,Java提供的GC功能可以自动监测对象是否超过作用域从而达到自动回收内存的目的,Java语言没有提供释放已分配内存的显示操作方法。
103、垃圾回收器的基本原理是什么?垃圾回收器可以马上回收内存吗?有什么办法主动通知虚拟机进行垃圾回收?对于GC来说,当程序员创建对象时,GC就开始监控这个对象的地址、大小以及使用情况。通常,GC采用有向图的方式记录和管理堆(heap)中的所有对象。通过这种方式确定哪些对象是"可达的",哪些对象是"不可达的"。当GC确定一些对象为"不可达"时,GC就有责任回收这些内存空间。可以。程序员可以手动执行System.gc(),通知GC运行,但是Java语言规范并不保证GC一定会执行。
23、什么时候用assert。assertion(断言)在软件开发中是一种常用的调试方式,很多开发语言中都支持这种机制。在实现中,assertion就是在程序中的一条语句,它对一个boolean表达式进行检查,一个正确程序必须保证这个boolean表达式的值为true;如果该值为false,说明程序已经处于不正确的状态下,assert将给出警告或退出。一般来说,assertion用于保证程序最基本、关键的正确性。assertion检查通常在开发和测试时开启。为了提高性能,在软件发布后,assertion检查通常是关闭的。
packagecom.huawei.interview;publicclassAssertTest{/***@paramargs*/publicstaticvoidmain(String[]args){//TODOAuto-generatedmethodstubinti=0;for(i=0;i<5;i++){System.out.println(i);}//假设程序不小心多了一句--i;--i;asserti==5;}}
101、java中会存在内存泄漏吗,请简单描述。所谓内存泄露就是指一个不再被程序使用的对象或变量一直被占据在内存中。java中有垃圾回收机制,它可以保证一对象不再被引用的时候,即对象编程了孤儿的时候,对象将自动被垃圾回收器从内存中清除掉。由于Java使用有向图的方式进行垃圾回收管理,可以消除引用循环的问题,例如有两个对象,相互引用,只要它们和根进程不可达的,那么GC也是可以回收它们的,例如下面的代码可以看到这种情况的内存回收:
packagecom.huawei.interview;importjava.io.IOException;publicclassGarbageTest{/***@paramargs*@throwsIOException*/publicstaticvoidmain(String[]args)throwsIOException{//TODOAuto-generatedmethodstubtry{gcTest();}catch(IOExceptione){//TODOAuto-generatedcatchblocke.printStackTrace();}System.out.println("hasexitedgcTest!");System.in.read();System.in.read();System.out.println("outbegingc!");for(inti=0;i<100;i++){System.gc();System.in.read();System.in.read();}}privatestaticvoidgcTest()throwsIOException{System.in.read();System.in.read();Personp1=newPerson();System.in.read();System.in.read();Personp2=newPerson();p1.setMate(p2);p2.setMate(p1);System.out.println("beforeexitgctest!");System.in.read();System.in.read();System.gc();System.out.println("exitgctest!");}privatestaticclassPerson{byte[]data=newbyte[20000000];Personmate=null;publicvoidsetMate(Personother){mate=other;}}}
java中的内存泄露的情况:长生命周期的对象持有短生命周期对象的引用就很可能发生内存泄露,尽管短生命周期对象已经不再需要,但是因为长生命周期对象持有它的引用而导致不能被回收,这就是java中内存泄露的发生场景,通俗地说,就是程序员可能创建了一个对象,以后一直不再使用这个对象,这个对象却一直被引用,即这个对象无用但是却无法被垃圾回收器回收的,这就是java中可能出现内存泄露的情况,例如,缓存系统,我们加载了一个对象放在缓存中(例如放在一个全局map对象中),然后一直不再使用它,这个对象一直被缓存引用,但却不再被使用。检查java中的内存泄露,一定要让程序将各种分支情况都完整执行到程序结束,然后看某个对象是否被使用过,如果没有,则才能判定这个对象属于内存泄露。
如果一个外部类的实例对象的方法返回了一个内部类的实例对象,这个内部类对象被长期引用了,即使那个外部类实例对象不再被使用,但由于内部类持久外部类的实例对象,这个外部类对象将不会被垃圾回收,这也会造成内存泄露。
内存泄露的另外一种情况:当一个对象被存储进HashSet集合中以后,就不能修改这个对象中的那些参与计算哈希值的字段了,否则,对象修改后的哈希值与最初存储进HashSet集合中时的哈希值就不同了,在这种情况下,即使在contains方法使用该对象的当前引用作为的参数去HashSet集合中检索对象,也将返回找不到对象的结果,这也会导致无法从HashSet集合中单独删除当前对象,造成内存泄露。
8、能不能自己写个类,也叫java.lang.String?
可以,但在应用的时候,需要用自己的类加载器去加载,否则,系统的类加载器永远只是去加载jre.jar包中的那个java.lang.String。由于在tomcat的web应用程序中,都是由webapp自己的类加载器先自己加载WEB-INF/classess目录中的类,然后才委托上级的类加载器加载,如果我们在tomcat的web应用程序中写一个java.lang.String,这时候Servlet程序加载的就是我们自己写的java.lang.String,但是这么干就会出很多潜在的问题,原来所有用了java.lang.String类的都将出现问题。
虽然java提供了endorsed技术,可以覆盖jdk中的某些类,具体做法是....。但是,能够被覆盖的类是有限制范围,反正不包括java.lang这样的包中的类。
(下面的例如主要是便于大家学习理解只用,不要作为答案的一部分,否则,人家怀疑是题目泄露了)例如,运行下面的程序:
packagejava.lang;publicclassString{/***@paramargs*/publicstaticvoidmain(String[]args){//TODOAuto-generatedmethodstubSystem.out.println("string");}}
报告的错误如下:java.lang.NoSuchMethodError:mainExceptioninthread"main"这是因为加载了jre自带的java.lang.String,而该类中没有main方法。
2.Java代码查错
importjava.util.regex.Matcher;importjava.util.regex.Pattern;publicclassRegexTest{/***@paramargs*/publicstaticvoidmain(String[]args){//测试是否为合法的身份证号码String[]strs={"130681198712092019","13068119871209201x","13068119871209201","123456789012345","12345678901234x","1234567890123"};Patternp1=Pattern.compile("(//d{17}[0-9a-zA-Z]|//d{14}[0-9a-zA-Z])");for(inti=0;i
1、编写一个程序,将a.txt文件中的单词与b.txt文件中的单词交替合并到c.txt文件中,a.txt文件中的单词用回车符分隔,b.txt文件中用回车或空格进行分隔。答:
packagecn.itcast;importjava.io.File;importjava.io.FileReader;importjava.io.FileWriter;publicclassMainClass{publicstaticvoidmain(String[]args)throwsException{FileManagera=newFileManager("a.txt",newchar[]{'/n'});FileManagerb=newFileManager("b.txt",newchar[]{'/n',''});FileWriterc=newFileWriter("c.txt");StringaWord=null;StringbWord=null;while((aWord=a.nextWord())!=null){c.write(aWord+"/n");bWord=b.nextWord();if(bWord!=null)c.write(bWord+"/n");}while((bWord=b.nextWord())!=null){c.write(bWord+"/n");}c.close();}}classFileManager{String[]words=null;intpos=0;publicFileManager(Stringfilename,char[]seperators)throwsException{Filef=newFile(filename);FileReaderreader=newFileReader(f);char[]buf=newchar[(int)f.length()];intlen=reader.read(buf);Stringresults=newString(buf,0,len);Stringregex=null;if(seperators.length>1){regex=""+seperators[0]+"|"+seperators[1];}else{regex=""+seperators[0];}words=results.split(regex);}publicStringnextWord(){if(pos==words.length)returnnull;returnwords[pos++];}}
1、编写一个程序,将d:/java目录下的所有.java文件复制到d:/jad目录下,并将原来文件的扩展名从.java改为.jad。(大家正在做上面这道题,网上迟到的朋友也请做做这道题,找工作必须能编写这些简单问题的代码!)答:listFiles方法接受一个FileFilter对象,这个FileFilter对象就是过虑的策略对象,不同的人提供不同的FileFilter实现,即提供了不同的过滤策略。
importjava.io.File;importjava.io.FileInputStream;importjava.io.FileOutputStream;importjava.io.FilenameFilter;importjava.io.IOException;importjava.io.InputStream;importjava.io.OutputStream;publicclassJad2Java{publicstaticvoidmain(String[]args)throwsException{FilesrcDir=newFile("java");if(!(srcDir.exists()&&srcDir.isDirectory()))thrownewException("目录不存在");File[]files=srcDir.listFiles(newFilenameFilter(){publicbooleanaccept(Filedir,Stringname){returnname.endsWith(".java");}});System.out.println(files.length);FiledestDir=newFile("jad");if(!destDir.exists())destDir.mkdir();for(Filef:files){FileInputStreamfis=newFileInputStream(f);StringdestFileName=f.getName().replaceAll("//.javatiny_mce_markerquot;,".jad");FileOutputStreamfos=newFileOutputStream(newFile(destDir,destFileName));copy(fis,fos);fis.close();fos.close();}}privatestaticvoidcopy(InputStreamips,OutputStreamops)throwsException{intlen=0;byte[]buf=newbyte[1024];while((len=ips.read(buf))!=-1){ops.write(buf,0,len);}}}
由本题总结的思想及策略模式的解析:1.classjad2java{1.得到某个目录下的所有的java文件集合1.1得到目录FilesrcDir=newFile("d://java");1.2得到目录下的所有java文件:File[]files=srcDir.listFiles(newMyFileFilter());1.3只想得到.java的文件:
classMyFileFilterimplememytsFileFilter{publicbooleanaccept(Filepathname){returnpathname.getName().endsWith(".java")}}2.将每个文件复制到另外一个目录,并改扩展名2.1得到目标目录,如果目标目录不存在,则创建之2.2根据源文件名得到目标文件名,注意要用正则表达式,注意.的转义。2.3根据表示目录的File和目标文件名的字符串,得到表示目标文件的File。//要在硬盘中准确地创建出一个文件,需要知道文件名和文件的目录。2.4将源文件的流拷贝成目标文件流,拷贝方法独立成为一个方法,方法的参数采用抽象流的形式。//方法接受的参数类型尽量面向父类,越抽象越好,这样适应面更宽广。}
分析listFiles方法内部的策略模式实现原理
1、说明生活中遇到的二叉树,用java实现二叉树这是组合设计模式。我有很多个(假设10万个)数据要保存起来,以后还需要从保存的这些数据中检索是否存在某个数据,(我想说出二叉树的好处,该怎么说呢?那就是说别人的缺点),假如存在数组中,那么,碰巧要找的数字位于99999那个地方,那查找的速度将很慢,因为要从第1个依次往后取,取出来后进行比较。平衡二叉树(构建平衡二叉树需要先排序,我们这里就不作考虑了)可以很好地解决这个问题,但二叉树的遍历(前序,中序,后序)效率要比数组低很多,原理如下图:代码如下:
1、从类似如下的文本文件中读取出所有的姓名,并打印出重复的姓名和重复的次数,并按重复次数排序:1,张三,282,李四,353,张三,284,王五,355,张三,286,李四,357,赵六,288,田七,35
程序代码如下(答题要博得用人单位的喜欢,包名用该公司,面试前就提前查好该公司的网址,如果查不到,现场问也是可以的。还要加上实现思路的注释):
48、写一个Singleton出来。第一种:饱汉模式
publicclassSingleTon{privateSingleTon(){}
//实例化放在静态代码块里可提高程序的执行效率,但也可能更占用空间
privatefinalstaticSingleToninstance=newSingleTon();publicstaticSingleTongetInstance(){returninstance;}}
第二种:饥汉模式
publicclassSingleTon{privateSingleTon(){}privatestaticinstance=null;//newSingleTon();publicstaticsynchronizedSingleTongetInstance(){if(instance==null)instance=newSingleTon();returninstance;}}
第三种:用枚举
publicenumSingleTon{ONE;}
第三:更实际的应用(在什么情况用单例)
publicclassSequenceGenerator{//下面是该类自身的业务功能代码privateintcount=0;publicsynchronizedintgetSequence(){++count;}//下面是把该类变成单例的代码privateSequenceGenerator(){}privatefinalstaticinstance=newSequenceGenerator();publicstaticSingleTongetInstance(){returninstance;}}
第四:
publicclassMemoryDao{privateHashMapmap=newHashMap();publicvoidadd(Studentstu1){map.put(SequenceGenerator.getInstance().getSequence(),stu1);}//把MemoryDao变成单例}
Singleton模式主要作用是保证在Java应用程序中,一个类Class只有一个实例存在。一般Singleton模式通常有几种种形式:第一种形式:定义一个类,它的构造函数为private的,它有一个static的private的该类变量,在类初始化时实例话,通过一个public的getInstance方法获取对它的引用,继而调用其中的方法。
7、递归算法题2第1个人10,第2个比第1个人大2岁,依次递推,请用递归方式计算出第8个人多大?
packagecn.itcast;importjava.util.Date;publicclassA1{publicstaticvoidmain(String[]args){System.out.println(computeAge(8));}publicstaticintcomputeAge(intn){if(n==1)return10;returncomputeAge(n-1)+2;}}publicstaticvoidtoBinary(intn,StringBufferresult){if(n/2!=0)toBinary(n/2,result);result.append(n%2);}
94、排序都有哪几种方法?请列举。用JAVA实现一个快速排序。本人只研究过冒泡排序、选择排序和快速排序,下面是快速排序的代码:
publicclassQuickSort{/***快速排序*@paramstrDate*@paramleft*@paramright*/publicvoidquickSort(String[]strDate,intleft,intright){Stringmiddle,tempDate;inti,j;i=left;j=right;middle=strDate[(i+j)/2];do{while(strDate[i].compareTo(middle)<0&&i0&&j>left)j--;//找出右边比中间值小的数if(i<=j){//将左边大的数和右边小的数进行替换tempDate=strDate[i];strDate[i]=strDate[j];strDate[j]=tempDate;i++;j--;}}while(i<=j);//当两者交错时停止if(ileft){quickSort(strDate,left,j);}}/***@paramargs*/publicstaticvoidmain(String[]args){String[]strVoid=newString[]{"11","66","22","0","55","22","0","32"};QuickSortsort=newQuickSort();sort.quickSort(strVoid,0,strVoid.length-1);for(inti=0;i
7、有数组a[n],用java代码将数组元素顺序颠倒
//用下面的也可以//for(inti=0,intj=a.length-1;i
2.金额转换,阿拉伯数字的金额转换成中国传统的形式如:(¥1011)->(一千零一拾一元整)输出。去零的代码:
returnsb.reverse().toString().replaceAll("零[拾佰仟]","零").replaceAll("零+万","万").replaceAll("零+元","元").replaceAll("零+","零");publicclassRenMingBi{/***@paramargsaddbyzxx,Nov29,2008*/privatestaticfinalchar[]data=newchar[]{'零','壹','贰','叁','肆','伍','陆','柒','捌','玖'};privatestaticfinalchar[]units=newchar[]{'元','拾','佰','仟','万','拾','佰','仟','亿'};publicstaticvoidmain(String[]args){//TODOAuto-generatedmethodstubSystem.out.println(convert(135689123));}publicstaticStringconvert(intmoney){StringBuffersbf=newStringBuffer();intunit=0;while(money!=0){sbf.insert(0,units[unit++]);intnumber=money%10;sbf.insert(0,data[number]);money/=10;}returnsbf.toString();}}
1.用table显示n条记录,每3行换一次颜色,即1,2,3用红色字体,4,5,6用绿色字体,7,8,9用红颜色字体。