0
点赞
收藏
分享

微信扫一扫

JAVA八股文

Hyggelook 2022-03-30 阅读 65
java

1、谈谈面向对象的理解?面向对象与面向过程的区别? 面向对象的三个特性:

  1. 封装
    封装是指将类内部的实现细节隐藏,只提供调用接口,封装不仅可以有效保护数据,还可以提高代码可维护性
  2. 继承
    继承是指从现有类中继承基类的数据和方法,并拓展新的方法,继承可以提高代码的复用性和灵活性
  3. 多态
    多态是指类与类之间的关系。两个类有继承关系,存在方法的重写(override),子类的方法覆盖父类的方法。多态必备的三个要素:继承,重写,父类引用指向子类对象

2、 HashMap原理是什么,在jdk1.7和1.8中有什么区别

HashMap利用hash值存储数据,具有很快的访问速度,但是遍历顺序不确定。
HashMap 非线程安全,即任一时刻可以有多个线程同时写 HashMap,可能会导致数据的不一致。如果需要满足线程安全,可以用 Collections 的 synchronizedMap 方法使 HashMap 具有线程安全的能力,或者Hashtable,但是这两种方法效率不高(同步方法无竞争),也可以使用 ConcurrentHashMap。

JAVA1.7实现

请添加图片描述
总体上就是数组+单链表,这样当冲突发生次数较多时可能会造成查找性能下降,因为链表的查找时间复杂度是O(N)

JAVA1.8实现

最大的不同是HASHMAP变成了数组+链表+红黑树实现
在 Java8 中,当链表中的元素超过了 8 个以后,会将链表转换为红黑树,在这些位置进行查找的时候可以降低时间复杂度为 O(logN)
在这里插入图片描述

3、ArrayList和LinkedList有什么区别

区别:ArrayList底层由数组实现,LinkedList由链表实现

  • ArrayList查找的时间复杂度是O(1), 但对数据进行插入或删除操作复杂度是O(N)
  • LinkedList查找的时间复杂度是O(N),但是插入数据可以很快
  • 类似于插入数据,删除数据时, LinkedList 也优于 ArrayList
  • LinkedList 需要更多的内存,因为需要多存储结点信息
    适用场景:
    ArrayList 适用与查找多的场景
    LinkedList适用于增删多的场景

4、高并发中的集合有哪些问题

第一代线程安全集合类

Vector、Hashtable

是怎么保证线程安排的: 使用synchronized修饰方法*

缺点:效率低下

第二代线程非安全集合类

ArrayList、HashMap
线程不安全,但是性能好,用来替代Vector、Hashtable        
使用ArrayList、HashMap,需要线程安全怎么办呢?
使用 Collections.synchronizedList(list); Collections.synchronizedMap(m);

底层使用synchronized代码块锁 虽然也是锁住了所有的代码,但是锁在方法里边,并所在方法外边性能可以理解为稍有提高吧。毕竟进方法本身就要分配资源的

第三代线程安全集合类

在大量并发情况下如何提高集合的效率和安全呢?

java.util.concurrent.*

ConcurrentHashMap:

CopyOnWriteArrayList :

CopyOnWriteArraySet: 注意 不是CopyOnWriteHashSet*

底层大都采用Lock锁(1.8的ConcurrentHashMap不使用Lock锁),保证安全的同时,性能也很高。

jdk1.8的新特性有哪些

1、默认方法

interface My{
	//默认方法
   default void test(){
       
   }
}

默认方法是被default关键字修饰的方法,该方法是有方法体,并且该方法是可以不被接口的实现类重写的

2、Lambda 表达式

函数式编程
lambda表达式就和方法一样,它提供了一个正常的参数列表和一个使用这些参数的主体(body,可以是一个表达式或一个代码块)。

String[] atp = {"Rafael Nadal", "Novak Djokovic",  
       "Stanislas Wawrinka",  
       "David Ferrer","Roger Federer",  
       "Andy Murray","Tomas Berdych",  
       "Juan Martin Del Potro"};  
List<String> players =  Arrays.asList(atp);  
  
// 以前的循环方式  
for (String player : players) {  
     System.out.print(player + "; ");  
}  
  
// 使用 lambda 表达式以及函数操作(functional operation)  
players.forEach((player) -> System.out.print(player + "; "));  
   
// 在 Java 8 中使用双冒号操作符(double colon operator)  
players.forEach(System.out::println);

3、函数式接口

// 1.1使用匿名内部类  
new Thread(new Runnable() {  
    @Override  
    public void run() {  
        System.out.println("Hello world !");  
    }  
}).start();  
  
// 1.2使用 lambda expression  
new Thread(() -> System.out.println("Hello world !")).start();  
  
// 2.1使用匿名内部类  
Runnable race1 = new Runnable() {  
    @Override  
    public void run() {  
        System.out.println("Hello world !");  
    }  
};  
  
// 2.2使用 lambda expression  
Runnable race2 = () -> System.out.println("Hello world !");  
   
// 直接调用 run 方法(没开新线程哦!)  
race1.run();  
race2.run();

4、方法与构造方法的引用

java8可以让你通过关键字::来传递方法和构造函数的引用。

class Person { 
    String firstName; 
    String lastName;

    Person() {
    }

    Person(String firstName, String lastName) { 
    this.firstName = firstName; 
    this.lastName = lastName;
    } 
}

接下来我们指定一个用来创建Person对象的对象工厂接口:

interface PersonFactory<P extends Person> 
{ 
P create(String firstName, String lastName); 
}
PersonFactory<Person> personFactory = Person::new; 
Person person = personFactory.create("Peter", "Parker");

我们只需要使用 Person::new 来获取Person类构造函数的引用,Java编译器会自动根据PersonFactory.create方法的签名来选择合适的构造函数。

Java中重写和重载有哪些区别

方法的重载和重写都是实现多态的方式,区别在于前者实现的是编译时的多态性,而后者实现的是运行时的多态

  • 重载发生在一个类中,同名的方法如果有不同的参数列表(参数类型不同、参数个数不同或者二者都不同)则视为重载
  • 重写发生在子类与父类之间,重写要求子类被重写方法与父类被重写方法有相同的返回类型,比父类被重写方法更好访问

接口和抽象类有哪些区别

不同

  • 抽象类具有构造方法和具体方法,而接口没有

  • 抽象类的成员可以不是public的,而接口必须是public的

  • 抽象类可以有静态方法,而接口不可以

  • 一个类只能继承一个抽象类,而可以继承多个接口

  • 都不能实例化
  • 继承了抽象类或接口,必须实现其中的抽象方法或接口方法

怎样声明一个类不会被继承,什么场景下会用

如果一个类被final修饰,此类不可以有子类,不能被其它类继承,如果一个中的所有方法都没有重写的需要,当前类没有子类也罢,就可以使用final修饰类。

Java中==和equals有哪些区别

equals 和== 最大的区别是一个是方法一个是运算符。

==:如果比较的对象是基本数据类型,则比较的是数值是否相等;如果比较的是引用数据类型,则比较的是对象的地址值是否相等。

equals():用来比较方法两个对象的内容是否相等。

注意:equals 方法不能用于基本数据类型的变量,如果没有对 equals 方法进行重写,则比较的是引用类型的变量所指向的对象的地址。

String、StringBuffer、StringBuilder区别及使用场景

1)String 是只读字符串,也就意味着 String 引用的字符串内容是不能被改变的。初学者可能会有这样的误解:
2)StringBuffer/StringBuilder 表示的字符串对象可以直接进行修改。
3)StringBuilder 是 Java5 中引入的,它和 StringBuffer 的方法完全相同,区别在于它是在单线程环境下使用的,因为它的所有方法都没有被 synchronized 修饰,因此它的效率理论上也比 StringBuffer 要高

举报

相关推荐

Java八股文

java八股文

Java基础八股文

java八股文(并发)

Java八股文(Maven)

八股文|Java基础

Java八股文(Docker)

Java面试八股文

【八股文】Java基础

0 条评论