JAVA面试题(一)

 一、Java 基础

1.JDK 和 JRE 有什么区别?

答:JRE: Java Runtime Environment

        JDK:Java Development Kit

        JRE顾名思义是java运行时环境,包含了java虚拟机,java基础类库。是使用java语言编写的程序运行所需要的软件环境,是提供给想运行java程序的用户使用的。

        JDK顾名思义是java开发工具包,是程序员使用java语言编写java程序所需的开发工具包,是提供给程序员使用的。JDK包含了JRE,同时还包含了编译java源码的编译器javac,还包含了很多java程序调试和分析的工具:jconsole,jvisualvm等工具软件,还包含了java程序编写所需的文档和demo例子程序。

        如果安装了JDK,会发同你的电脑有两套JRE,一套位于 \jre 另外一套位于 C:\Program Files\Java\j2re1.4.1_01 目录下,后面这套比前面那套少了Server端的Java虚拟机


2.== 和 equals 的区别是什么?

答:==:比较引用类型比较的是地址值是否相同

        equals:比较引用类型默认也是比较地址值是否相同,注意:String类重写了equals()方法,比较的是内容是否相同。


3.两个对象的 hashCode()相同,则 equals()也一定为 true,对吗?

答:首先了解hashCode()的用途,HashCode的存在主要是为了查找的快捷性,HashCode是用来在散列存储结构中确定对象的存储地址的。

        由上一题我们可以得知,equals是默认比较地址值是否相同,String类的equals方法则比较内容是否相同。

        所以可以得出结论:

       ( 1.如果两个对象相同,那么它们的hashCode值一定要相同;

        2.如果两个对象的hashCode相同,它们并不一定相同(这里说的对象相同指的是用eqauls方法比较)。  

        如不按要求去做了,会发现相同的对象可以出现在Set集合中,同时,增加新元素的效率会大大下降。

        3.equals()相等的两个对象,hashcode()一定相等;equals()不相等的两个对象,却并不能证明他们的hashcode()不相等。

        换句话说,equals()方法不相等的两个对象,hashcode()有可能相等(我的理解是由于哈希码在生成的时候产生冲突造成的)。反过来,hashcode()不等,一定能推出equals()也不等;hashcode()相等,equals()可能相等,也可能不等。

---------------------

作者:flyingsen

来源:CSDN

原文:https://blog.csdn.net/zj15527620802/article/details/88547914

版权声明:本文为博主原创文章,转载请附上博文链接!)


4.final 在 java 中有什么作用?

答:final关键字可以用于三个地方。用于修饰类、类属性和类方法。

       被final关键字修饰的类不能被继承,被final关键字修饰的类属性和类方法不能被覆盖(重写);


5.java 中的 Math.round(-1.5) 等于多少?

答:math.round是四舍五入函数,这题扩展一下应该和Math.round(1.5)等于多少进行比较。

       Math.round(-1.5) = -2          Math.round(1.5)= 2

       四舍五入的原理是在参数上加0.5然后做向下取整。


6.String 属于基础的数据类型吗?

答:String不属于基础的数据类型,是final修饰的java类。

        拓展一下下。Java的八大基础数据类型:

        1 字符类型:byte,char

        2 基本整型:short,int,long

        3 浮点型:float,double

        4 布尔类型:boolean 


7.java 中操作字符串都有哪些类?它们之间有什么区别?

答:(String、StringBuffer、StringBuilder

        String : final修饰,String类的方法都是返回new String。即对String对象的任何改变都不影响到原对象,对字符串的修改操作都会生成新的对象。

        StringBuffer : 对字符串的操作的方法都加了synchronized,保证线程安全。

        StringBuilder : 不保证线程安全,在方法体内需要进行字符串的修改操作,可以new StringBuilder对象,调用StringBuilder对象的append、replace、delete等方法修改字符串。

---------------------

作者:ConstXiong

来源:CSDN

原文:https://blog.csdn.net/meism5/article/details/89328490

版权声明:本文为博主原创文章,转载请附上博文链接!)


区别:String是不可变的对象,对每次对String类型的改变时都会生成一个新的对象,StringBuffer和StringBuilder是可以改变对象的。

     对于操作效率:StringBuilder > StringBuffer > String

     对于线程安全:StringBuffer 是线程安全,可用于多线程;StringBuilder 是非线程安全,用于单线程

     不频繁的字符串操作使用 String。反之,StringBuffer 和 StringBuilder 都优于String


8.String str="i"与 String str=new String("i")一样吗?

答:不一样

       前者内存会去查找永久代(常量池) ,如果没有的话,在永久代中中开辟一块儿内存空间,把地址付给栈指针,如果已经有了"ABC"的内存,直接把地址赋给栈指针;所以如果String str=“i”     String str1=“i”      String str2=“i”时,str==str1==str2

       后者是根据"i"这个String对象再次构造一个String对象;在堆中从新new一块儿内存,把指针赋给栈,将新构造出来的String对象的引用赋给str。 因此 只要是new String(),则,栈中的地址都是指向最新的new出来的堆中的地址。     


9.如何将字符串反转?

答:方法1 递归方法:

public static String reverse1(String s) {

  int length = s.length();

  if (length <= 1){

    return s;

    }

  String left = s.substring(0, length / 2);

  String right = s.substring(length / 2, length);

  return reverse1(right) + reverse1(left);

}

        方法2 通过 charAt(int index)返回char值进行字符串拼接

public static String reverse2(String s) {

  int length = s.length();

  String reverse = "";

  for (int i = 0; i < length; i++)

  reverse = s.charAt(i) + reverse;

  return reverse;

}

        方法3 把字符串转换成字符数组倒叙拼接然后返回值

public static String reverse3(String s) {

  char[] array = s.toCharArray();

  String reverse = "";

  for (int i = array.length - 1; i >= 0; i--)

  reverse += array[i];

  return reverse;

}

        方法4 调用StringBuffer中的reverse方法

publicstatic String reverse4(String s) {

  returnnew StringBuffer(s).reverse().toString();

}

        方法5 把字符串转换成字符数组首位对调位置

public static String reverse5(String orig) {

  char[] s = orig.toCharArray();

  int n = s.length - 1;

  int halfLength = n / 2;

  for (int i = 0; i <= halfLength; i++) {

  char temp = s[i];

  s[i] = s[n - i];

  s[n - i] = temp;

  }

  return new String(s);

}

        方法6

public static String reverse6(String s) {

  char[] str = s.toCharArray();

  int begin = 0;

  int end = s.length() - 1; 

  while (begin < end) {

  str[begin] = (char) (str[begin] ^ str[end]);

  str[end] = (char) (str[begin] ^ str[end]);

  str[begin] = (char) (str[end] ^ str[begin]);

  begin++;

  end--;

  }

return new String(str);

}

        方法7

import java.util.Stack;

public class StringReverse {   

public static String reverse7(String s) {

  char[] str = s.toCharArray();

  Stack<Character> stack = new Stack<Character>();

  for (int i = 0; i < str.length; i++)

  stack.push(str[i]);

  String reversed = "";

  for (int i = 0; i < str.length; i++)

  reversed += stack.pop();

  return reversed;

}

}

作者:绝不妥协绝不低头

来源:博客园

原文:https://www.cnblogs.com/lanseyitai1224/p/6955609.html


10.String 类的常用方法都有那些?

答:下面列举了20个常用方法。格式:返回类型  方法名  作用。

1、和长度有关:

int length() 得到一个字符串的字符个数

2、和数组有关:

byte[] getByte() ) 将一个字符串转换成字节数组

char[] toCharArray() 将一个字符串转换成字符数组

String split(String) 将一个字符串按照指定内容劈开

3、和判断有关:

boolean equals() 判断两个字符串的内容是否一样

boolean equalsIsIgnoreCase(String) 忽略太小写的比较两个字符串的内容是否一样

boolean contains(String) 判断一个字符串里面是否包含指定的内容

boolean startsWith(String) 判断一个字符串是否以指定的内容开头

boolean endsWith(String) 判断一个字符串是否以指定的内容结尾

4、和改变内容有关:

String toUpperCase() 将一个字符串全部转换成大写

String toLowerCase() 将一个字符串全部转换成小写

String replace(String,String) 将某个内容全部替换成指定内容

String replaceAll(String,String) 将某个内容全部替换成指定内容,支持正则

String repalceFirst(String,String) 将第一次出现的某个内容替换成指定的内容

String substring(int) 从指定下标开始一直截取到字符串的最后

String substring(int,int) 从下标x截取到下标y-1对应的元素

String trim() 去除一个字符串的前后空格

5、和位置有关:

char charAt(int) 得到指定下标位置对应的字符

int indexOf(String) 得到指定内容第一次出现的下标

int lastIndexOf(String) 得到指定内容最后一次出现的下标


11.抽象类必须要有抽象方法吗?

答:抽象类中不一定要包含抽象(abstrace)方法。也就是了,抽象中可以没有抽象(abstract)方法。反之,类中含有抽象方法,那么类必须声明为抽象类。


12.普通类和抽象类有哪些区别?

答:1.抽象类不能被实例化。

        2.抽象类可以有构造函数,被继承时子类必须继承父类一个构造方法,抽象方法不能被声明为静态。

        3.抽象方法只需申明,而无需实现,抽象类中可以允许普通方法有主体

        4.含有抽象方法的类必须申明为抽象类

        5.抽象的子类必须实现抽象类中所有抽象方法,否则这个子类也是抽象类。

拓展一下:抽象类是否可以有构造函数?答案是可以有。抽象类的构造函数用来初始化抽象类的一些字段,而这一切都在抽象类的派生类实例化之前发生。不仅如此,抽线类的构造函数还有一种巧妙应用:就是在其内部实现子类必须执行的代码


13.抽象类能使用 final 修饰吗?

答:不能,抽象类是被用于继承的,final修饰代表不可修改、不可继承的。(抽象类中的抽象方法是未来继承之后重写方法,而用final修饰的类,无法被继承。)


14.接口和抽象类有什么区别?

答:a. 抽象类可以有构造方法,接口中不能有构造方法。

        b. 抽象类中可以有普通成员变量,接口中没有普通成员变量。

        c. 抽象类中可以包含非抽象普通方法,接口中的所有方法必须都是抽象的,不能有非抽象的方法。

        d. 抽象类中的抽象方法的访问权限可以是 public、protected 和(默认类型,虽然 eclipse 不报错,但也不能用,默认类型子类不能继承),接口中的抽象方法只能是 public 类型的,并且默认即为 public abstract 类型。

        e. 抽象类中可以包含静态方法,在 JDK1.8 之前接口中不能不包含静态方法,JDK1.8 以后可以包含。

        f. 抽象类和接口中都可以包含静态成员变量,抽象类中的静态成员变量的访问权限可以是任意的,但接口中定义的变量只能是 public static final 类型的,并且默认即为 public static final 类型。

        g. 一个类可以实现多个接口,用逗号隔开,但只能继承一个抽象类,接口不可以实现接口,但可以继承接口,并且可以继承多个接口,用逗号隔开。

        h.接口是设计的结果 ,抽象类是重构的结果


15.java 中 IO 流分为几种?

答:•按照流的流向分,可以分为输入流和输出流;

        •按照操作单元划分,可以划分为字节流和字符流;

        •按照流的角色划分为节点流和处理流。

        Java Io流共涉及40多个类,这些类看上去很杂乱,但实际上很有规则,而且彼此之间存在非常紧密的联系, Java I0流的40多个类都是从如下4个抽象类基类中派生出来的。

        1.字节输入流(InputStream

        2.字节输出流(OutputStream

        3.字符输入流(Reader

        4.字符输出流(Writer

---------------------

作者:qfc8930858

来源:CSDN

原文:https://blog.csdn.net/qfc8930858/article/details/89493877

版权声明:本文为博主原创文章,转载请附上博文链接!


16.BIO、NIO、AIO 有什么区别?

答:•BIO (Blocking I/O): 同步阻塞I/O模式,数据的读取写入必须阻塞在一个线程内等待其完成。在活动连接数不是特别高(小于单机1000)的情况下,这种模型是比较不错的,可以让每一个连接专注于自己的 I/O 并且编程模型简单,也不用过多考虑系统的过载、限流等问题。线程池本身就是一个天然的漏斗,可以缓冲一些系统处理不了的连接或请求。但是,当面对十万甚至百万级连接的时候,传统的 BIO 模型是无能为力的。因此,我们需要一种更高效的 I/O 处理模型来应对更高的并发量。

        •NIO (New I/O): NIO是一种同步非阻塞的I/O模型,在Java 1.4 中引入了NIO框架,对应 java.nio 包,提供了 Channel , Selector,Buffer等抽象。NIO中的N可以理解为Non-blocking,不单纯是New。它支持面向缓冲的,基于通道的I/O操作方法。NIO提供了与传统BIO模型中的 Socket 和 ServerSocket 相对应的 SocketChannel 和 ServerSocketChannel 两种不同的套接字通道实现,两种通道都支持阻塞和非阻塞两种模式。阻塞模式使用就像传统中的支持一样,比较简单,但是性能和可靠性都不好;非阻塞模式正好与之相反。对于低负载、低并发的应用程序,可以使用同步阻塞I/O来提升开发速率和更好的维护性;对于高负载、高并发的(网络)应用,应使用 NIO 的非阻塞模式来开发

        •AIO (Asynchronous I/O): AIO 也就是 NIO 2。在 Java 7 中引入了 NIO 的改进版 NIO 2,它是异步非阻塞的IO模型。异步 IO 是基于事件和回调机制实现的,也就是应用操作之后会直接返回,不会堵塞在那里,当后台处理完成,操作系统会通知相应的线程进行后续的操作。AIO 是异步IO的缩写,虽然 NIO 在网络操作中,提供了非阻塞的方法,但是 NIO 的 IO 行为还是同步的。对于 NIO 来说,我们的业务线程是在 IO 操作准备好时,得到通知,接着就由这个线程自行进行 IO 操作,IO操作本身是同步的。查阅网上相关资料,我发现就目前来说 AIO 的应用还不是很广泛,Netty 之前也尝试使用过 AIO,不过又放弃了。

---------------------

作者:qfc8930858

来源:CSDN

原文:https://blog.csdn.net/qfc8930858/article/details/89493877

版权声明:本文为博主原创文章,转载请附上博文链接!


17.Files的常用方法都有哪些?

答:

创建:

createNewFile()在指定位置创建一个空文件,成功就返回true,如果已存在就不创建,然后返回false。

mkdir() 在指定位置创建一个单级文件夹。

mkdirs() 在指定位置创建一个多级文件夹。

renameTo(File dest)如果目标文件与源文件是在同一个路径下,那么renameTo的作用是重命名, 如果目标文件与源文件不是在同一个路径下,那么renameTo的作用就是剪切,而且还不能操作文件夹。

删除:

delete() 删除文件或者一个空文件夹,不能删除非空文件夹,马上删除文件,返回一个布尔值。

deleteOnExit()jvm退出时删除文件或者文件夹,用于删除临时文件,无返回值。

判断:

exists() 文件或文件夹是否存在。

isFile() 是否是一个文件,如果不存在,则始终为false。

isDirectory() 是否是一个目录,如果不存在,则始终为false。

isHidden() 是否是一个隐藏的文件或是否是隐藏的目录。

isAbsolute() 测试此抽象路径名是否为绝对路径名。

获取:

getName() 获取文件或文件夹的名称,不包含上级路径。

getAbsolutePath()获取文件的绝对路径,与文件是否存在没关系

length() 获取文件的大小(字节数),如果文件不存在则返回0L,如果是文件夹也返回0L。

getParent() 返回此抽象路径名父目录的路径名字符串;如果此路径名没有指定父目录,则返回null。

lastModified()获取最后一次被修改的时间。

文件夹相关:

static File[] listRoots()列出所有的根目录(Window中就是所有系统的盘符)

list() 返回目录下的文件或者目录名,包含隐藏文件。对于文件这样操作会返回null。

listFiles() 返回目录下的文件或者目录对象(File类实例),包含隐藏文件。对于文件这样操作会返回null。

list(FilenameFilter filter)返回指定当前目录中符合过滤条件的子文件或子目录。对于文件这样操作会返回null。

listFiles(FilenameFilter filter)返回指定当前目录中符合过滤条件的子文件或子目录。对于文件这样操作会返回null。

测试代码:

package com.file;

import java.io.File;

import java.io.IOException;

/**

* file相关的方法

*

* @author coco_xu

*

*/

public class FileMethodTest {

    public static void main(String[] args) throws IOException {

        File fileCreate = new File("D:\\coco_xu\\study\\files\\file.txt");

        // 创建单级文件夹

        System.out.println("单级文件夹创建:" + fileCreate.mkdir());

        // 创建多级文件夹

        System.out.println("多级文件夹创建:" + fileCreate.mkdirs());

//创建文件

        System.out.println("创建文件:" + fileCreate.createNewFile());

//文件重命名

        File toFile = new File("D:\\coco_xu\\study\\files\\toFile.txt");

        System.out.println("文件重命名:" + fileCreate.renameTo(toFile));

        // 删除方法

        File file = new File("D:\\coco_xu\\study\\files\\toFile.tx");

        System.out.println("删除文件:" + file.delete());

        file.deleteOnExit();

        // 判断方法

        /*

        * File file = new File("F:\\a.txt");

        * System.out.println("文件或者文件夹存在吗?"+file.exists());

        * System.out.println("是一个文件吗?"+file.isFile());

        * System.out.println("是一个文件夹吗?"+file.isDirectory());

        * System.out.println("是隐藏文件吗?"+file.isHidden());

        * System.out.println("此路径是绝对路径名?"+file.isAbsolute());

        */

        // 获取方法

        /*

        * File file = new File("f:\\a.txt");

        * System.out.println("文件或者文件夹得名称是:"+file.getName());

        * System.out.println("绝对路径是:"+file.getPath());

        * System.out.println("绝对路径是:"+file.getAbsolutePath());

        * System.out.println("文件大小是(以字节为单位):"+file.length());

        * System.out.println("父路径是"+file.getParent()); //使用日期类与日期格式化类进行获取规定的时间 long

        * lastmodified= file.lastModified(); Date data = new Date(lastmodified);

        * SimpleDateFormat simpledataformat = new

        * SimpleDateFormat("YY年MM月DD日 HH:mm:ss");

        * System.out.println("最后一次修改的时间是:"+simpledataformat.format(data));

        */

        // 文件或者文件夹的方法

        /*

        * File[] file = File.listRoots(); System.out.println("所有的盘符是:"); for (File item

        * : file) { System.out.println("\t" + item); } File filename = new

        * File("D:\\coco_xu"); String[] name = filename.list();

        * System.out.println("指定文件夹下的文件或者文件夹有:"); for (String item : name) {

        * System.out.println("\t" + item); } File[] f = filename.listFiles();

        * System.out.println("获得该路径下的文件或文件夹是:"); for (File item : f) {

        * System.out.println("\t" + item.getName()); }

        */

    }

}

转载自:https://www.cnblogs.com/cocoxu1992/p/10460994.html


©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,928评论 6 509
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,748评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 166,282评论 0 357
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,065评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,101评论 6 395
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,855评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,521评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,414评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,931评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,053评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,191评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,873评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,529评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,074评论 0 23
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,188评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,491评论 3 375
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,173评论 2 357

推荐阅读更多精彩内容