Java软件开发技术面试题总结二
Posted zhaochunhui
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java软件开发技术面试题总结二相关的知识,希望对你有一定的参考价值。
常见的基础内容:
Java 的命名规范:
Java是大小写敏感的,这就意味着标识符Hello与hello是不同的
java的变量命名规范:首字母:英文字母、$和下划线。变量名:由$、字母、数字和下划线组成。
类名:单个单词,首字母大写,多个单词,首字母都大写。
方法名、参数名、变量名:单个单词,首字母小写,多个单词,第一单词首字母小写,其他单词首字母大写。
包名:全部小写。
java的修饰符:
非访问控制修饰符 : final, abstract, static, synchronized
访问控制修饰符 : default, public , protected, private
java语言的变量类型:【全局变量是有默认值的,int类型默认值为0,string类型默认为null,局部变量必须要进行初始化】
1、类变量:独立与方法之外的变量,用static进行修饰
2、实例变量:独立于方法之外的变量,不过没有static进行修饰
3、局部变量:类的方法中的变量,局部变量必须要进行初始化
public class Variable
static int allClicks=0; // 类变量 ,全局变量
String str="hello world"; // 实例变量
public void method()
int i =0; // 局部变量
java枚举:【枚举可以单独声明或者声明在类里面。方法、变量、构造函数也可以在枚举中定义。使用枚举可以减少代码中的 bug。】
class FreshJuice
enum FreshJuiceSize SMALL, MEDIUM , LARGE
FreshJuiceSize size;
public class FreshJuiceTest
public static void main(String []args)
FreshJuice juice = new FreshJuice();
juice.size = FreshJuice.FreshJuiceSize.MEDIUM ;
Java的do,while循环【首先就是会进行do里面的内容的执行,然后在判断while的内容是不是符合规定,如果里面的条件是符合规定的,再次执行do里面的内容,直到不满足条件】
public class StringBase
public static void main(String[] args)
Scanner sc=new Scanner(System.in);
int a=sc.nextInt();
do
System.out.println(a);
a++;
while (a<=10);
System.out.println("结束");
while循环就是判断是不是满足while里面的内容,如果满足的执行while里面的循环体,如果不满足,就直接跳出
public class StringBase
public static void main(String[] args)
Scanner sc=new Scanner(System.in);
int a=sc.nextInt();
while (a<=10)
System.out.println(a);
a++;
System.out.println("结束");
instanceof(实例)【instanceof 严格来说是Java中的一个双目运算符,用来测试一个对象是否为一个类的实例,用法为:】
boolean result = obj instanceof Class
其中 obj 为一个对象,Class 表示一个类或者一个接口,当 obj 为 Class 的对象,或者是其直接或间接子类,或者是其接口的实现类,结果result 都返回 true,否则返回false。
throw和throws的区别
1、throws出现在方法函数头;而throw出现在函数体。
2、throws表示出现异常的一种可能性,并不一定会发生这些异常;throw则是抛出了异常,执行throw则一定抛出了某种异常。
3、两者都是消极处理异常的方式(这里的消极并不是说这种方式不好),只是抛出或者可能抛出异常,但是不会由函数去处理异常,真正的处理异常由函数的上层调用处理。
Java虚拟机
java虚拟机实际上只是一层接口,一层Java程序和操作系统通讯的接口。java文件编译生成class文件,
而java虚拟机就是这些class文件能够在上面运行的一个平台,你把class文件看成一个软件,java虚拟机就是这个软件可以运行的操作系统。
解释运行字节码程序(Java程序编译后产生)、消除平台差异性
使用Java虚拟机是实现这一特点的关键 一般的高级语言如果要在不同的平台上运行 至少需要编译成不同的目标代码 而引入Java语言虚拟机后 Java语言在不同平台上运行时不需要重新编译 Java语言使用模式Java虚拟机屏蔽了与具体平台相关的信息 使得Java语言编译程序只需生成在Java虚拟机上运行的目标代码(字节码)就可以在多种平台上不加修改地运行 Java虚拟机在执行字节码时 把字节码解释成具体平台上的机器指令执行
Java应用的特点
1、一个源文件中只能有一个public修饰的类,其他类个数不限。
2、一个源文件有n个类时,编译结果的class文件就有n个。
3、源文件的名字必须和public修饰的类名相同
4、java语言中单词拼写大小写严格区分。
5、main方法入口
6、每一句以分号(;)结束
Java类中方法的调用【在一个源文件中,只能有一个public修饰的类,并且在类中定义的 static方法,可以直接进行方法名的调用】
class test
public static void test4()
System.out.println("test4");
public void test1()
test4();//可以直接进行调用的
System.out.println("test1");
public class StringBase
public void test2()
System.out.println("test2");
public static void test3()
System.out.println("test3");
public static void main(String[] args)
test.test4();//静态方法可以直接用类名.方法名直接调用
test test=new test();
test.test1();//要定义类的对象,对象调用类里面的方法
StringBase sb=new StringBase();
sb.test2();
test3();//可以直接进行调用
执行结果:
test4
test4
test1
test2
test3
Java的单引号和双引号的区别:
单引号引的数据 是char类型的——》单引号只能引一个字符(表示单个字符)
双引号引的数据 是String类型的——》而双引号可以引0个及其以上(引用字符串)
首先单引号引起来的都是单字符例如:char a=‘a‘;这样是可以使用的,但是如果String a=‘a’ 和String a=‘aa‘ 这样就是会报错的,超过一位的字符就要使用String
三目运算符:X ? Y : Z
min=(a<b)?a:b;这样,在a<b的情况下,min=a,否则min=b
程序的流程控制
结构化程序的三种结构:顺序、选择(分支)、循环
switch的选择分支结构:
switch (a)
case 2:
System.out.println(3);
break;//加上break会跳出本次的switch选择结构
case 3:
System.out.println(3);
递归的特征:
函数有返回值类型、函数有参数、函数中有跳出循环的控制语句、自己调用自己
java的静态(static)
在静态的情况下:可以使用 类名.方法名 类名.属性名 这样的方式直接进行调用对应的属性或者是方法名.
也可以进行对象的创建,然后用对象进行属性或者是方法名的调用;
public class StringBase
static int a;//全局变量,类变量,初始默认值是0
public static void test3()
String test="test";
System.out.println("test3");
public static void main(String[] args)
System.out.println(StringBase.a);
StringBase.test3();
StringBase sb =new StringBase();
System.out.println(sb.a);
sb.test3();
在非静态的情况下,只能使用对象进行相应的调用
java中的this的使用
【在类的构造器中使用,并且this后面调用的全是本类中的资源(变量,方法{普通函数:this.test1();有参构造this(int n);无参构造this();})】
1、在有参构造中的使用,构造函数的默认类型是public
class Person
private String name;
private int age;
public Person(String name,int age)
this.name = name; //this.name明确表示调用类中name属性就近原则,不再使用
this.age = age;
public void getpersonInfo()
System.out.println("姓名:"+name+",年龄:"+age);
public class ThisTest
public static void main(String[] args)
Person per=new Person("张二",25);
per.getpersonInfo();
执行结果:姓名:张二,年龄:25
2、可以调用类中的方法
public class ThisTest
private String name;
private int age;
public ThisTest(String name,int age)
this.name = name;
this.age = age;//this.age表示本类属性
this.print("#############");//调用普通方法
public void print(String n)
System.out.println(n);
public String getpersonInfo()
return "姓名:"+name+",年龄:"+age;
public static void main(String[] args)
ThisTest per=new ThisTest("张三",30);
System.out.print (per.getpersonInfo());
执行结果:
#############
姓名:张三,年龄:30
3、调用类中的构造方法(有参构造方法/无参构造方法)
public class ThisTest
private String name;
private int age;
public ThisTest()
System.out.println("***产生一个新的person对象***");
public ThisTest(String name)
this();//调用本类中无参构造
this.name=name;
public ThisTest(String name,int age)
this(name);//调用本类有参构造
this.age=age;
public String getpersonInfo()
return "姓名:"+name+",年龄:"+age;
public static void main(String[] args)
ThisTest per1=new ThisTest();
System.out.println (per1.getpersonInfo());
ThisTest per2=new ThisTest("张二");
System.out.println (per2.getpersonInfo());
ThisTest per3=new ThisTest("张三",30);
System.out.println (per3.getpersonInfo());
执行结果:
***产生一个新的person对象***
姓名:null,年龄:0
***产生一个新的person对象***
姓名:张二,年龄:0
***产生一个新的person对象***
姓名:张三,年龄:30
java的super的使用
super是调用父类里面的资源(变量和类,this是调用本类中的资源和方法)
java初始化顺序。初始化子类必先初始化父类。子类的构造方法会隐式去调用 父类无参的构造方法(不会在代码中显示)。但如果父类没有无参的构造方法,就必须在子类构造方法第一行显示调用父类的有参构造方法。否则编译失败
1、子类继承父类的时候,会自动调用父类的无参构造器
class Person
Person()//无参构造器
System.out.println("person");
public class ThisTest extends Person
ThisTest()
System.out.println("ThisTest");
public static void main(String[] args)
ThisTest tt=new ThisTest();
执行结果:
person
ThisTest
2、子类调用父类的方法和属性【子类没有进行初始化,则父类的初始化也不会有要求,只有在子类进行构造器初始化的时候,才会涉及到父类里面的初始化】
class Country
String name;
void value()
System.out.println("china");
name = "China";
class ThisTest extends Country
String name;
void value()
name = "Hefei";
super.value();//不调用此方法时,super.name返回的是父类的成员变量的值null
System.out.println(name);
System.out.println(super.name);
public static void main(String[] args)
ThisTest c=new ThisTest();
c.value();
执行结果:
china
Hefei
China
3、子类调用父类中的构造方法(在子类中不写super的情况下,默认会调用父类的无参构造器,如果super中传入参数的话,会调用父类中对应的有参构造)
class Person
public static void prt(String s)
System.out.println(s);
Person()
prt("A Person.");
Person(String name)
prt("A person name is:" + name);
public class ThisTest extends Person
ThisTest()
super(); // 调用父类构造函数(1)
prt("A chinese.");// (4)
ThisTest(String name)
super(name);// 调用父类具有相同形参的构造函数(2)
prt("his name is:" + name);
ThisTest(String name, int age)
this(name);// 调用当前具有相同形参的构造函数(3)
prt("his age is:" + age);
public static void main(String[] args)
ThisTest cn = new ThisTest();
cn = new ThisTest("kevin");
cn = new ThisTest("kevin", 22);
执行结果:
A Person.
A chinese.
A person name is:kevin
his name is:kevin
A person name is:kevin
his name is:kevin
his age is:22
java的final关键字
1、final可以修饰全局变量,并且在进行变量创建的时候,必须要进行初始化;也可以修局部变量,但是也必须要进行初始化赋值
static final int a=0;
2、final修饰方法,对final修饰的方法,用子类继承父类时候,是不可以进行重写的
class Animal
public final void move() //用final进行修饰方法时候,子类是无法进行重写父类方法的
System.out.println("动物可以动");
class Dog extends Animal
public void move()
System.out.println("狗可以跑和走");
public class ThisTest
public static void main(String[] args)
Animal a = new Animal(); // Animal 对象
Animal b = new Dog(); // Dog 对象,由父类创建的子类对象
a.move();// 执行 Animal 类的方法
b.move();//执行 Dog 类的方法
执行结果:报错:
Error:(9, 17) java: com.zch.springboot_mybatis.Dog中的move()无法覆盖com.zch.springboot_mybatis.Animal中的move()
被覆盖的方法为final
3、final修饰类,则此类无法在进行继承
final class Animal
public void move() //用final进行修饰方法时候,子类是无法进行重写父类方法的
System.out.println("动物可以动");
class Dog extends Animal
public void move()
System.out.println("狗可以跑和走");
public class ThisTest
public static void main(String[] args)
Animal a = new Animal(); // Animal 对象
Animal b = new Dog(); // Dog 对象,由父类创建的子类对象
a.move();// 执行 Animal 类的方法
b.move();//执行 Dog 类的方法
执行结果:
报错:Error:(8, 19) java: 无法从最终com.zch.springboot_mybatis.Animal进行继承
java面向对象的三大特性
1、封装(可以提高代码的的安全性):
将属性进行私有化,并且提供对外界的接口(get/set方法)
用private进行修饰属性和方法,并且只能在本类中进行使用
2、继承(可以提高代码的复用性,减少重复代码)
子类可以继承父类的非私有的属性和方法,但是不可以继承父类的构造方法以及私有属性和方法
子类在继承父类的元素的时候,也可以进行修改(重写)
一个子类只能继承一个父类,必须是单继承
子类可以通过使用super进行参数的传递,进行父类的有参构造器的初始化
3、多态性:
运行时多态性:重写(子类继承父类的方法进行重写,但是子类方法的访问类型要大于父类的访问类型)
编译时多态性:重载(重载就是同名方法的不同参数)
java的抽象类(用abstract进行修饰的类)
1、如果一个类里面有抽象方法,那么这个类必须定义为抽象的;
2、抽象类是不能进行创建对象的,因为抽象类不能进行实例化
3、继承抽象类,使用的关键字是extends
Java的接口(interface)
1、实现接口用implements关键字
2、接口中只有全局变量和抽象方法
3、接口在实现的时候,同时去继承,extends在implements前面
Java排序算法:
1、冒泡排序
public class MaoPao
public static void main(String []args )
int a[]=1,3,4,5,2,7,6,10,9,8;
for(int i=0;i<a.length-1;i++)//控制外循环的次数
for(int j=0;j<a.length-1-i;j++)//控制内循环次数,比外循环少一次,与下一个比较
if(a[j]>a[j+1])
int temp=a[j];
a[j]=a[j+1];
a[j+1]=temp;
2、选择排序
public class MaoPao
public static void main(String []args )
int a[]=1,3,4,5,2,7,6,10,9,8;
for (int i = 0; i < a.length-1; i++)
int k=i;
for (int j = i; j < a.length-1; j++)
if (a[k]>a[j+1])
k=j+1;
if(i!=k)
int temp=a[i];
a[i]=a[k];
a[k]=temp;
for (int i=0; i<a.length;i++)
System.out.println(a[i]);
Java的StringBuffer用法
String 长度不可变
StringBuffer 长度可变 线程安全 速度慢
StringBuilder 长度可变 线程不安全 速度快
StringBuffer sb=new StringBuffer("a");
System.out.println(sb);
sb.append("b");//追加
System.out.println(sb);
sb.insert(2,"cde");//在指定位置进行插入
System.out.println(sb);
sb.delete(2,3);//在指定位置进行删除
System.out.println(sb);
sb.reverse();//反向逆转
System.out.println(sb);
执行结果:
a
ab
abcde
abde
edba
Java的线程与进程
1、多线程,从宏观的角度看就是同时执行多个进程,在微观的角度看待就是同一时间只能执行一个线程
2、进程是应用程序,线程就是一条执行路径
3、在一个进程中,至少有一个线程
4、开启一个线程,可以继承Thread的类,重写run方法,然后创建类对象,然后对象.start();
class ThreadTest extends Thread
//继承Thread类,重写run()方法
@Override
public void run()
System.out.println(Thread.currentThread().getName()+"执行Run中");
System.out.println(Thread.currentThread().getName()+"执行完毕");
public class ExtendThread
public static void main(String[] args)
new ThreadTest().start();
new ThreadTest().start();
new ThreadTest().start();
new ThreadTest().start();
new ThreadTest().start();
还可以通过实现 Runnable接口,重写run方法,创建类对象,然后new Thread(类对象).start 然后通过start来启动多线程
class ThreadTest implements Runnable
//实现Runnable接口,实现run()方法
@Override
public void run()
System.out.println(Thread.currentThread().getName()+"执行Run中");
System.out.println(Thread.currentThread().getName()+"执行完毕");
public class ExtendThread
public static void main(String[] args)
ThreadTest runnable = new ThreadTest();
new Thread(runnable).start();
new Thread(runnable).start();
new Thread(runnable).start();
new Thread(runnable).start();
new Thread(runnable).start();
首先run是没有开辟新的栈空间,没有新线程,都是主程序在执行
start开辟了新的栈空间,在新的栈空间里面启动run()方法
tcp和udp
1、tcp:面向连接,数据传输是可靠的,传输效率 偏低,传输数据的大小没有限制
2、udp:面向无连接,数据安全不可靠,执行效率比较高,数据的大小不超过64kb
【tcp和udp只是传输协议,只是设定了规范,真正起到传输作用的是数据ip协议】
【ip协议:将数据从源传递到目的地,ipv4是32位,ipv6是128位】
Java的反射机制
反射就是将Java类中的信息进行拆分,包括属性、方法、构造方法,并且可以进行调用
优点:
1、提高了Java程序的灵活性和拓展性,降低了耦合性,提高了自适应的能力
2、允许程序创建和控制任何类的对象,无需提前编码目标类
get和post的区别:
GET产生一个TCP数据包;POST产生两个TCP数据包。
GET比POST更不安全,因为参数直接暴露在URL上,所以不能用来传递敏感信息。
对参数的数据类型,GET只接受ASCII字符,而POST没有限制。
GET请求会被浏览器主动cache,而POST不会
在类中不能直接进行运算,要写在方法代码块或者静态代码块中static中
public abstract class MaoPao
public int constInt = 5;
consInt=constInt+5;
private static void testMethod()
System.out.println("testMethod");
public static void main(String[] args)
((MaoPao)null).testMethod();
这样在里面consInt=constInt+5;是会报错的
Java在多线程下的sleep和 wait()
共同点 :
1. 他们都是在多线程的环境下,都可以在程序的调用处阻塞指定的毫秒数,并返回。
2. wait()和sleep()都可以通过interrupt()方法 打断线程的暂停状态 ,从而使线程立刻抛出InterruptedException。
如果线程A希望立即结束线程B,则可以对线程B对应的Thread实例调用interrupt方法。如果此刻线程B正在wait/sleep/join,则线程B会立刻抛出InterruptedException,在catch() 中直接return即可安全地结束线程。
需要注意的是,InterruptedException是线程自己从内部抛出的,并不是interrupt()方法抛出的。对某一线程调用 interrupt()时,如果该线程正在执行普通的代码,那么该线程根本就不会抛出InterruptedException。但是,一旦该线程进入到 wait()/sleep()/join()后,就会立刻抛出InterruptedException 。
不同点 :
1.每个对象都有一个锁来控制同步访问。Synchronized关键字可以和对象的锁交互,来实现线程的同步。
sleep方法没有释放锁,而wait方法释放了锁,使得其他线程可以使用同步控制块或者方法。
2.wait,notify和notifyAll只能在同步控制方法或者同步控制块里面使用,而sleep可以在任何地方使用
3.sleep必须捕获异常,而wait,notify和notifyAll不需要捕获异常
4.sleep是线程类(Thread)的方法,导致此线程暂停执行指定时间,给执行机会给其他线程,但是监控状态依然保持,到时后会自动恢复。调用sleep不会释放对象锁。
5.wait是Object类的方法,对此对象调用wait方法导致本线程放弃对象锁,进入等待此对象的等待锁定池,只有针对此对象发出notify方法(或notifyAll)后本线程才进入对象锁定池准备获得对象锁进入运行状态。
以上是关于Java软件开发技术面试题总结二的主要内容,如果未能解决你的问题,请参考以下文章
如何在二三线城市月薪过万5年面试的经验,万字吐血总结2021年java面试题
如何在二三线城市月薪过万5年面试的经验,万字吐血总结2021年java面试题