Java面试(基础部分)
1.什么是B/S架构,什么是C/S架构?
B/S(Browser/Server),浏览器/服务器程序
C/S(Client/Server),客户端/服务器,桌面应用程序
2.Java都有哪些开发平台?
(1).JAVA SE:主要用在客户端开发
(2).JAVA EE:主要用在web应用程序开发
(3).JAVA ME:主要用在嵌入式应用程序开发
3.JDK?JRE?
JDK:java开发工具包,是开发人员所需要安装的环境
JRE:java运行环境,java程序运行所需要安装的环境
4.Java语言有什么特点?
简单易学,有丰富的类库
面向对象(Java最重要的特性,让程序高内聚,低耦合)
跨平台(JVM)
可靠,安全
支持多线程
5.面向对象和面向过程的区别?
面向过程编程:强调功能行为,功能的执行过程,每个功能使用函数按步骤实现,使用时依次调用函数即可。
面向对象编程:强调具备某些功能的对象,编程的本质是以类的方式组织代码,以对象的形式封装数据。类相当于对象的模板,然后通过new关键字创建不同的实例。在软件工程上,面向对象可以使工程更加模块化,实现高内聚低耦合。
6.数据结构是什么?
数据结构指的是计算机保存、组织数据的方式
7.Java的数据结构有哪些?
数组,链表,堆,栈,队列,图,树,散列表等。
8.OOP?
OOP指的是面向对象编程
9.类与对象的关系?
类是对象的抽象,对象是类的具体,类是对象的模板,对象是类的实例。
10.Java中的基本数据类型
整型:byte(1字节),short(2字节),int(4字节),long(8字节)
浮点型:float(4字节),double(8字节)
字符型:char(2字节)
布尔型:boolean(1个字节/4个字节)
1.标识符的命名规则
含义:标识符指在程序中,我们自己定义的内容,比如类的名字,方法名称以及变量名称等,都是标识符
命名规则:
标识符可以包含英文,数字(0-9),$以及_
标识符不能以数字开头
标识符不能是关键字
类名规范:首字母大写,后面每个单词首字母大写
方法名/变量名:首字母小写,后面每个单词首字母大写
2.instanceof关键字
instanceof严格来说是Java中的一个双目运算符,用来测试一个对象是否为一个类的实例,返回值是一个boolean类型的结果。
注意:
判断的变量不能是基本类型;
如果引用类型用null代替,那么将返回false.
3.隐式转换?显式转换?
显式转换:强制类型转换
隐式转换:自动类型转换
4.char–>int?char–>string?char–>double?
char–>int可以,char–>double可以------隐式转换
char–>string不可以转换
5.拆装箱?
装箱:自动将基本数据类型转换为包装器类型
拆箱:自动将包装器类型转换为基本数据类型
6.Java中基本数据类型对应的包装类为?
基本数据类型 | 对应的包装类 |
---|---|
byte | Byte |
short | Short |
int | Integer |
long | Long |
float | Float |
double | Double |
char | Character |
boolean | Boolean |
7.一个类中包含哪些内容
属性,方法,内部类,构造方法,代码块
8.与银行或金融挂钩的money,应使用哪个类运算?
使用Bigdecimal类进行浮点型数据的运算
9.面向对象的特征有哪些?
抽象,封装,继承,多态
抽象:包括数据抽象和行为抽象两方面。抽象只关注对象的属性和行为,不关注这些行为的细节是什么。
封装:属性私有,提供公有的get/set方法
继承:使用的关键字是extends,是类与类之间的关系。有继承关系的两个类,一个是子类,一个是父类。在Java中所有的类都默认间接或者直接继承Object类。Java中只有单继承。
多态:多态 是指方法的多态,属性没有多态;要存在多态就要有继承关系,有方法的重写,父类引用指向子类对象;如果方法被static,final,private修饰,那么就不可能实现多态。
10.java中的访问修饰符
修饰符 | 当前类 | 同包 | 子类 | 其他包 | |
---|---|---|---|---|---|
public | 能 | 能 | 能 | 能 | |
protected | 能 | 能 | 能 | 不能 | |
default | 能 | 能 | 不能 | 不能 | |
private | 能 | 不能 | 不能 | 不能 |
1.String是最基本的数据类型吗?
不是。Java的基本类型有八个:byte,short,int,long,float,double,char,boolean;除了基本类型,其它都是引用类型,Java5之后引入的枚举类型也是一种比较特殊的引用类型。
2.float = 3.4,是否正确?
错误,3.4是双精度数,即double,需要强转,即float = (float)3.4 或者 float = 3.4 F。
3.short s1 = 1,s1 = s1 + 1 ,有错吗?short s1 = 1,s1 += 1,有错吗?
short s1 = 1, s1 = s1 + 1,有错。因为1是int类型,s1 + 1 结果也是int类型,因此需要强转类型才能赋值给short类型。
short s1 = 1,s1 += 1,正确。因为s1 += 1 相当于,s1 = (short)(s1+1),其中有隐含的强制类型转换。
4.重载?重写?
重载:
方法名称必须相同;
参数列表必须不同;
方法的返回类型可相同也可不同。
注意:仅仅返回类型不同不能说明重载。
重写:
方法名必须相同;
参数列表必须相同;
方法的返回类型必须相同;
修饰符:范围可以扩大但不能缩小。
抛出的异常:范围可以缩小但不能扩大。
5.equals 与 == 的区别?
(1)== 是关系运算符,equals是Object类中的一个方法
(2)对于基本数据类型,只能使用==比较;
(3)除了8种基本数据类型外,==比较的是两个变量或实例(对象)是不是指向同一个内存空间,equals比较的是两个变量或实例(对象)所指向的内存空间中存的值是不是相同。
6.++i 和 i++ 的区别?
++i :先计算,后赋值
i++ :先赋值,后计算
7.程序的结构?
顺序结构;
选择结构;
循环结构。
8.数组实例化的方式?
静态初始化:创建+赋值
int[] a = {1, 2, 3, 4, 5, 6, 7, 8};
动态初始化: 包含默认初始化。基本类型:0 引用类型:null
int[] b = new int[10];
b[0] = 10;
System.out.println(b[0]);
System.out.println(b[1]);//0,默认初始化了。
9.Java中各种数据的默认值?
整型默认都是0;
布尔型默认是false;
字符型默认是’’;
浮点型默认是0.0;
对象类型默认是null。
10.Java常用包有哪些?
java.lang;
java.io;
java.sql;
java.util;
java.awt;
java.net;
java.math等等。
1.Object类常用的方法有哪些?
equals,hashcode,toString,wait,notify,clone,getClass等等。
2.Java中有没有指针?
有指针,但是隐藏了,开发人员无法直接操作指针,由JVM来操作指针。
3.Java中是值传递还是引用传递?
Java中只有一种参数传递方式就是值传递。参数类型分为基本类型和引用类型。
如果参数传递的是基本类型,接收的是原始值的副本,操作副本并不会对原始值产生影响。
如果参数传递的是引用类型,实则是把实际参数的引用的地址复制了一份,传递给了形式参数。
结论,Java中都是值传递,值传递和引用传递的区别并不是传递的内容,而是实参到底有没有被复制一份给形参。
4.实例化数组后,能不能改变数组长度呢?
不能,数组一旦实例化,它的长度就是固定的。
5.假如数组内有五个元素,如果对数组进行反序,该如何做?
创建一个新数组,从后到前循环遍历每个元素,将取出的元素依次顺序放入新数组中。
6.实参和形参的区别?
(1)形参变量只有在被调用时才分配内存单元,调用结束时,即刻释放所分配的内存单元。因此,形参只在函数内部有效。
(2)实参可以是常量、变量、表达式、函数等等,在进行函数调用时它们都必须是确定的值,以便把值传递给形参。因此需先赋值。
(3)实参和形参在数量上、类型上、顺序上应严格一致,否则就会发生类型不匹配的错误。
(4)传递是单向的,只能是由实参传递给形参。
7.构造方法能不能显式调用?
不能,构造方法当成普通方法调用,只有在创建对象的时候才会被系统调用。
8.构造方法能不能被重写?能不能被重载?
不能重写,只能重载。
9.什么是方法的重载?
方法的重载就是在同一个类中允许同时存在一个以上同名的方法,只要它们的参数个数或者类型不同即可。在这种情况下,该方法就叫被重载了,这个过程称为方法的重载。
10.内部类与静态内部类的区别?
静态内部类是内部类的一种。
内部类分为成员内部类,静态内部类,局部内部类,匿名内部类。
成员内部类可以获取到外部类的私有属性和私有方法;
局部内部类在方法内部定义,作用于方法内部,不能用访问修饰符修饰;
匿名内部类也在方法内部,没有构造函数,主要用于事件绑定,回调函数设置。对于匿名内部类,它的前提是接口对象作为外部类中方法的参数。
静态内部类随着外部类创建就有了,那时候还没有外部类的属性和方法,不依赖于外部类。
1.static关键字?
static可以修饰内部类、方法、变量、代码块。
2.final在Java中如何用?
(1)被final修饰的类不可以被继承
(2)被final修饰的方法不能被重写
(3)被final修饰的变量不可被更改
(4)被final修饰的方法,JVM会尝试将其内联,以提高运行效率
(5)被final修饰的常量,在编译阶段会存入常量池中
3.String,StringBuffer和StringBuilder的区别?
主要区别在两个方面,一个是运行效率,一个是线程安全。
运行效率方面:StringBuilder>StringBuffer>String
因为String是字符串常量,而另外两个均为字符串变量,即String对象一旦创建之后该对象是不可更改的。
线程安全方面:StringBuilder线程不安全,StringBuffer是线程安全的。
因此在对字符串操作时:
String适用于少量的字符串操作的情况;
StringBuilder适用于单线程下在字符缓冲区进行大量操作的情况;
StringBuffer适用多线程下字符缓冲区进行大量操作的情况。
4.String str = "aaa"与String str = new String(“aaa”)一样吗?
不一样,String str=“aaa”; 因为String 是final类型的,所以“aaa”应该是在常量池;而new String(“aaa”);则是新建对象放到堆内存中。
5.Java中Math类都有哪些方法?
pow():幂运算
sqrt():平方根
round():四舍五入
abs():求绝对值
random():生成一个0-1的随机数,[0,1)。
6.String类常用的方法
charAt():返回指定索引处的字符。
indexOf():返回指定字符的索引。
replace():字符串替换
trim():去除字符串两端空白
split():分割字符串,返回分割后的字符串数组
getBytes():返回字符串的byte类型数组
length():返回字符串长度
toLowerCase():将字符串转成小写字母
toUpperCase():将字符串转成大写字符
substring():截取字符串
format():格式化字符串
equals():字符串比较
7.Java中的继承是单继承还是多继承?
Java中是单继承,一个类只能有一个父类。
对于接口来说,一个类可以实现多个接口。
8.Super与this表示什么?
super表示当前类的父类对象
this表示当前类的对象
9.普通类和抽象类的区别?
(1)abstract修饰的类叫做抽象类;普通类不被abstract修饰。
(2)普通类中不能有抽象方法;抽象类可以包含抽象方法。
(3)抽象类不能直接实例化,普通类可以直接实例化。
10.什么是接口?为什么需要接口?
接口就是规范,就是某个事物对外提供的一些功能的声明,是一种特殊的Java类,接口弥补了Java单继承的缺点。
1.接口有什么特点?
接口中所有方法都是抽象方法;
接口没有构造方法;
接口不能直接实例化;
接口可以多继承。
2.抽象类和接口的区别?
(1)抽象类中可以有非抽象方法,接口中的方法全是抽象方法;
(2)关键字不同,抽象类是abstract,接口是interface;
(3)抽象类只能被继承;接口可以有多个类实现;
3.hashcode()?
(1)hashcode的存在主要是为了查找的快捷性,hashcode是用来散列存储结构中确定对象的存储地址的。
(2)如果两个对象equals相等,那么两个对象的hashcode一定也相同。
(3)如果对象的equals被重写,那么hashcode方法也尽量重写。
(4)如果两个对象的hashcode相同,不代表两个对象相同,只能说明这两个对象在散列存储结构中,存放于同一个位置。
4.Java的四种引用?
强引用:在程序内存不足的时候也不会被回收。
软引用:在程序内存不足的时候会被回收。
弱引用:只要JVM垃圾回收器发现了它,就会将之回收。
虚引用:跟弱引用差不多,但在回收之前,会被放入ReferenceQueue中。
5.Java中创建对象有几种方式?
(1)使用new创建对象
(2)通过反射机制
(3)采用done机制
(4)通过序列化机制
6.hashcode相同,对象一定相同吗?
不一定,在产生hash冲突时,两个不相等的对象就会有相同的hashcode值。
7.深拷贝和浅拷贝的区别?
深拷贝:深拷贝把要复制的对象所引用的对象都复制一遍。
浅拷贝:浅拷贝仅仅复制所考虑的对象,而不复制它所引用的对象。
8.static的用法?
static修饰的变量叫静态变量;
static修饰的方法叫静态方法;
static也用于静态代码块,多用于初始化操作;
static修饰的内部类,称为静态内部类;
static也可用于静态导包。
9.a = a + b 和 a += b有什么区别吗?
a += b :操作符会进行隐式自动类型转换,此处a+=b隐式的将加操作的结果类型强制转换为持有结果的类型;
a = a + b:不会自动进行类型转换.
10.final、finally、finalize()三者的区别?
性质不同:
(1)final是关键字
(2)finally为区块标志,用于try语句中
(3)finalize为方法
作用不同:
(1)final可以修饰类(不可被继承)、变量(不可被更改)、方法(不可被重写)。
(2)finally一般与try语句配合,不管try中的代码是否执行完,该代码块中的程序一定会执行。
(3)finalize是Object类中的方法,该方法由JVM调用用于对对象进行垃圾回收。
1.JDBC操作的步骤?
(1)加载驱动;
(2)获取连接;
(3)执行sql;
(4)返回结果;
(5)关闭资源。
2.使用JDBC的时候,如何防止出现sql注入的问题?
sql注入:欺骗服务器执行恶意的SQL命令。
使用PrepareStatement,而不是使用Statement。
PrepareStatement特点:使用占位符?表示SQL语句中的参数,通过set方法为SQL语句传入参数。
使用PrepareStatement的优点(相比Statement):
(1)安全性不同:PrepareStatement可以有效防止sql注入,而Statement不能防止sql注入。
(2)语法不同:PrepareStatement可以使用预编译的sql,而Statement只能使用静态的sql。
(3)效率不同:对于更改参数的同一SQL语句,PrepareStatement可以使用sql缓存区,效率比Statement高。
3.如何在JDBC内调用一个存储过程?
使用CallableStatement,CallableStatement对象是Statement对象的子类。
4.连接池?
数据库连接是非常消耗资源的,影响到程序的性能指标。连接池是用来分配、管理、释放数据库连接的,可以使应用程序重复使用同一个数据库连接,而不是每次都创建一个新的数据库连接。通过释放空闲时间较长的数据库连接避免数据库因创建太多的连接而造成的连接遗漏问题,提高程序性能。
5.数据源技术有哪些?使用数据源的好处?
dbcp,c3p0等,用的最多的是c3p0,因为c3p0比dbcp更加稳定,安全;通过配置文件的形式来维护数据库信息,而不是通过硬编码。当连接的数据库信息发生改变时,不需要再更改程序代码就实现了数据库信息的更新。
6.&和&&的区别?
&是位运算符,&&是逻辑运算符。
&&会造成短路现象,即如果前面内容是false,那么就不再处理后面的内容了;&则即使前为false,后面内容仍会处理。
7.静态内部类?
外部类中定义了一个static修饰的内部类,不依赖于外部类。
8.成员内部类?
可以获取到外部类的私有属性和方法。
9.什么是稀疏数组?
稀疏数组:当一个数组总大部分元素为0,或者为同一值的数组时,可以使用稀疏数组来保存该数组。
稀疏数组的
第一行:原数组行数,原数组列数,有效数字个数
第二行:第一个有效数字所在行数,第一个有效数字所在列数,第一个有效数字的值
第三行:第二个有效数字所在行数,第二个有效数字所在列数,第二个有效数字的值
…
10.数组的特点?
(1)长度是确定的。一旦创建,大小不可更改。
(2)元素必须是相同类型。
(3)元素可以是基本类型或引用类型。
(4)数组变量是引用类型,数组对象本身是在堆中的。
1.Java有没有goto?
goto是Java中的保留字,现在没有在Java中使用。
2.数组有没有length()方法?String有没有length()方法?
数组没有length()这个方法,有length的属性。String有length()这个方法。
3.最有效的方法算出2*8?
2<<3
左移<< 相当于乘以2
如:2<<3 相当于2*2*2*2=16
右移>> 相当于除以2
如:16>>3 相当于16/2/2/2=2
4.float型float f = 3.4是否正确?
不正确,精度不准确。应为float f = 3.4f或者float f =(float)3.4。
5.排序算法都有哪几种方法?
记忆法:
选泡插,
快归堆希桶计基。
选择排序,冒泡排序,插入排序,
快速排序,归并排序,堆排序,希尔排序,桶排序,计数排序,基数排序。
6.静态变量和实例变量的区别?
(1)静态变量需要static关键字修饰,实例变量不需要。
(2)静态变量从属于类,实例变量从属于对象。
(3)静态变量只被初始化一次,实例变量每次调用都会初始化。
(4)静态变量可以直接使用类名来调用,实例变量需要先创建该类对象,通过对象来调用。
7.常用类,包,接口各列举5个。
常用类:String, BufferedReader, BufferedWriter, FileReader, FileWriter,Integer
常用包:java.lang, java.util, java.sql, java.awt, java.io
常用接口:Remote, List, Map, Document, NodeList
8.a.hashcode()有什么用?与a.equals(b)有什么关系?
hashcode()方法是计算相应对象整型的hash值。
与a.equals(b)的关系:equals返回为true,则两者的hashcode一定相等,即相等的对象必须具有相等的哈希码,一般当equals方法被重写,通常需要重写hashcode方法从而保持对象行为的一致性。
9.Java中的编译期常量是什么?
公共静态不可变(public static final)变量就是编译期常量。
10.在Java中,如何跳出当前的多重嵌套循环?
使用break可以跳出循环,因此如果有用到死循环,一定要设置循环退出的条件,然后break。
1.构造器是否可以被重写?
构造器不能被继承,因此不能被重写,但可以被重载。
2.两个对象的equals相同,但却可有不同的hashcode,是否正确?
错误!两个对象的equals相同,它们的hashcode一定相同。但是hashcode相同,这两个对象不一定相同。
3.是否可以继承String类?
String类是final修饰的,不可以被继承。
4.当一个对象被当做参数传递到一个方法后,此方法可改变这个对象的属性,并可返回变化后的结果,那么这里是值传递还是引用传递?
是值传递,Java语言的方法调用只支持参数的值传递。当一个对象实例作为一个参数被传递到方法中时,参数的值就是对该对象的调用。
5.String和StringBuilder,StringBuffer的区别?
主要区别在两个方面,一个是运行效率,一个是线程安全。
运行效率方面:StringBuilder>StringBuffer>String
因为String是字符串常量,而另外两个均为字符串变量,即String对象一旦创建之后该对象是不可更改的。
线程安全方面:StringBuilder线程不安全,StringBuffer是线程安全的。
因此在对字符串操作时:
String适用于少量的字符串操作的情况;
StringBuilder适用于单线程下在字符缓冲区进行大量操作的情况;
StringBuffer适用多线程下字符缓冲区进行大量操作的情况。
6.如何实现对象克隆?
两种方式:
(1)实现cloneable接口并重写Object类中的clone()方法。
(2)实现Serializable接口,通过对象的序列化和反序列化实现克隆,可以实现真正的深度克隆。
7.Java中的异常和错误各列举5个。
/*
异常:
RuntimeException 运行时异常
ArrayIndexOutOfBoundsException 数组下标越界异常
ArithmeticException 算术异常
NullPointerException 空指针异常
MissingResourceException 丢失资源异常
ClassNotFoundException 找不到类
错误:
StackOverflowError 栈溢出
Virtual MachineError Java虚拟机运行错误
OutOfMemoryError 内存溢出错误
NoClassDefFoundError 定义错误
LinkageError 链接错误
*/
8.列举几个Java8的新特性。
(1)Lambda表达式
(2)方法的引用:方法引用使用一对冒号(:😃。
(3)默认方法:接口可以有实现方法。
(4)Stream API:把真正的函数式编程风格引入到Java中。
(5)Date Time API:加强对日期与时间的处理。
(6)Optional类:用来解决空指针异常。
9.Java中常用的端口号?
名称 | 端口号 |
---|---|
http服务器 | 80 |
Oracle | 1521 |
Zookeeper | 2181 |
MySQL | 3306 |
Redis | 6379 |
tomcat | 8080 |
10.写一个单例模式。
public class LazyMan{
private LazyMan(){}
//volatile为了保证原子性,避免指令重排(多线程情况下)
/*
new LazyMan()在JVM中其实是3个操作:
1.给lazyMan分配空间、
2.执行构造函数并初始化.
3.对象指向分配的内存空间
添加volatile的目的就是为了让这三步按顺序执行。
*/
private volatile static LazyMan lazyMan;
public static LazyMan getInstance(){
if(lazyMan == null){
synchronized(LazyMan.class){
if(lazyMan == null){
lazyMan = new LazyMan();
}
}
}
return lazyMan;
}
}