黑马程序员技术交流社区

标题: 常见小测试题答案 [打印本页]

作者: 黄玉昆    时间: 2013-3-14 15:42
标题: 常见小测试题答案
本帖最后由 黄玉昆 于 2013-3-14 15:42 编辑

各位版主已经把大家的答案都仔细的评分了,首先在此谢谢各位版主,也谢谢滔哥对本次活动的支持。
说明:分数会在2月14号和15号给大家加上的,答案也会一同公布的,只不过答案是参考答案,不一定是非常准确的,只是作为大家的参考。对于评分如果有异议的,请一定要私信给我,否则无效。
我在此说一下几个问题:
我理解大家的心情,也明白大家想提高自己的技术,通过回答问题和提出问题获得技术分。论坛里不止一次再强调这个技术分的问题,但是今天我还是有必要再说明一下。我在评分过程中,看到了很多同学做的真的很认真,回答得很详细,代码、注释一应俱全,没的说,太标准了,比我之前写的答案还要好,我自愧不如。但是我也看到了一些同学的侥幸心理,为了技术分而回答问题,我在这不是想批评谁,因为我没那个权利,我是版主,但是我更多的是为大家服务的义务,我义务没尽到,就是我的问题了,是我服务的不好。我只想说的是,不管是不是存在侥幸心理,捞取点技术分,可能你百度了答案,找了点资料,复制粘贴,答题成功了,你蒙蔽过了版主们的眼睛,但是人要慎独,就是自己要为自己的良心负责,学习是为了自己,进入黑马也不是说你多厉害,不是说你技术多高,而是你肯努力了,你踏踏实实学java了,只要你对得起自己,就足够了。我真心劝解那些心存侥幸的同学,学习是为的自己,你可以在背后说我怎么怎么样,没关系的,但是我今天就做一回愤青,我看不惯那些敷衍了事的人,如果你为自己学,你是好样的,如果你就想浑水摸鱼,那你就是在掩耳盗铃,将来毁了的是自己,害了的是自己。实实在在的,踏踏实实地学习,都是为的自己,你看别人那么多分,那是别人辛苦做出来的,我佩服那些能一道题一道题认真做的人,我不及他们,我还需要向他们学习。技术高不高没关系,但是做人如果没原则就很差劲了,人不能突破善良的底线。

说这么多了,其实就是简单一句话:人,为自己而活,要对得起自己的良心。做一个诚实的人,比做一个能力强的人,更重要。

其实,对于技术分,只要你踏踏实实学知识,看视频,回答问题,提出问题,我保证你半个月到一个月,拿够25分没问题。不要以25分为目标,这样你会没动力的,你需要将黑马入学作为你的中级目标,成为架构师为终极目标,那么你的人生都会因此而辉煌,而充满激情的。每一次的善良,都是幸福的积累。加油吧!!!

注意:
1、答案会显示在以下楼层中,大家可以讨论我给出的答案。
2、此贴禁止占楼,抢楼,严重者扣除相应的技术分。本帖只能回复与题目有关的,如果对哪道题有疑问或问题,可点击相应题目下的”回复“进行回帖。(当然,可以加写金币{:soso_e113:})
3、如果觉得哪道题有疑问,或觉得答案有问题,可以回复或私信给我。对于不合格的回复(或刷楼或占楼之类的楼层,一经发现将立即删楼,不作通知,请谅解)
4、如果觉得对自己的分数不满意,请不要点评说明,直接私信给我,否则分数不作处理,点评将被删除。
回复图解(如果我说的不太明白,或为照顾对回帖操作不明白的,可以看图解)
1、找对应的楼层,如第11层,那么直接点击这层对应的回复即可,如下图。(点击即可放大)

2、对哪层有疑问就回复那层。







测试题参考答案.zip

19.84 KB, 下载次数: 492


作者: 黄玉昆    时间: 2013-3-14 15:42
1、 Integer a = new Integer(100);     Integer b = 100;     Integer c =100;     int d = 100;a、b、c、d这四个数通过“==”和equals方法,进行比较,都哪些结果是true,哪些是false
第一、用equals比较的都是true,因为equals比较的是值,都为100,所以都相等
第二、用“==”比较的是地址,只有a和b,a和c不相等,其余为true。Java中,如果用“==”比较两个对象结果为true,说明这两个对象实际上是同一个对象,false说明是两个对象。a==d,b==d,c==d都是true,因为d是一个原始数据类型, Integer对int进行了封装,拿Integer对象和int基本数据类型==相比,就会发生一个自动拆箱操作,把Integer进行拆箱了再和int进行比较,所以都是true.
如何使用这两个比较方式:
当使用"=="来判断两个变量是否相等时,如果两个变量是基本数据类型的变量,且都是数值型(不一定要求数据类型严格相同),则只要两个变量的值相等,则使用"=="判断将返回true。但对于两个引用类型的变量,必须它们指向同一个对象时,"=="判断才会返回true;
使用equals判断:当程序需要判断两个引用变量是否相等时,并不要求两个引用变量指向同一个对象。比如两个字符串变量进行比较。只要求它们引用变量字符串里包含的字符序列相同即可,则用equals判断。其实equals的底层是用的==的比较方式,所以一般自定义的类,都需要复写这个equals的方法。
补充:
int 是基本类型,直接存数值;integer是对象,用一个引用指向这个对象。
1.Java 中的数据类型分为基本数据类型和复杂数据类型,int 是前者,Integer 是后者(也就是一个类)
2.初始化时,int d =100; Integer a= new Integer(100);(要把Integer当做一个类看)
  int 是基本数据类型(面向过程留下的痕迹,不过是对java的有益补充)
  Integer 是一个类,是int的扩展,定义了很多的转换方法
  类似的还有:float Float;doubleDouble;string String等
Java中int和Integer关系是比较微妙的。关系如下:
  1.int是基本的数据类型;
  2.Integer是int的封装类;
  3.int和Integer都可以表示某一个数值;
  4.int和Integer不能够互用,因为他们两种不同的数据类型;
Integer类的内部, 有一个常量静态数组, 在Integer类被加载的时候, 预先创建了-128 ~ 127的Integer对象, 所以当声明的Integer类型变量的值在-128 ~ 127的范围内时, 不会新创建对象, 直接引用数组中创建好的。而int是一个基本数据类型,不存在integer那样的创建对象的过程,只要数值不超过-2……31~2^31-1(对于32位的编译器来说),编译器就不会报错。


作者: 黄玉昆    时间: 2013-3-14 15:42
2、BS与CS的联系与区别
定义:
C/SClient/Server的缩写。服务器通常采用高性能的PC、工作站或小型 机,并采用大型数据库系统,如OracleSybaseInformix SQL Server。客户端需要安装专用的客户端软件。
B/S是Brower/Server的缩写,客户机上只要安装一个浏览器(Browser),如 Netscape NavigatorInternet Explorer,服务器安装OracleSybaseInformix SQL Server等数据库。在这种结构下,用户界面完全通过WWW浏览器实现,一部分事务逻辑在前端实现,但是主要事务逻辑在服务器端实现。浏览器通过Web Server 同数据库进行数据交互。
C/S B/S 区别:
(1)硬件环境不同:
C/S 一般建立在专用的网络上, 小范围里的网络环境, 局域网之间再通过专门服务器提供连接和数据交换服务.
B/S 建立在广域网之上的, 不必是专门的网络硬件环境,例与电话上网, 租用设备. 信息自己管理. 有比C/S更强的适应范围, 一般只要有操作系统和浏览器就行
(2)对安全要求不同
C/S 一般面向相对固定的用户群, 对信息安全的控制能力很强. 一般高度机密的信息系统采用C/S 结构适宜. 可以通过B/S发布部分可公开信息.
B/S 建立在广域网之上, 对安全的控制能力相对弱, 可能面向不可知的用户。
(3)对程序架构不同
C/S 程序可以更加注重流程, 可以对权限多层次校验, 对系统运行速度可以较少考虑.
B/S 对安全以及访问速度的多重的考虑, 建立在需要更加优化的基础之上.C/S有更高的要求 B/S结构的程序架构是发展的趋势, MS.Net系列的BizTalk2000 Exchange 2000, 全面支持网络的构件搭建的系统.SUN IBM推的JavaBean 构件技术等,使 B/S更加成熟.
(4)软件重用不同
C/S 程序可以不可避免的整体性考虑, 构件的重用性不如在B/S要求下的构件的重用性好.
B/S 对的多重结构,要求构件相对独立的功能. 能够相对较好的重用.就入买来的餐桌可以再利用,而不是做在墙上的石头桌子
(5)系统维护不同
C/S 程序由于整体性, 必须整体考察, 处理出现的问题以及系统升级. 升级难. 可能是再做一个全新的系统
B/S 构件组成,方面构件个别的更换,实现系统的无缝升级. 系统维护开销减到最小.用户从网上自己下载安装就可以实现升级.
(6)处理问题不同
C/S 程序可以处理用户面固定, 并且在相同区域, 安全要求高需求, 与操作系统相关. 应该都是相同的系统
B/S 建立在广域网上, 面向不同的用户群, 分散地域, 这是C/S无法作到的. 与操作系统平台关系最小.
(7)用户接口不同
C/S 多是建立的Window平台上,表现方法有限,对程序员普遍要求较高
B/S 建立在浏览器上, 有更加丰富和生动的表现方式与用户交流. 并且大部分难度减低,减低开发成本.
(8)信息流不同
C/S 程序一般是典型的中央集权的机械式处理, 交互性相对低
B/S 信息流向可变化, B-B B-C B-G等信息、流向的变化, 更像交易中心。


作者: 黄玉昆    时间: 2013-3-14 15:42
3、内部类可以引用他包含类的成员吗?有没有什么限制?
一个内部类对象可以访问创建它的外部类对象的内容。
第一、内部类可以直接访问外部类中的成员,包括私有。之所以可以直接访问外部类中的成员,是因为内部类中持有了一个外部类的引用,格式外部类名.this
第二、当内部类在成员位置上,就可以被成员修饰符所修饰。当内部类被static修饰后,只能直接访问外部类中的static成员。出现了访问局限。
第三、内部类定义在局部时,(1)不可以被成员修饰符修饰。(2)可以直接访问外部类中的成员,因为还持有外部类中的引用。但是不可以访问它所在的局部中的变量。只能访问被final修饰的局部变量。


作者: 黄玉昆    时间: 2013-3-14 15:42
4、小程序设计:通过键盘录入数据,分别录入三次,每次存入一个.txt文件中,并将三个文件合并为一个.java文件。(可直接下载附件)
  1. import java.io.*;
  2. import java.util.*;


  3. class Text4
  4. {
  5.         public static void main(String[] args)
  6.         {
  7.                 //录入数据,写入文件
  8.                 inputFile();
  9.                
  10.                 //合并文件
  11.                 sequenceFile();
  12.         }

  13.         //录入数据,写入文件
  14.         public static void inputFile()
  15.         {
  16.                 //创建字符输入流
  17.                 BufferedReader in = null;        
  18.                 //创建字符输出流
  19.                 BufferedWriter out = null;        
  20.                 try
  21.                 {
  22.                         //录入三次
  23.                         for(int i=1;i<=3;i++)
  24.                         {
  25.                                 System.out.println("请将数据录入第"+i+"个txt文件中,输入over结束:");
  26.                                 //创建文件对象
  27.                                 File file = new File(i+".txt");        
  28.                                 if(!file.exists())
  29.                                         file.createNewFile();
  30.                                 //键盘录入,读入数据                        
  31.                                 in = new BufferedReader(new InputStreamReader(System.in));
  32.                                 //将数据写到文件
  33.                                 out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file)));
  34.                                 String line = null;
  35.                                 //读取每一行数据到缓冲区
  36.                                 while((line = in.readLine())!= null)
  37.                                 {
  38.                                         //输入over结束本次录入
  39.                                         if("over".equals(line))
  40.                                                 break;
  41.                                         //写入数据到流
  42.                                         out.write(line);
  43.                                         out.newLine();
  44.                                         out.flush();
  45.                                 }
  46.                         }
  47.                 }
  48.                 catch (IOException e)
  49.                 {
  50.                         throw new RuntimeException("键盘录入失败");
  51.                 }
  52.                 //关闭资源
  53.                 finally
  54.                 {
  55.                         try{
  56.                                 if(in!= null)
  57.                                         in.close();
  58.                         }catch(IOException e){
  59.                                 throw new RuntimeException("读取流关闭失败");
  60.                         }
  61.                         try{
  62.                                 if(out!= null)
  63.                                         out.close();
  64.                         }
  65.                         catch(IOException e){
  66.                                 throw new RuntimeException("写入流关闭失败");
  67.                         }
  68.                 }
  69.         }
  70.         //合并文件
  71.         public static void sequenceFile()
  72.         {
  73.                 FileOutputStream fos = null;
  74.                 SequenceInputStream sis = null;
  75.                 try
  76.                 {
  77.                         //创建集合,存储多个文件
  78.                         ArrayList<FileInputStream> al = new ArrayList<FileInputStream>();
  79.                         for(int i=1;i<=3;i++)
  80.                         {
  81.                                 al.add(new FileInputStream(i+".txt"));
  82.                         }
  83.                         //匿名内部类访问局部变量要final
  84.                         final Iterator<FileInputStream> it = al.iterator();
  85.                         //创建Enumeration匿名对象
  86.                         Enumeration<FileInputStream> en = new Enumeration<FileInputStream>()
  87.                         {
  88.                                 public boolean hasMoreElements()
  89.                                 {
  90.                                         return it.hasNext();
  91.                                 }
  92.                                 public FileInputStream nextElement()
  93.                                 {
  94.                                         return it.next();
  95.                                 }
  96.                         };
  97.                         //合并流对象,将集合元素加入。
  98.                         sis = new SequenceInputStream(en);
  99.                         //创建写入流对象,FileOutputStream
  100.                         fos = new FileOutputStream("all.txt");
  101.                         byte[] b = new byte[1024*1024];
  102.                         int len = 0;
  103.                         //循环,将数据写入流资源
  104.                         while((len=sis.read(b))!=-1)
  105.                         {
  106.                                 fos.write(b,0,len);
  107.                         }

  108.                 }
  109.                 catch (IOException e)
  110.                 {
  111.                         throw new RuntimeException("文件操作失败");
  112.                 }
  113.                 //关闭流资源
  114.                 finally
  115.                 {
  116.                         try
  117.                         {
  118.                                 if(fos!=null)
  119.                                         fos.close();
  120.                         }
  121.                         catch (IOException e)
  122.                         {
  123.                                 throw new RuntimeException("关闭流资源操作失败");
  124.                         }
  125.                         try
  126.                         {
  127.                                 if(sis!=null)
  128.                                         sis.close();
  129.                         }
  130.                         catch (IOException e)
  131.                         {
  132.                                 throw new RuntimeException("关闭流资源操作失败");
  133.                         }
  134.                 }               
  135.         }
  136. }
复制代码

Text4.zip

1.24 KB, 下载次数: 289


作者: 黄玉昆    时间: 2013-3-14 15:42
5、JAVA语言如何进行异常处理,关键字:throws,throw,try,catch,finally分别代表什么意义?在try块中可以抛出异常吗?
第一、JAVA语言如何进行异常处理:
Java通过面向对象的方法进行异常处理,把各种不同的异常进行分类,并提供了良好的接口。在Java中,每个异常都是一个对象,它是Throwable类或其它子类的实例。当一 个方法出现异常后便抛出一个异常对象,该对象中包含有异常信息,调用这个对象的方法可以捕获到这个异常并进行处理。Java的异常处理是通过5个关键词来 实现的:trycatchthrowthrowsfinally。一般情况下是用try来执行一段程序,如果出现异常,系统会抛出 throws)一个异常,这时候你可以通过它的类型来捕捉(catch)它,或最后(finally)由缺省处理器来处理。
第二、关键字含义:
try来指定一块 预防所有异常的程序。紧跟在try程序后面,应包含一个catch子句来指定你想要捕捉的异常的类型。
throw语句用来明确地抛出一个异常
throws用来标明一个成员函数可能抛出的各种异常
Finally为确保一段代码不管发生什么异常都被执行一段代 码。
第三、在try块中可以抛出异常吗:
可以在一个成员函数调用的外面写一个try语句,在这个成员函数内部写另一个try语句保护其他代码。每当遇到一个try语句,异常的框架就放到堆栈上面,直到所有的try语句都完成。如果下一级的try语句没有对某种异常进行处理,堆栈就会展开,直到遇到有处理这种异常try 语句。
try{
       需要被检测的代码;
}
catch(异常类变量){
       处理异常的代码;(处理方式)
}
finally{
       一定会执行的语句;
}
并有三种结合方式:
结合方式一:
try{}catch{}
结合方式二:
try{}catch{}finally{}
结合方式三:
try{}finally{}


作者: 黄玉昆    时间: 2013-3-14 15:42
6、是否可以从一个static方法内部发出对非 static方法的调用?
不可以,如果其中包含对象的method();不能保证对象初始化.
static修饰的成员是在类加载的时候初始化的,而非static的成员是在创建对象的时候,即new操作的时候才初始化的。先后顺序是:先加载,才能初始化,那么加载的时候初始化static的成员,此时非static的成员还没有被加载必然不能使用,而非static的成员是在类加载之后,通过new操作符创建对象的时候初始化,此时static 已经分配内存空间,所以非静态成员可以访问静态成员!
      简单点说:静态成员属于类,不需要生成对象就存在了.而非静态需要生成对象才产生.,所以静态成员不能直接访问.  


作者: 黄玉昆    时间: 2013-3-14 15:42
7、是否可以继承String类?
String类是final类故不可以继承。
finaljava语言中的理解为“最终的”或者是“最终无法改变的”的意义。它可以对非抽象类的成员方法和变量进行修饰,final对非抽象类的成员方法和变量进行修饰后表示此抽象类不能再被继承和扩展,表示就是最终的。如果final修饰常量时表示此常量只能赋值一次,以后不能再进行修改。


作者: 黄玉昆    时间: 2013-3-14 15:42
本帖最后由 黄玉昆 于 2013-3-15 19:03 编辑

8、char型变量中能不能存贮一个中文汉字?为什么?
能够定义成为一个中文的,因为java中以unicode编码,一个char2个字节,16个二进制位;一个汉字也是两个字节,所以放一个中文是没问题的

作者: 黄玉昆    时间: 2013-3-14 15:42
9、java中的锁synchronized和Lock的异同
主要相同点:Lock能完成synchronized所实现的所有功能,
主要不同点:
synchronized一般是在线程同步上会涉及到。它可以放在函数上修饰函数,也可以放在某些代码块上修饰语句,放在函数上叫同步函数,放在语句上叫同步代码块。它再用的时候要获取一个锁,这个锁是一个对象。任何对象都可以,但是必须是一致的才能保证同步,一般可以用Object对象。如果是非静态函数,那么这个对象用的是this;如果是在静态函数上,则这个对象就是该方法所在类的字节码文件,即类名.class
Locklock JDK1.5出现的,是对sychornized的改进。sychornized能实现的功能lock基本都能实现,但是Lock有比synchronized更精确的线程语义和更好的性能。synchronized会自动释放锁,而Lock一定要求程序员手工释放,并且必须在finally从句中释放。


作者: 黄玉昆    时间: 2013-3-14 15:42
10、Collection和Collections的区别
Collection是集合类的上级接口,继承与他的接口主要有Set List。它提供了对集合对象进行基本操作的通用接口方法。Collection接口在Java 类库中有很多具体的实现。Collection接口的意义是为各种具体的集合提供了最大化的统一操作方式
Collections是针对集合类的一个工具类,他提供一系列静态方法实现对各种集合的搜索、排序、线程安全化等操作。


作者: 黄玉昆    时间: 2013-3-14 15:42
11、一个类中的静态方法可以用这个类的一个对象调用吗?为什么?
可以,因为静态是在类加载时就存在了,是属于整个类的,可以被类名直接调用,也可以被本类对象调用。


作者: 黄玉昆    时间: 2013-3-14 15:42
12、对于Person p = new Person("张三","25");这句话的加载示意图(画图,保存为图片的相关格式)




作者: 黄玉昆    时间: 2013-3-14 15:42
本帖最后由 黄玉昆 于 2013-3-14 15:35 编辑

13、为什么this和super不能同时出现在构造函数中的第一行?
构造函数中,thissuper语句都必须在第一语句出现,因为两者都是用来初始化的,既然是初始化,就要首先存在,就只能进行一次,因此不能同时作为第一条语句出现。


作者: 黄玉昆    时间: 2013-3-14 15:42
14、假设A是一个接口,A中有两个方法,类B实现了这个接口,那么B一定要覆写A中全部的方法吗?A可以创建一个A对象吗?A a =new B();的写法正取吗?
第一、B如果要创建对象,必须覆写A中全部的方法,因为如果只覆写一部分,B会继承A中的抽象方法,抽象方法必须存在于抽象类中,如果这样B就不可以创建对象了
第二、A不可以创建对象,因为A是一个接口,全为抽象方法,不能实例化对象
第三、这种写法是正确的,A虽然不能实例化对象,但是可以创建一个引用,指向类B这个对象。这里用到了多态。


作者: 黄玉昆    时间: 2013-3-14 15:43
15、什么是单例设计模式?什么是模板方法?什么是装饰类?
单例设计模式解决一个类在内存中只存在一个对象的问题(比如说一个软件中的配置文件)
1、饿汉式:先初始化对象,类一进内存就加载
  1. class Single   
  2. {  
  3.     private Single(){}  
  4.     private static Single s = new Single();  
  5.     public static  Single getSingle()  
  6.     {  
  7.         return s;  
  8.     }  
  9. }  
  10.   
  11. class SingleText  
  12. {  
  13.     public static void main(String [] args)  
  14.     {  
  15.         Single s1 = Single.getSingle();  
  16.         Single s2 = Single.getSingle();  
  17.         if (s1==s2)  
  18.             System.out.println(true);  
  19.         else  
  20.             System.out.println(false);        
  21. }
  22. }  
复制代码
2、懒汉式:类进内存,对象还没有存在,只有调用了getSingle方法时,才建立对象
  1. class Single  
  2. {  
  3.     private static Single s = null;  
  4.     private Single(){}  
  5.     public static Single getInstance()  
  6.     {  
  7.         if (s == null)  
  8.         {  
  9.             synchronized(Single.class)  
  10.             {  
  11.                 if (s == null)  
  12.                     s = new Single();  
  13.             }  
  14.         }  
  15.         return s;  
  16.     }  
  17. }
复制代码
模板方法:在定义功能时,功能的一部分是确定的,但有一部分是不确定的,而确定的部分在使用不确定的部分,那次是讲不确定的部分(抽象)暴露出去,由子类完成具体内部(复写),如下面的例子,study的具体方法需要子类去实现
  1. class Person{}
  2. abstract class PersonFunction{
  3.         private Person p;
  4.         PersonFunction(Person p){
  5.                 this.p = p;
  6.         }
  7.         private void breath()
  8.         {
  9.                 System.out.println("我在呼吸");
  10.         }
  11.         public abstract void study();
  12. }
复制代码
装饰类:
装饰类是对已有对象进行功能的增强,将已有对象作为参数传入,基于已有的功能,并提供加强的功能。装饰类是一种组合结构,和被装饰的类同属一个体系。装饰模式比继承更灵活,避免了继承体系的臃肿,且降低了类与类之间的关系
  1. class MyBufferReader extends MyReader
  2. {
  3.         private MyReader r;
  4.         MyBufferReader(MyReader r)
  5.         {}
  6. }
复制代码

作者: 黄玉昆    时间: 2013-3-14 15:43
16、装饰类和继承的区别和联系?
区别:
装饰类是对已有对象进行功能的增强,将已有对象作为参数传入,基于已有的功能,并提供加强的功能。装饰类是一种组合结构,和被装饰的类同属一个体系。装饰模式比继承更灵活,避免了继承体系的臃肿,且降低了类与类之间的关系
继承是当两个事物之间存在一定的所属关系时,可以使用继承,继承的类可以使用被继承类中的功能和属性,提高代码的复用性。让类与类之间产生了关系。但不能为了使用一个类的方法,就任意继承。
联系:
可以说装饰类和被装饰类同继承一个类,是被继承类体系下的子类。


作者: 黄玉昆    时间: 2013-3-14 15:43
本帖最后由 黄玉昆 于 2013-3-14 17:12 编辑

17、Outer.Inner in = new Outer().new Inner(),请对这句话解释一下
这个是在外部其他类中直接建立内部类对象的格式,即
外部类名.内部类名  变量名 = 外部类对象.内部类对象


作者: 黄玉昆    时间: 2013-3-14 15:43
18、在多线程中,为什么要覆盖run方法?
覆盖run方法的原因:
1)Thread类用于描述线程。该类定义了一个功能:用于存储线程要运行的代码,该存储功能即为run方法。也就是说,Thread类中的run方法用于存储线程要运行的代码,就如同main方法存放的代码一样。
2)复写run的目的:将自定义代码存储在run方法中,让线程运行要执行的代码。直接调用run,就是对象在调用方法。调用start(),开启线程并执行该线程的run方法。如果直接调用run方法,只是将线程创建了,但未运行。


作者: 黄玉昆    时间: 2013-3-14 15:43
19、String s = newString("ABC")创建了几个对象?
创建了两个对象,一个对象存在于常量池中,一个对象存在于堆内存中,原理是,当创建“ABC”时,先检查常量池中是否存在这个字符串,如果没有,则创建一个新的“ABC”字符串对象;之后再在堆内存中new一个对象,并将地址值赋给s。


作者: 黄玉昆    时间: 2013-3-14 15:43
20、String s1 = newString("ABC");和String s2 = "ABC";中,先写第一句和后写第一句的区别和联系?
对于上面的代码,有一点要说的:就是无论String s2 = new String("abc")s1前面写还是后面写,s2都会检查StringPool中是否有"abc"
若有,就直接在堆内存中创建一个对象;若没有,则要先在StringPool中创建"abc"后,再在堆内存中创建一个对象。这和20题一样的。
但是对于这道题,s1在前,创建两个对象,s1在后,这创建一个对象,因为s2已经在常量池中创建了一个“abc”的字符串对象,则s1就不会在创建了,直接在堆内存中new一个对象。


作者: 黄玉昆    时间: 2013-3-14 15:43
21、同步函数是静态的和是非静态的这两者所用的锁有何区别和联系?
1、非静态同步函数中的锁---> this
函数需被对象调用,那么函数都有一个所属的对象引用,就是this,因此同步函数使用的锁为this
2、静态同步函数中的锁:
如果同步函数被静态修饰后,经验证,使用的锁不是this了,因为静态方法中不可定义this,所以,这个锁不再是this了。静态进内存时,内存中没有本类对象,但是一定有该类对应的字节码文件对象:类名.class;该对象的类型是Class
所以静态的同步方法使用的锁是该方法所在类的字节码文件对象,即类名.class


作者: 黄玉昆    时间: 2013-3-14 15:43
22、在使用String类的split()方法是,下面这样写会成功分割为元素吗?如果成功,结果是什么?不成功的话,只使用split()方法,如何成功分割?        Strings = "A.B.C.D.E.java";     s.split(".");
这样截取是不会成功的,会报角标越界的异常,因为无法引号中的点不会被作为截取的标志,如果想让点成为被截取的标志,需要这样操作:s.split("\\.");就可以了。点是特殊字符,需要用\\来转义成普通字符


作者: 黄玉昆    时间: 2013-3-14 15:43
23、List集合的特有迭代器是什么?
特有的迭代器是listIterator
  1. public static void methodListIterator()  
  2.     {  
  3.         //演示列表迭代器:  
  4.         ArrayList list = new ArrayList();  
  5.         //1.添加元素--->add(Object obj),多态   
  6.         list.add("java01");  
  7.         list.add("java02");  
  8.         list.add("java03");  
  9.         list.add("java04");  
  10.   
  11.         //打印原集合  
  12.         sop("原集合:" + list);  
  13.         sop("------------------");  
  14.   
  15.          
  16.   
  17.         //在迭代过程中,准备添加或删除元素  
  18.         for (ListIterator it = list.listIterator();it.hasNext(); )  
  19.         {  
  20.             Object obj = it.next();  
  21.             if (obj.equals("java01"))  
  22.                 it.remove();  
  23.             else if(obj.equals("java02"))  
  24.                 it.add("增加java200");  
  25.             else if(obj.equals("java03"))  
  26.                 it.set("修改为java300");  
  27.             sop("obj:" + obj);  
  28.         }  
  29.         sop("list :" + list);  
  30.     }
复制代码

作者: 黄玉昆    时间: 2013-3-14 15:43
24、集合中的两种排序方式?
排序有两个要素:元素和集合
1)第一种排序方式:自然排序:让元素自身具备比较性。元素需要实现Comparable接口,覆盖compareTo方法,这种方式也称为元素的自然排序或默认排序方式。
  1. /*
  2. 第一种排序方式:自然排序,实现Comparable接口,重写compareTo方法
  3. 需求:
  4. 向TreeSet集合中存储自定义对象学生
  5. 按照学生的年龄进行排序
  6. */  
  7. import java.util.*;  
  8. //此接口强制让Student实现比较性  
  9. class Student implements Comparable   
  10. {  
  11.     //定义Student私有属性  
  12.     private String name;  
  13.     private int age;  
  14.     //构造Student函数,初始化  
  15.     Student(String name,int age)
  16.     {  
  17.         this.name = name;  
  18.         this.age = age;  
  19.     }  
  20.     //公共访问方法,访问私有属性  
  21.     public String getName()  
  22.     {  
  23.         return name;      
  24.     }  
  25.     public int getAge()  
  26.     {  
  27.         return age;  
  28.     }  
  29.     //复写Comparator中的compare方法,自定义比较器  
  30.     public int compareTo(Object obj)  
  31.     {  
  32.         //判断是否属于Student类型,否则抛异常  
  33.         if (!(obj instanceof Student))  
  34.             throw new RuntimeException("NotSuchTypeException");  
  35.         //将Object类对象强转为Student类  
  36.         Student s = (Student)obj;  
  37.          
  38.         //System.out.println(this.age + "--compare-" + s.age);//测试用,查看比较情况  
  39.   
  40.         //按年龄大小比较,相同则比较姓名大小,不同返回两年龄之差  
  41.         if (this.age == s.age)  
  42.         {  
  43.             return this.name.compareTo(s.name);  
  44.         }  
  45.         else if (this.age <s.age)  
  46.             return this.age-s.age;  
  47.         return this.age-s.age;  
  48.     }  
  49.     /*
  50.     //如果按照存入顺序输出
  51.     public int compareTo()
  52.     {
  53.         return 1;//改为-1则按倒叙输出
  54.     }
  55.     */  
  56. }  
  57. //测试  
  58. class TreeSetTest  
  59. {  
  60.     public static void main(String[] args)   
  61.     {  
  62.         //创建集合,并添加元素  
  63.         TreeSet ts = new TreeSet();  
  64.         ts.add(new Student("li01",25));  
  65.         ts.add(new Student("li02",20));  
  66.         ts.add(new Student("li01",22));  
  67.         ts.add(new Student("li05",24));  
  68.         ts.add(new Student("li08",40));  
  69.         //打印集合中元素  
  70.         printE(ts);  
  71.          
  72.         System.out.println("Hello World!");  
  73.     }  
  74.   
  75.     //定义打印集合中元素的功能  
  76.     public static void printE(TreeSet ts)  
  77.     {  
  78.         //迭代器方法获取  
  79.         Iterator it = ts.iterator();  
  80.       
  81.         while (it.hasNext())  
  82.         {  
  83.             //将返回的元素(Object类)强转为Student类  
  84.             Student s = (Student)it.next();  
  85.             System.out.println(s.getName() + "---" + s.getAge());  
  86.         }  
  87.     }  
  88. }  
复制代码
2)第二种排序方式:比较器
      当元素自身不具备比较性是,或者具备比较性,却不是所需要的,这时就需要让集合自身具备比较性。在集合初始化时就有了比较方式(即参阅构造函数)。
当两种排序方式都存在时,以比较器为主。
      如何构造比较器:定义一个类,实现Comparator接口,覆盖compare方法。
  1. import java.util.*;  
  2. //此接口强制让Student实现比较性  
  3. class Student implements Comparable  
  4. {  
  5.     //定义Student私有属性  
  6.     private String name;  
  7.     private int age;  
  8.     //构造Student函数,初始化  
  9.     Student(String name,int age)  
  10.     {  
  11.         this.name = name;  
  12.         this.age = age;  
  13.     }  
  14.     //公共访问方法,访问私有属性  
  15.     public String getName()  
  16.     {  
  17.         return name;  
  18.     }  
  19.     public int getAge()  
  20.     {  
  21.         return age;  
  22.     }  
  23.   
  24.     //复写Comparator中的compare方法,自定义比较器  
  25.     public int compareTo(Object obj)  
  26.     {  
  27.         //判断是否属于Student类型,否则抛异常  
  28.         if (!(obj instanceof Student))  
  29.             throw new RuntimeException("NotSuchTypeException");  
  30.         //按年龄大小比较,相同则比较姓名大小,不同返回两年龄之差  
  31.         Student s = (Student)obj;  
  32.         if (this.age > s.age)  
  33.             return this.age-s.age;  
  34.         else if (this.age == s.age)  
  35.         {  
  36.             return this.name.compareTo(s.name);  
  37.         }  
  38.         return this.age-s.age;  
  39.     }  
  40.          
  41. }  
  42.   
  43. //定义比较器,实现Comparator接口  
  44. class MyCompare implements Comparator  
  45. {  
  46.     //重写Comparator中的compare方法,按姓名顺序排序  
  47.     public int compare(Object o1,Object o2)  
  48.     {  
  49.         //判断给定对象是否为Student类,否则抛异常  
  50.         if (!((o1 instanceof Student) && (o2 instanceof Student)))  
  51.             throw new RuntimeException("NotSuchTypeException");  
  52.         //将给定对象强转为Student类  
  53.         Student s1 = (Student)o1;  
  54.         Student s2 = (Student)o2;  
  55.         //比较名字,返回数值,相同则比较年龄  
  56.         int n = s1.getName().compareTo(s2.getName());  
  57.         if (n == 0)  
  58.             return new Integer(s1.getAge()).compareTo(new Integer(s2.getAge()));  
  59.         return n;  
  60.     }  
  61. }  
  62. //测试  
  63. class TreeSetComDemo   
  64. {  
  65.     public static void main(String[] args)   
  66.     {  
  67.         //TreeSet ts = new TreeSet();  
  68.   
  69.         //创建集合,加入接口类参数,并添加元素  
  70.         TreeSet ts = new TreeSet(new MyCompare());  
  71.         ts.add(new Student("li01",25));  
  72.         ts.add(new Student("li02",20));  
  73.         ts.add(new Student("li01",22));  
  74.         ts.add(new Student("li05",24));  
  75.         ts.add(new Student("li08",40));  
  76.   
  77.         //打印集合中元素  
  78.         printE(ts);  
  79.     }  
  80.       
  81.     //定义打印集合中元素的功能  
  82.     public static void printE(TreeSet ts)  
  83.     {  
  84.         //迭代器方法获取  
  85.         Iterator it = ts.iterator();  
  86.       
  87.         while (it.hasNext())  
  88.         {  
  89.             //将返回的元素(Object类)强转为Student类  
  90.             Student s = (Student)it.next();  
  91.             System.out.println(s.getName() + "---" + s.getAge());  
  92.         }  
  93.     }  
  94. }
复制代码

作者: 黄玉昆    时间: 2013-3-14 15:43
25、集合中的两种取出方式?
keySet()entrySet()方法
1keySet()方法获取元素
原理:将Map集合中的所有键存入到Set集合中,因为Set集合具备迭代器,所以可以用迭代方式取出所有的键,再根据get方法获取每一个键对应的值。简单说就是:Map集合---->Set集合 ---->迭代器取出
  1. import java.util.*;  
  2. class KeySetDemo   
  3. {  
  4.     public static void main(String[] args)   
  5.     {  
  6.         //创建Map集合,并添加元素  
  7.         Map<Integer,String> map = new HashMap<Integer,String>();  
  8.         map.put(2,"zhangsan");  
  9.         map.put(6,"lisi");  
  10.         map.put(3,"wangwu");  
  11.         map.put(4,"heihei");  
  12.         map.put(5,"xixi");  
  13.         //获取map集合中的所有键的Set集合  
  14.         Set<Integer> keySet = map.keySet();  
  15.         //有了Set集合就可以获取其迭代器,取值  
  16.         Iterator<Integer> it = keySet.iterator();  
  17.         while (it.hasNext())  
  18.         {  
  19.             Integer i = it.next();  
  20.             String s = map.get(i);  
  21.             System.out.println(i + " = " + s);  
  22.         }  
  23.     }  
  24. }  
复制代码
2entrySet()方法获取元素:
原理:将Map集合中的映射关系存入到了Set集合中,而这个映射关系的数据类型是Map.Entry,在通过迭代器将映射关系存入到Map.Entry集合中,并通过其中的getKey()getValue()放取出键值。
  1. import java.util.*;  
  2. class EntrySetDemo  
  3. {  
  4.     public static void main(String[] args)   
  5.     {  
  6.         //创建集合,存入元素  
  7.         Map<String,String> map = new HashMap<String,String>();  
  8.         map.put("01","lisi1");  
  9.         map.put("02","lisi2");  
  10.         map.put("03","lisi3");  
  11.         map.put("04","lisi4");  
  12.         //获取map集合中的所有键,存入到Set集合中,  
  13.         Set<Map.Entry<String,String>> entry = map.entrySet();  
  14.         //通过迭代器取出map中的键值关系,迭代器接收的泛型参数应和Set接收的一致  
  15.         Iterator<Map.Entry<String,String>> it = entry.iterator();  
  16.         while (it.hasNext())  
  17.         {  
  18.             //将键值关系取出存入Map.Entry这个映射关系集合接口中  
  19.             Map.Entry<String,String>  me = it.next();  
  20.             //使用Map.Entry中的方法获取键和值  
  21.             String key = me.getKey();  
  22.             String value = me.getValue();  
  23.             System.out.println(key + " : " + value);  
  24.         }  
  25.     }  
  26. }  
复制代码

作者: 黄玉昆    时间: 2013-3-14 15:43
26、FileWriter和File创建文件的区别和联系?
File创建文件是先查看文件是否存在,如果存在则返回true,不存在则创建一个新文件
FileWriter创建对象时,不论文件存不存在,都会覆盖,创建新的文件


作者: 黄玉昆    时间: 2013-3-14 15:43
本帖最后由 黄玉昆 于 2013-3-17 20:41 编辑

27、请将你知道的最简单的几种死循环形式写出来
第一种:for(;;)
第二种:while(){}
第三种:do {}while(1);
第四种:public void show(){show();}


作者: 黄玉昆    时间: 2013-3-14 15:43
预留楼层

作者: 黄玉昆    时间: 2013-3-14 15:43
预留楼层
作者: wangjinyu501    时间: 2013-3-14 15:52
本帖最后由 wangjinyu501 于 2013-3-14 15:58 编辑

java多线程是不是很麻烦啊
作者: 熊冠银    时间: 2013-3-14 16:09
黄玉昆 发表于 2013-3-14 15:43
17、Outer.Inner in = new Outer(new Inner()),请对这句话解释一下这个是在外部其他类中直接建立内部类对 ...

不是应该这样写吗?Outer.Inner in=new Outer().new Inner();
题目上的那句话,我怎么看着都像是new外部类对象,初始化时传入了内部了对象
作者: 彭波    时间: 2013-3-14 18:10
很好,这样提高会很快的
作者: 符立波    时间: 2013-3-15 07:40
不错......
作者: 张豪杰    时间: 2013-3-15 10:44
本帖最后由 张豪杰 于 2013-3-15 10:46 编辑

楼主,第二十五题我有疑惑:
25、集合中的两种取出方式?
问题是问集合中的取出方式,但是你给的答案仅仅只是写出Map的两种取出方式
像List集合中的用迭代器取出,还有高级for取出元素,这应该也是吧?
难道List和Set都不属于集合体系?还是我对问题理解有误?
或者这道题的题目应该指明是“Map集合的两种取出方式”?
作者: 黄玉昆    时间: 2013-3-15 11:22
张豪杰 发表于 2013-3-15 10:44
楼主,第二十五题我有疑惑:
25、集合中的两种取出方式?
问题是问集合中的取出方式,但是你给的答案仅仅只 ...

你这么说也有道理,说的很准确;我觉得大家应该都理解我说的意思,因为在看视频都知道毕老师讲的这两种方式是说的Map集合,理解就好了。谢谢你
作者: 黄诗宾    时间: 2013-3-15 21:22
顶顶顶 支持了
作者: 黄文伯    时间: 2013-3-19 19:00
楼主辛苦了{:soso_e113:}
作者: 李道福    时间: 2013-3-19 23:47
黄玉昆 发表于 2013-3-14 15:42
6、是否可以从一个static方法内部发出对非 static方法的调用?不可以,如果其中包含对象的method();不能保 ...

public class A{
public static void main(String[] args){
  A a=new A();
  A.print(a); //这个算不算在静态方法内发出对非静态方法的调用 ?
}
void show(){
  System.out.println("hello");
}
static void print(A a){
  a.show();
}
}

作者: 蔡辉    时间: 2013-3-20 16:58
嘿嘿,顶一个
作者: 魏福伟    时间: 2013-3-22 19:08
给力啊!
作者: remeber    时间: 2013-3-28 12:18
楼主幸苦了  学习了好多
作者: 翟宝海    时间: 2013-3-30 14:01
技术贴,马克!
作者: 黄玉昆    时间: 2013-3-30 14:18
李道福 发表于 2013-3-19 23:47
public class A{
public static void main(String[] args){
  A a=new A();

首先来说,你这个print方法是个静态的,可以以直接调用,而不需要用A.print,虽然这样调用也没错。你的意思是:print里调用了非静态方法show,问这算不算在静态方法内发出对非静态方法的调用 ?其实这里你是用a.show(),是对象在调用这个show方法,这个不是静态调用非静态,因为已经有对象调用非静态方法show了,你要是直接调用show(),那么就是静态调用非静态了。




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2