JAVA-SE-基础知识点面试必知1

1、面向对象的特征有哪些方面?

答:面向对象的特征主要有四个方面(三大特性中:没有抽象):

- 抽象:抽象是将一类对象的共同特征总结出来构造类的过程,包括数据抽象和行为抽象两方面。抽象只关注对象有哪些属性和行为,并不关注这些行为的细节是什么。

- 封装:封装就是隐藏一切可隐藏的东西,只向外界提供最简单的编程接口。通常认为封装是把数据和操作数据的方法绑定起来,对数据的访问只能通过已定义的接口。

- 继承:继承是从已有类得到继承信息创建新类的过程。提供继承信息的类被称为父类(超类、基类);得到继承信息的类被称为子类(派生类)。

- 多态性:多态性是指允许不同子类型的对象对同一消息作出不同的响应。简单的说就是用同样的对象引用调用同样的方法但是做了不同的事情。多态性分为编译时的多态性和运行时的多态性。

2访问修饰符public,private,protected,以及不写(默认)时的区别?

修饰符 当前类 同 包 子 类 其他包
public
protected ×
default × ×
private × × ×

类的成员不写访问修饰时默认为default。默认对于同一个包中的其他类相当于公开(public),对于不是同一个包中的其他类相当于私有(private)。受保护(protected)对子类相当于公开,对不是同一包中的没有父子关系的类相当于私有。Java中,外部类的修饰符只能是public或默认,类的成员(包括内部类)的修饰符可以是以上四种。

3 java中的数据类型?

     

基本数据类型:

byte:Java中最小的数据类型,在内存中占8位(bit),即1个字节,取值范围-128~127,默认值0

short:短整型,在内存中占16位,即2个字节,取值范围-32768~32717,默认值0

int:整型,用于存储整数,在内在中占32位,即4个字节,取值范围-2147483648~2147483647,默认值0

long:长整型,在内存中占64位,即8个字节-2^63~2^63-1,默认值0L

float:浮点型,在内存中占32位,即4个字节,用于存储带小数点的数字,默认值0

double:双精度浮点型,用于存储带有小数点的数字,在内存中占64位,即8个字节,默认值0

char:字符型,用于存储单个字符,占16位,即2个字节,取值范围0~65535,默认值为空

boolean:布尔类型,占1个字节,用于判断真或假(仅有两个值,即true、false),默认值false

引用数据类型:除过简单类型变量的定义,其变量都是引用数据类型;(对象传递等)

枚举类型:本质上是以类的形式存在;

enum Signal {  
    GREEN, YELLOW, RED  
}  
public class TrafficLight {  
    Signal color = Signal.RED; //类似   类名.属性   ;赋值
} 

4 不同类型赋值:

float f=3.4;是否正确?

答:不正确。3.4是双精度数,将双精度型(double)赋值给浮点型(float)属于下转型(down-casting,也称为窄化)会造成精度损失,因此需要强制类型转换float f =(float)3.4; 或者写成float f =3.4F;。

short s1 = 1; s1 = s1 + 1;有错吗?
答:错误,1为int类型,需要强制转换类型才能赋值给short型。而short s1 = 1; s1 += 1;可以正确编译,因为s1+= 1;相当于s1 = (short)(s1 + 1);其中有隐含的强制类型转换。

5包装类问题?

答:Java是一个近乎纯洁的面向对象编程语言,但是为了编程的方便还是引入了基本数据类型,但是为了能够将这些基本数据类型当成对象操作,Java为每一个基本数据类型都引入了对应的包装类型(wrapper class),int的包装类就是Integer,从Java 5开始引入了自动装箱/拆箱机制,使得二者可以相互转换。
Java 为每个原始类型提供了包装类型:

- 原始类型: boolean,char,byte,short,int,long,float,double

- 包装类型:Boolean,Character,Byte,Short,Integer,Long,Float,Double

 Integer a = new Integer(3);
        Integer b = 3;                  // 将3自动装箱成Integer类型
        int c = 3;
        System.out.println(a == b);     // false 两个引用没有引用同一对象
        System.out.println(a == c);     // true a自动拆箱成int类型再和c比较
   Integer a = 3;Integer b = 3;           System.out.println(a==b);     //true

   Integer a = 777;Integer b = 777;           System.out.println(a==b);     //false

原因详情原码。简单总结原码原因:如果整型字面量的值在-128到127之间,那么不会new新的Integer对象,而是直接引用常量池中的Integer对象。

6内存中的栈(stack)、堆(heap)和静态区(static area)的用法。

堆区:专门用来保存对象的实例(new 创建的对象和数组),实际上也只是保存对象实例的属性值,属性的类型和对象本身的类型标记等,并不保存对象的方法(方法是指令,保存在Stack中)

1.存储的全部是对象,每个对象都包含一个与之对应的class的信息。(class的目的是得到操作指令)
2.jvm只有一个堆区(heap)被所有线程共享,堆中不存放基本类型和对象引用,只存放对象本身.
3.一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收 。
栈区:对象实例在Heap 中分配好以后,需要在Stack中保存一个4字节的Heap内存地址,用来定位该对象实例在Heap 中的位置,便于找到该对象实例。
1.每个线程包含一个栈区,栈中只保存基础数据类型的对象和自定义对象的引用(不是对象),对象都存放在堆区中
2.每个栈中的数据(原始类型和对象引用)都是私有的,其他栈不能访问。
3.栈分为3个部分:基本类型变量区、执行环境上下文、操作指令区(存放操作指令)。
4.由编译器自动分配释放 ,存放函数的参数值,局部变量的值等.
静态区/方法区:
1.方法区又叫静态区,跟堆一样,被所有的线程共享。方法区包含所有的class和static变量。
2.方法区中包含的都是在整个程序中永远唯一的元素,如class,static变量。
3.全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域, 未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。

例:          String str = new String("hello");

变量str在栈中,动态分配的对象放在堆上,"hello"常量放在静态区。

7 数组有没有length()方法?String有没有length()方法?

答:数组没有length()方法,有length 的属性。String 有length()方法。

 int  a[]={2,3,4};
         System.out.println(a.length);
         String b="bbb";
         System.out.println(b.length());
JavaScript中,获得字符串的长度是通过length属性得到的,这一点容易和Java混淆。

8构造器(constructor)是否可被重写(override)?

答:构造器(构造函数)不能被继承,因此不能被重写,但可以被重载。

9、equals()和==的区别?

String str1 = new String("hello");  //堆中分配
		String str2 = new String("hello");
		String str3 = "hello";     //常量池中
		String str4 = "hello";
		System.out.println(str1 == str2); // false
		System.out.println(str1.equals(str2));// true
		System.out.println(str3 == str2); // false
		System.out.println(str3.equals(str2));// true
		System.out.println(str3 == str4); // true

注意问题:

如果两个对象不相同,他们的hashcode可能相同原因:

规范1:若重写equals(Object obj)方法,有必要重写hashcode()方法,确保通过equals(Object obj)方法判断结果为true的两个对象具备相等的hashcode()返回值。说得简单点就是:“如果两个对象相同,那么他们的hashcode应该 相等”。不过请注意:这个只是规范,如果你非要写一个类让equals(Object obj)返回true而hashcode()返回两个不相等的值,编译和运行都是不会报错的。不过这样违反了Java规范,程序也就埋下了BUG。 

规范2:如果equals(Object obj)返回false,即两个对象“不相同”,并不要求对这两个对象调用hashcode()方法得到两个不相同的数。 

根据这两个规范,可以得到如下推论: 
1、如果两个对象equals,Java运行时环境会认为他们的hashcode一定相等。 
2、如果两个对象不equals,他们的hashcode有可能相等。 
3、如果两个对象hashcode相等,他们不一定equals。 
4、如果两个对象hashcode不相等,他们一定不
equals。

10是否可以继承String类?

 答:String 类是final类,不可以被继承。     string原码:


11 当一个对象被当作参数传递到一个方法后,此方法可改变这个对象的属性,并可返回变化后的结果,那么这里到底是值传递还是引用传递?

答:是值传递。Java语言的方法调用只支持参数的值传递。当一个对象实例作为一个参数被传递到方法中时,参数的值就是对该对象的引用。对象的属性可以在被调用过程中被改变,但对对象引用的改变是不会影响到调用者的,仅仅有值传递不过可以通过对象的方式来实现引用传递 ,类似java没有多继承 但可以用多次implements接口实现多继承的功能;

12String,StringBuffer与StringBuilder的区别?

 答:1.运行效率:StringBuilder > StringBuffer > String。

   2.String为字符串常量,而StringBuilder和StringBuffer均为字符串变量,即String对象一旦创建之后该对象是不可更改的,但后两者的对象是变量,是可以更改的。StringBuilder是线程不安全的,而StringBuffer是线程安全的。由于StringBuffer中带有(锁)synchronized,所有处理速度比StringBuder慢!

    3.String:适用于少量的字符串操作的情况;

    StringBuilder:适用于单线程下在字符缓冲区进行大量操作的情况;(速度快)

    StringBuffer:适用多线程下在字符缓冲区进行大量操作的情况;(安全


13重载(Overload)和重写(Override)的区别。重载的方法能否根据返回类型进行区分?

  答:方法的重载和重写都是实现多态的方式,区别在于前者实现的是编译时的多态性,而后者实现的是运行时的多态性。重载发生在一个类中,同名的方法如果有不同的参数列表(参数类型不同、参数个数不同或者二者都不同)则视为重载;重写发生在子类与父类之间,重写要求子类被重写方法与父类被重写方法有相同的返回类型,比父类被重写方法更好访问,不能比父类被重写方法声明更多的异常(里氏代换原则)。重载对返回类型没有特殊的要求。

为何不能通过返回值来区分重载方法(华为面经):

void f(){} intf(){reurn1;}
比如在int x =f()中,那么的确可以据此却分重载方法。不过,有你想要的是方法调用的其他效果,这时你可能会调用方法而忽略其返回值。所以,如果像下面这样调用方法:f();此时Java如何才能判断该调用哪一个f()呢?因此,根据方法的返回值来区分重载方法是行不通的。

   

14抽象类(abstract class)和接口(interface)有什么异同?

  答:抽象类和接口都不能够实例化但可以定义抽象类和接口类型的引用。一个类如果继承了某个抽象类或者实现了某个接口都需要对其中的抽象方法全部进行实现,否则该类仍然需要被声明为抽象类。接口比抽象类更加抽象,因为抽象类中可以定义构造器,可以有抽象方法和具体方法,而接口中不能定义构造器而且其中的方法全部都是抽象方法(1.8新特性,可以增加实例方法,要有关键字)。抽象类中的成员可以是private、默认、protected、public的,而接口中的成员全都是public的。抽象类中可以定义成员变量,而接口中定义的成员变量实际上都是常量。有抽象方法的类必须被声明为抽象类,而抽象类未必要有抽象方法。两个都不能被final修饰;

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

class first{
	public final void str(){	
}
}
public class Text extends first {
 public int str(){               //编译器报错,覆盖了父类str(). 和底层的泛型擦除有关
		return 0;
}
}  

15char 型变量中能不能存贮一个中文汉字,为什么?
  答:char类型可以存储一个中文汉字,因为Java中使用的编码是Unicode(不选择任何特定的编码,直接使用字符在字符集中的编号,这是统一的唯一方法),一个char类型占2个字节(16比特),所以放一个中文是没问题的。不过,如果某个特殊的汉字没有被包含在unicode编码字符集中,那么,这个char型变量中就不能存储这个特殊汉字。
    补充:使用Unicode意味着字符在JVM内部和外部有不同的表现形式,在JVM内部都是Unicode,当这个字符被从JVM内部转移到外部时(例如存入文件系统中),需要进行编码转换。所以Java中有字节流和字符流,以及在字符流和字节流之间进行转换的转换流,如InputStreamReader和OutputStreamReader,这两个类是字节流和字符流之间的适配器类,承担了编码转换的任务;对于程序员来说,要完成这样的编码转换恐怕要依赖于union(联合体/共用体)共享内存的特征来实现了

16内部类详解:

      1. 内部类:静态内部类,非静态内部类(匿名内部类,局部内部类)。

      2.为什么使用内部类:

                      内部类的优点:i.封装性,隐藏操作;

                                             ii.内部类对象可以访问创建它的外部类对象的内容,甚至包括私有变量。(可以理解为类内私有 可访问)。

     3.静态内部类和非静态内部类区别:

     i.静态内部类没有了指向外部的引用。

     ii.静态内部类只可以访问外部类中的静态成员变量与成员方法,而非静态的内部类即可以访问所有的外部类成员方法与成员变量。(原因:静态不能访问非静态,非静态可以访问静态)

     iii.静态内部类不依赖外部类对象的生成。非静态内部类依赖外部类对象的生成。(原因:静态属于类。不属于对象单元)。

  4.实现手段:

       内部类:写在类的内部;(就如同写外类的方法一样,不过该方法是一个类)

       匿名内部类:写在类的方法体中,并且以返回生成类对象的形式完成;

       静态内部类:内部类加关键字static;

       局部内部类:将内部类写在外面类的方法体中;


17、抽象的(abstract)方法是否可同时是静态的(static),是否可同时是本地方法(native),是否可同时被synchronized修饰?

  答:都不能。抽象方法需要子类重写,而静态的方法是无法被重写的,因此二者是矛盾的。本地方法是由本地代码(如C代码)实现的方法,而抽象方法是没有实现的,也是矛盾的。synchronized和方法的实现细节有关,抽象方法不涉及实现细节,因此也是相互矛盾的。

18、阐述静态变量和实例变量的区别。

  答:静态变量是被static修饰符修饰的变量,也称为类变量,它属于类,不属于类的任何一个对象,一个类不管创建多少个对象,静态变量在内存中有且仅有一个拷贝;实例变量必须依存于某一实例,需要先创建对象然后通过对象才能访问到它。静态变量可以实现让多个对象共享内存。

19、String s = new String("xyz");创建了几个字符串对象?

答:两个对象,一个是静态区的"xyz",一个是用new创建在堆上的对象。

20、接口是否可继承extends接口?抽象类是否可实现(implements)接口?抽象类是否可继承具体类(concrete class)?

答:接口可以继承接口,而且支持多重继承。抽象类可以实现(implements)接口,抽象类可继承具体类也可以继承抽象类。

  注:实现接口用implements;多继承extends出现在接口间。类是不能多继承的。

      











全部评论

相关推荐

点赞 评论 收藏
转发
点赞 1 评论
分享
牛客网
牛客企业服务