• 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)后本线程才进入对象锁定池准备获得对象锁进入运行状态。
     
     
  • 相关阅读:
    一个JS的问题,请帮下忙!
    开始练习VS2003了
    SQL查询结果的合并问题
    几个微软的好东西!
    对谷歌输入发的一点疑虑
    Visual studio 2005 sdk 安装引起的后果
    Socket协议测试:TPS偏低,和响应时间计算出来的TPS不相符的问题
    数据库索引失效
    挡板模拟器桩模块驱动模块
    nmon 监控结果
  • 原文地址:https://www.cnblogs.com/zhaochunhui/p/11629564.html
Copyright © 2020-2023  润新知