Java核心知识点

1、Collection.sort排序内部原理:事实上Collections.sort方法底层就是调用的Arrays.sort方法,而Arrays.sort使用了两种排序方法,快速排序和优化的归并排序。快速排序主要是对那些基本类型数据(int,short,long等)排序, 而归并排序用于对Object类型进行排序。

2、HashMap原理:HashMap是数组+链表+红黑树实现的。HashMap最多只允许一条记录的键为null,允许多条记录的值为null。HashMap非线程安全,不保证有序(比如插入的顺序)、也不保证顺序不随时间变化。当出现冲突时,采用链地址法,即数组+链表的方法,将关键词为同义词的结点链接在一个单链表中,散列表长m,则定义一个由m个头指针组成的指针数组T,地址为i的结点插入以T(i)为头指针的单链表中。在链表长度大于8的时候,将后面的数据存在红黑树中,以加快检索速度。

3、String和StringBuilder区别:1)可变与不可变:String不可变,每一次执行“+”都会新生成一个新对象,所以频繁改变字符串的情况中不用String,以节省内存。2)是否多线程安全:StringBuilder并没有对方法进行加同步锁,所以是非线程安全的。StringBuffer和String均线程安全。

4、Vector和Array区别:1)ArrayList在内存不够时默认是扩展50% + 1个,Vector是默认扩展1倍。2)Vector属于线程安全级别的,但是大多数情况下不使用Vector,因为线程安全需要更大的系统开销。

5、HashMap和HashTable区别:1)Hashtable继承Dictonary类, HashMap继承自abstractMap;2) HashMap允许空的键值对, HashTable不允许;3) HashTable同步,而HashMap非同步,效率上比HashTable要高。

6、ArrayList和LinkedList区别:ArrrayList 底层的数据结构是数组,支持随机访问,而 LinkedList 的底层数据结构是链表,不支持随机访问。使用下标访问一个元素,ArrayList 的时间复杂度是 O(1),而 LinkedList 是 O(n)。LinkedList是双向链表。

7、抽象类和接口: 

        抽象类:用abstract修饰的类叫做抽象类,此类不能有对象,不能实例化(即不能有“new”),有抽象方法的类一定是抽象类(注:抽象方法即有abstract关键词,不能有方法体,即不能有"{}"),但抽象类中不一定有抽象方法。抽象类中的抽象方法必须在子类中被重写。抽象类注定要被继承,抽象方法注定要被重写。用抽象类是为了重用,提供“合理”的机制,减少编码量,降低耦合性。

        接口:规范化,类似抽象类,通过interface关键字定义。接口用implements去“实现”(而不是像类一样用extend来“继承”),即A类实现了B接口,此时A成为B接口的实现类。接口中的变量默认为“public static final ****”,默认方法为“public abstract ****”

        区别:继承是“单继承”,可以多对一,但不能一对多。但一个类却可以实现多个接口。

8、重载和重写:

        重载和重写都允许你用相同的名称来实现不同的功能,但是重载是编译时活动,而重写是运行时活动。你可以在同一个类中重载方法,但是只能在子类中重写方法。重写必须要有继承

        重写:1、在子类中可以根据需要对从基类中继承来的方法进行重写。2、重写的方法和被重写的方法必须具有相同方法名称、参数列表和返回类型。3、重写方法不能使用比被重写的方法更严格的访问权限。

        重载:方法名要一样,但是参数类型和个数不一样,返回值类型可以相同也可以不相同。无法以返回型别作为重载函数的区分标准。

9、Collection和Collections区别:Collection是Java集合框架中的基本接口;Collections是Java集合框架提供的一个工具类,其中包含了大量用于操作或返回集合的静态方法。

10、多态实现原理:父类引用指向子类对象,调用方法时会调用子类的实现而不是父类的实现。多态的实现的关键在于“动态绑定”。多态存在的三个必要条件:继承、重写、父类引用指向子类对象。

11、泛型和类型擦除:泛型即参数化类型,在创建集合时,指定集合元素的类型,此集合只能传入该类型的参数。类型擦除:java编译器生成的字节码不包含泛型信息,所以在编译时擦除:1.泛型用最顶级父类替换;2.移除。

12、JDK1.8新特性:1、Lambda 表达式;允许像对象一样传递匿名函数 Stream API,充分利用现代多核 CPU,可以写出很简洁的代码 ;2、Date 与 Time API,最终,有一个稳定、简单的日期和时间库可供你使用;3、扩展方法,接口中可以有静态、默认方法;4、重复注解,现在你可以将相同的注解在同一类型上使用多次。

13、public、private、protected:Protected可在包内及包外子类访问,default只能同一包内访问,prvate只能同一类。

14、常用数据结构:集合,线性结构(数组,队列,链表和栈),树形结构,图状结构。

15、TreeMap采用什么树:红黑树。

16、匿名内部类:即没有名字的内部类,匿名内部类只能使用一次,它通常用来简化代码编写。匿名内部类只能访问外部类的Final变量。

17、单例模式:

        特点:1、单例类只能有一个实例;2、单例类必须自己创建自己的唯一实例;3、单例类必须给所有其他对象提供这一实例。

        目的:单例模式确保某个类只有一个实例,而且自行实例化并向整个系统提供这个实例。选择单例模式就是为了避免不一致状态,避免政出多头。线程池、缓存、日志对象、对话框、打印机、显卡的驱动程序对象常被设计成单例。

        两种创建方法:

            懒汉式:特点是线程安全,调用效率不高,但是能延时加载。

            饿汉式:在类初始化时,已经自行实例化。特点是线程安全,调用效率高,但是不能延时加载。程序从头到位都没用使用这个单例的话,单例的对象还是会创建。这就造成了不必要的资源浪费。所以不推荐这种实现方式。

            双锁式:DCL也就是双重锁判断机制。由于JVM底层模型原因,偶尔会出问题,不建议使用。

            静态内部类:线程安全,调用效率高,可以延时加载。

            枚举类:线程安全,调用效率高,不能延时加载,可以天然的防止反射和反序列化调用)。

        如何选用:单例对象占用资源少,不需要延时加载,选取枚举优于饿汉式;单例对象占用资源多,需要延时加载,静态内部类优于懒汉式。

18、poll()和remove():都是从队列中取出一个元素,但是 poll() 在获取元素失败的时候会返回空,但是remove() 失败的时候会抛出异常。

19、内存溢出和内存泄漏:内存溢出是程序申请内存时,没有足够的内存,out of memory;内存泄漏指的是垃圾对象无法回收,可以使用memory analyzer工具查看泄漏。

20、进程与线程:进程是资源分配的最小单位,线程是程序执行的最小单位;进程有自己的独立地址空间,每启动一个进程,系统就会为它分配地址空间,建立数据表来维护代码段、堆栈段和数据段,这种操作非常昂贵;线程是共享进程中的数据的,使用相同的地址空间,因此CPU切换一个线程的花费远比进程要小很多,同时创建一个线程的开销也比进程要小很多;线程之间的通信更方便(不过如何处理好同步与互斥是编写多线程程序的难点),而进程之间的通信需要以通信的方式(IPC)进行;多进程程序更健壮,多线程程序只要有一个线程死掉。

21、堆和栈:堆和栈属于不同的内存区域。栈常用于保存方法帧和局部变量,而对象总是在堆上分配。栈通常都比堆小,也不会在多个线程之间共享,而堆被整个 JVM 的所有线程共享。

22、String类为什么是final的:为了“安全性”和“效率”,因为:1、由于String类不能被继承,所以就不会没修改,这就避免了因为继承引起的安全隐患;2、String类在程序中出现的频率比较高,如果为了避免安全隐患,在它每次出现时都用final来修饰,这无疑会降低程序的执行效率,所以干脆直接将其设为final一提高效率。

23、final、finalize、finally:

        final:不能被改变的,可以修饰类、变量和方法。被final修饰的类不能被继承;被final修饰的方法不能被重写;final修饰的变量,无论是类属性、对象属性、形参还是局部变量,都需要进行初始化操作。

        finally:作为异常处理的一部分,它只能用在try/catch语句中,并且附带一个语句块,表示这段语句最终一定会被执行(不管有没有抛出异常),经常被用在需要释放资源的情况下。

        finalize():每一个对象都有这么个方法。这个方法在gc启动,该对象被回收的时候被调用。其实gc可以回收大部分的对象(凡是new出来的对象,gc都能搞定,一般情况下我们又不会用new以外的方式去创建对象),所以一般是不需要程序员去实现finalize的。特殊情况下,需要程序员实现finalize,当对象被回收的时候释放一些资源,比如:一个socket链接,在对象初始化时创建,整个生命周期内有效,那么就需要实现finalize,关闭这个链接。

24、面向对象OOP:易维护、易复用、易扩展,由于面向对象有封装、继承、多态性的特性,可以设计出低耦合的系统,使系统更加灵活、更加易于维护。

        三大特征:1、封装,隐藏对象的属性和实现细节,仅对外提供公共访问方式,将变化隔离,便于使用,提高复用性和安全性;2、继承,提高代码复用性;继承是多态的前提;3、多态,父类或接口定义的引用变量可以指向子类或具体实现类的实例对象。提高了程序的拓展性。

        五大基本原则:1、单一职责原则SRP(Single Responsibility Principle),类的功能要单一,不能包罗万象;2、开放封闭原则OCP(Open-Close Principle),一个模块对于拓展是开放的,对于修改是封闭的;3、里式替换原则LSP(the Liskov Substitution Principle LSP),子类可以替换父类出现在父类能够出现的任何地方;4、依赖倒置原则DIP(the Dependency Inversion Principle),高层次的模块不应该依赖于低层次的模块,他们都应该依赖于抽象。抽象不应该依赖于具体实现,具体实现应该依赖于抽象;5、接口分离原则ISP(the Interface Segregation Principle),设计时采用多个与特定客户类有关的接口比采用一个通用的接口要好。

25、JAVA基本数据类型:byte、short、int、long、float、double、char、boolean。

26、JVM分为哪些区

        方法区:被所有的线程共享,方法区包含所有的类信息和静态变量。

        堆:被所有的线程共享,存放对象实例以及数组,Java堆是GC的主要区域。

        栈:每个线程包含一个栈区,栈中保存一些局部变量等。

        程序计数器:是当前线程执行的字节码的行指示器。

27、进程间通信有哪几种方式:管道(Pipe);命名管道(named pipe);信号(Signal);消息(Message)队列;共享内存;内存映射(mapped memory);信号量(semaphore);套接口(Socket)。

你可能感兴趣的:(Java核心知识点)