几个常见java面试题

1. Java中==和equals的区别.

a.基本数据类型 == 跟 equals 结果一样
b. 引用类型, == 比较的是两个引用类型的地址是否相同; equals如果未重写,跟==一样
通常情况下,equals方法会重写,重写后一般比较的是值是否相同。比如:String就是重写了equals方法.。当创建 String类型的对象时,虚拟机会在常量池中查找有没有已经存在的值和要创建的值相同的对象,如果有就把它赋给当前引用。如果没有就在常量池中重新创建一个 String对象。

2. Try-catch-finally的finally块中代码在什么情况下会执行, 什么情况下不会执行?

以下3中情况下不会执行finally语句 :
a.如果在try 或catch语句中执行了System.exit(0)。
b.在执行finally之前jvm崩溃。
c.try语句中执行死循环。

3. synchronized 和 volatile 的区别是什么?

a. synchronized修饰方法,代码块,变量都行;volatile一般只修饰变量。
b. synchronized,可以保证变量修改的可见性及原子性,可能会造成线程的阻塞;synchronized在锁释放的时候会将数据写入主内存,保证可见性;
volatile仅能实现变量修改的可见性,但无法保证原子性,不会造成线程的阻塞;volatile修饰变量后,每次读取都是去主内存进行读取,保证可见性
c. synchronized修饰普通方法,锁的是方法的调用者,也就是对象。
synchronized修饰静态方法,锁的是当前类的class对象。
synchronized修饰代码块,可以设置为锁对象,或者锁引用类型的变量、常量。
d. volatile不会造成线程的阻塞;synchronized可能会。
e. volatile标记不会编译器优化;而synchronized标记的变量会。

4. 写一个标准的单例模式.

public class Singleton1 {
    
    
	//volatile修饰,防止指令重排
    private static volatile Singleton1 instance;
    private Singleton1() {
    
    }
    public static Singleton1 getInstance() {
    
    
        //第一重校验,检查实例是否存在
        if (instance == null) {
    
    
            //同步块
            synchronized (Singleton1.class) {
    
    
                //第二重校验,检查实例是否存在,如果不存在才真正创建实例
                if (instance == null) {
    
    
                    instance = new Singleton1();
                }
            }
        }
        return instance;
    }
}

5.http1.1和2.0有哪些区别?

可以参考

6. 有一个继承父类的子类,它们都包含有属性, 静态属性, 实例初始化块, 静态初始化块, 和构造函数. 当通过new构造此子类的时候, 写出各个属性, 初始化块以及构造函数的执行顺序.

父类静态属性
父类静态代码块
子类静态属性
子类静态代码块
父类实例属性
父类实例代码块
父类构造方法
子类实例属性
子类实例代码块
子类构造方法
子类普通方法


public class ExecutionSequence {
    
    
    public static void main(String[] args) throws Exception {
    
    
        SuperF su = new Sub();
        su.tetsExpands();
    }
}

class SuperF{
    
    

    static String staticField = "父类静态属性";
    static {
    
    
        System.out.println(staticField);
        System.out.println("父类静态代码块");
    }
    String instanceField = "父类实例属性";
    {
    
    
        System.out.println(instanceField);
        System.out.println("父类实例代码块");
    }
    public static void staticMethods() {
    
    
        System.out.println("父类静态方法");
    }
    public SuperF(){
    
    
        System.out.println("父类构造方法");
    }
    public void tetsExpands() {
    
    
        System.out.println("父类普通方法");
    }

}

class Sub extends SuperF{
    
    
    static String staticField = "子类静态属性";
    static {
    
    
        System.out.println(staticField);
        System.out.println("子类静态代码块");
    }
    String instanceField2 = "子类实例属性";
    {
    
    
        System.out.println(instanceField2);
        System.out.println("子类实例代码块");
    }
    public static void staticMethods() {
    
    
        System.out.println("子类静态方法");
    }
    public Sub(){
    
    
        System.out.println("子类构造方法");
    }
    public void tetsExpands() {
    
    
        System.out.println("子类普通方法");
    }
}

7.HashMap, HashTable与ConcurentHashMap的区别

  • 简单点说, 复杂了,这玩意几个小时
    a.hashMap的键合值都可以为空,但是hashtable、ConcurrentHashMap的键值都不可以为空;
    b.hashtable的大部分方法都是由关键字synchronized修饰,因此是线程安全的。
    c.hashtable、ConcurrentHashMap都是线程安全的,hashMap是非线程安全的;
    d.hashtable是一个过时的类,多线程高并发情况下优先使用线程安全的ConcurrentHashMap。

8.db索引的作用以及什么情况下需要建立索引?

a.索引类似于书籍的目录,提高数据检索的效率,减少数据库IO的成本
b.通过索引列对数据进行排序,降低数据排序的成本,降低CPU的消耗

1.某个字段在SELECT/UPDATE/DELETE语句的 WHERE条件中经常被使用到,通常需要给这个字段加索引;
尤其是在数据量大的情况下,创建普通索引就可以大幅提升数据查询的效率;
原理是因为我们需要先根据 WHERE 条件列检索出来这条记录,然后再对它进行更新或删除
2.索引就是让数据按照某种顺序进行存储或检索,因此当我们使用GROUP BY对数据进行分组查询,或者使用ORDER BY对数据进行排序的时候,
通常需要对分组或者排序的字段进行索引。如果待排序的列有多个,那么可以在这些列上建立组合索引。
3.多表JOIN 连接操作时,创建索引时,连接表的数量尽量不要超过3张,因为每增加一张表就相当于增加了一次嵌套的循环,数量级增长会非常快,严重影响查询的效率
4.有大量重复数据的列上不要建立索引
5.不建议用无序的值作为索引
6.不要定义冗余或重复的索引

9. 如果保证Redis与db的一致性?

a.采用延时双删策略
1.先删除缓存
2.再写数据库
3.休眠一定的毫秒
4.再次删除缓存

b.MySQL binlog增量订阅消费+消息队列+增量数据更新到redis
1.读Redis :热数据基本都在 Redis
2.写MySQL :增删改都是操作 MySQL
3.更新Redis数据:MySQL 的数据操作binlog,来更新到 Redis
读取binlog后分析,利用消息队列,推送更新各台的 redis 缓存数据。
canal(阿里的开源框架),通过该框架可以对MySQL的 binlog进行订阅,而 canal模仿了mysql 的slave数 据库的备份请求,使得 Redis的数据更新达到了相同的效果。

10.谈谈你对CAP理论的理解, 举一个例子简单说明它实现了CAP中的哪些属性.

CAP理论,是指在一个互相连接且共享数据的分布式系统中,当涉及读写操作时,只能保证一致性(Consistence)、可用性(Availability)、分区容错性(Partition tolerance)三者中的两个,三者不可兼得。
CAP理论关注的是数据的读写操作,而不是分布式系统的所有功能。像分布式系统的负载均衡、容错等都不是CAP理论的讨论范围。
故,CAP理论针对的是互相连接并且共享数据的分布式系统的数据的读写操作。

Zookeeper保证的是CP
​ 保证的是CP 当向注册中心查询服务列表时,我们可以容忍注册中心返回的是几分钟以前的注册信息,但不能接受服 务直接down掉不可用。也就是说,服务注册功能对可用性的要求要高于一致性。但是zk会出现这样一种 情况,当master节点因为网络故障与其他节点失去联系时,剩余节点会重新进行leader选举。问题在 于,选举leader的时间太长,30~120s,且选举期间整个zk集群都是不可用的,这就导致在选举期间注 册服务瘫痪。在云部署的环境下,因为网络问题使得zk集群失去master节点是较大概率会发生的事件, 虽然服务最终能够恢复,但是漫长的选举时间导致的注册长期不可用是不能容忍的。

Eureka保证的是AP
​ Eureka看清了这一点,因此在设计时就优先保证可用性。Eureka的各个节点是平等的,几个节点挂掉不会影响正常节点的工作,剩余节点依然可以提供注册和查询服务。而Eureka的客户端在向某个Erueka注册时,如果发现连接失败,则会自动切换其他至节点,只要有一台Erueka还在,就能保证服务的可用性,只不过查到的信息可能不是最新的,除此之外,Eureka还有一种自我保护机制,如果在15分钟内超过85%的节点没有正常的心跳,那么Erueka就认为客户端与主持中心出现了网络故障,此时会出现以下几种情况:
1.Eureka不再从注册列表中移除因为长时间没有收到心跳的服务。
2.Eureka仍然能接受新的服务注册和查询请求,但是不会同步到其他节点上(即保证当前节点依然可用)。
3.当网络稳定,当前实例新的注册信息会被同步到其他节点中。

猜你喜欢

转载自blog.csdn.net/u013080870/article/details/129182848