Java 知识点总结

 

Java 基础

1、Object 对象的方法有哪些?分别有什么作用?该什么场景用?

2、Integer 的常量缓存池

3、Java 特性?什么是多态?举个例子

Object 的 hashcode 方法重写了,equals 方法要不要改?

4、重载重写的区别?

Object 类中的方法

 equals hashcode toString,clone, notify() notifyAll(),wait()

hashcode 和 equals 方法常用地方

对象比较是否相同

1.比较对象时, ==比较的是地址,而equals()比较的是对象内容

2.重写equals()方法必须重写hashCode()

 

Java线程池

常见问答:

线程池的原理,为什么要创建线程池?创建线程池的方式;

为什么要创建线程池?

1.线程切换需要上下文切换开销,同时线程池中的工作线程可以被重复利用,可以执行多个任务

2. 可以根据实际需要设置线程池工作线程数目,避免内存消耗过多。

ThreadLocal 了解吗?项目有用过吗?可以说说

里面包含了一个ThreadLocalMap

 void createMap(Thread t, T firstValue) {
        t.threadLocals = new ThreadLocalMap(this, firstValue);
    }

JUC 里面你还知道什么其他的类吗?比如 CountDownLatch、Condition

从源码详细说下 Java 里面的线程池吧,使用线程池有什么要注意的地方?你们公司有规范吗?

 

线程

常见问答

线程的生命周期,什么时候会出现僵死进程;

僵尸进程(Zombie process)通俗来说指那些虽然已经终止的进程,但仍然保留一些信息,等待其父进程为其收尸。也就是说父进程没有结束,但是子进程结束了,父进程没死,没办法给子进程收尸,真的是只有父进程死了才能收尸

 

说说线程安全问题,什么实现线程安全,如何实现线程安全;

什么是线程安全?

线程安全是指在多线程运行环境下,某个函数被多次调用,都能够正确处理各个线程的局部变量,并且程序功能正确。

如何实现线程安全?

有三种方式 

1.使用ThreadLocal , 替每个线程维护线程安全的本地变量

2.使用Synchronized和lock 为需要访问的资源加锁,进行同步控制。

3.使用JUC下面的线程安全集合类 ConcurrentHashMap,Atomic原子类等

volatile、ThreadLocal的使用场景和原理;

 

ThreadLocal什么时候会出现OOM的情况?为什么?

ThreadLocal中存在一个ThreadLocalMap,其中的key值是弱引用的,会被回收掉,但是value不会被自动回收

  static class Entry extends WeakReference<ThreadLocal<?>> {
            /** The value associated with this ThreadLocal. */
            Object value;

            Entry(ThreadLocal<?> k, Object v) {
                super(k);
                value = v;
            }
        }

 

synchronized、volatile区别、synchronized锁粒度、模拟死锁场景、原子性与可见性;

 作用域 :synchronized   可以加载方法,变量,代码块上

                 voliatile 只能加载变量上 

线程阻塞

volatile不会造成线程阻塞

synchronized会造成线程阻塞

可见性 原子性

synchronized 可以保证原子性和可见性

volatile 只能保证可见性

模拟死锁场景

public class DeadLockSynchronizedTest {

    /**
     * @param args
     */
    public static void main(String[] args) {
        Object a = new Object();
        Object b = new Object();
        Thread t = new Thread(new Runnable() {
            @Override
            public void run() {
                testA(a, b);
            }
        });

        Thread t1 = new Thread(new Runnable() {
            @Override
            public void run() {
                testB(a, b);
            }
        });
        t.start();
        t1.start();

    }

    /**
     * @param a
     * @param b
     */
    private static void testB(Object a, Object b) {
        System.out.println("Entering into testB");
        synchronized (b) {
            System.out.println(Thread.currentThread() + "获得 锁 b");
            synchronized (a) {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread() + "获得 锁 a");
            }
        }

    }

    /**
     * @param a
     * @param b
     */
    private static void testA(Object a, Object b) {
        System.out.println("Entering into testA");
        synchronized (a) {
            System.out.println(Thread.currentThread() + "获得 锁 a");
            synchronized (b) {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread() + "获得 锁 b");
            }
        }

    }

}

 

 

Synchronized和ReentrantLock 区别

讲下 Synchronized?

Synchronized 和 RecentLock 有什么区别?这两个有没有深入了解源码?

1讲下 Volatile 吧?他是怎样做到同步的?

Volatile 为什么不支持原子性?举个例子

1Atomic 怎么设计的?有用过里面的类吗?

线程安全类和线程不安全的类,项目使用的时候你会怎么选择?怎么判断项目代码哪里会有线程不安全问题?

synchronized、lock

lock 需要主动释放锁

lock实现 基于AbstractQueuedSynchronizer  队列同步器 CAS 实现的

 

讲下 RecentLock 可重入锁? 什么是可重入锁?为什么要设计可重入锁?

 

如何避免死锁?

死锁的4个条件

  • 互斥条件:所谓互斥就是进程在某一时间内独占资源。
  • 请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。 
  • 不剥夺条件:进程已获得资源,在末使用完之前,不能强行剥夺。  
  • 循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。

资源互斥是无法改变的,可以改变其他三个条件避免死锁

  1. 破坏“不可剥夺”条件:一个进程不能获得所需要的全部资源时便处于等待状态,等待期间他占有的资源将被隐式的释放重新加入到 系统的资源列表中,可以被其他的进程使用,而等待的进程只有重新获得自己原有的资源以及新申请的资源才可以重新启动,执行。
  2. 破坏”请求与保持条件“:第一种方法静态分配即每个进程在开始执行时就申请他所需要的全部资源。第二种是动态分配即每个进程在申请所需要的资源时他本身不占用系统资源。
  3. 破坏“循环等待”条件:采用资源有序分配其基本思想是将系统中的所有资源顺序编号,将紧缺的,稀少的采用较大的编号,在申请资源时必须按照编号的顺序进行,一个进程只有获得较小编号的进程才能申请较大编号的进程。

 

JVM

1、JAVA 类加载器

线上服务 CPU 很高该怎么做?有哪些措施可以找到问题

2、Java 内存结构(注:不是 Java 内存模型,别搞混)

3、怎么判断对象是否可 GC?Java 对象有哪些引用类型?有什么区别?

4、OOM 出现的有哪些场景?为什么会发生?

5、Minor GC 和 Full GC 有什么区别?分析过 GC 日志吗?

6、说下你知道的垃圾回收算法

7、说下你知道的垃圾收集器

8、CMS 和 G1 的区别知道吗?使用场景分别是?你项目中用的是哪个?

CMS 并行收集器  G1 将堆分成一个个区域,判断哪个区域垃圾最多,优先回收

9、你还知道哪些 JVM 调优参数?

10、假如线上服务发生 OOM,有哪些措施可以找到问题?

11、假如线上服务 CPU 很高该怎么做?有哪些措施可以找到问题?

12、假如线上应用频繁发生 Full GC,有哪些措施可以找到问题?

13、一般线上环境遇到 JVM 问题,你会使用哪些工具来分析?找到问题后又该如何去解决呢?

GC分哪两种,Minor GC 和Full GC有什么区别?什么时候会触发Full GC?分别采用什么算法?

Eden空间不够,触发Minor GC

老年代空间不够(新生代晋升,大对象进入),触发 Major GC 

新生代一般采用 复制算法

老年代垃圾回收一般采用的是 标记整理算法

 

常见的JVM调优方法有哪些?可以具体到调整哪个参数,调成什么值?

jstatc -gc 

jmap -histo:live pid 

jmap -dump:live,format=b,file=dump.hprof 24971

导出文件 使用Mat 分析,内存泄露,溢出等

JVM虚拟机内存划分、类加载器、垃圾收集算法、垃圾收集器、class文件结构是如何解析的

 内存划分   堆 永久代, 栈 (本地方法栈,虚拟机栈)程序计数器

    

 

 

Java集合

常见问答:

HashMap内部的数据结构是什么?底层是怎么实现的?(还可能会延伸考察ConcurrentHashMap与HashMap、HashTable等,考察对技术细节的深入了解程度)

HashMap 中怎么解决冲突的?

使用链表

ConcurrentHashMap 和 HashTable 中线程安全的区别?为啥建议用 ConcurrentHashMap ?能把 ConcurrentHashMap 里面的实现详细的讲下吗?

5、画下 HashMap 的结构图?HashMap 、 HashTable 和 ConcurrentHashMap 的区别?使用场景分别是?

8、保证线程安全的还有其他的方式吗?

16、Map、List、Set 分别说下你了解到它们有的线程安全类和线程不安全的类?

17、TreeSet 清楚吗?能详细说下吗?

11、HashMap 和 hashTable 区别?

13、Hashmap 线程不安全的出现场景

ArrayList 和 LinkedList 区别

17、如果存取相同的数据,ArrayList 和 LinkedList 谁占用空间更大?

18、Set 存的顺序是有序的吗?

19、常见 Set 的实现有哪些?

TreeSet 对存入对数据有什么要求呢?

HashSet 的底层实现呢?

使用的是HashMap实现的

TreeSet 底层源码有看过吗?

HashSet 是不是线程安全的?为什么不是线程安全的?

没加锁

Java 中有哪些线程安全的 Map?

Concurrenthashmap

Concurrenthashmap 是怎么做到线程安全的?

使用了synchronized 和CAS

    public V put(K key, V value) {
        return putVal(key, value, false);
    }

    /** Implementation for put and putIfAbsent */
    final V putVal(K key, V value, boolean onlyIfAbsent) {
        if (key == null || value == null) throw new NullPointerException();
        int hash = spread(key.hashCode());
        int binCount = 0;
        for (Node<K,V>[] tab = table;;) {
            Node<K,V> f; int n, i, fh;
            if (tab == null || (n = tab.length) == 0)
                tab = initTable();
            else if ((f = tabAt(tab, i = (n - 1) & hash)) == null) {
                if (casTabAt(tab, i, null,
                             new Node<K,V>(hash, key, value, null)))
                    break;                   // no lock when adding to empty bin
            }
            else if ((fh = f.hash) == MOVED)
                tab = helpTransfer(tab, f);
            else {
                V oldVal = null;
                // 修改某个节点时 采用了同步控制
                synchronized (f) {
                    if (tabAt(tab, i) == f) {
                        if (fh >= 0) {
                            binCount = 1;
                            for (Node<K,V> e = f;; ++binCount) {
                                K ek;
                                if (e.hash == hash &&
                                    ((ek = e.key) == key ||
                                     (ek != null && key.equals(ek)))) {
                                    oldVal = e.val;
                                    if (!onlyIfAbsent)
                                        e.val = value;
                                    break;
                                }
                                Node<K,V> pred = e;
                                if ((e = e.next) == null) {
                                    pred.next = new Node<K,V>(hash, key,
                                                              value, null);
                                    break;
                                }
                            }
                        }
                        else if (f instanceof TreeBin) {
                            Node<K,V> p;
                            binCount = 2;
                            if ((p = ((TreeBin<K,V>)f).putTreeVal(hash, key,
                                                           value)) != null) {
                                oldVal = p.val;
                                if (!onlyIfAbsent)
                                    p.val = value;
                            }
                        }
                    }
                }
                if (binCount != 0) {
                    if (binCount >= TREEIFY_THRESHOLD)
                        treeifyBin(tab, i);
                    if (oldVal != null)
                        return oldVal;
                    break;
                }
            }
        }
        addCount(1L, binCount);
        return null;
    }

HashTable 你了解过吗?

线程安全的Hash表,使用Synchronized同步控制

    public synchronized V put(K key, V value) {
        // Make sure the value is not null
        if (value == null) {
            throw new NullPointerException();
        }

        // Makes sure the key is not already in the hashtable.
        Entry<?,?> tab[] = table;
        int hash = key.hashCode();
        int index = (hash & 0x7FFFFFFF) % tab.length;
        @SuppressWarnings("unchecked")
        Entry<K,V> entry = (Entry<K,V>)tab[index];
        for(; entry != null ; entry = entry.next) {
            if ((entry.hash == hash) && entry.key.equals(key)) {
                V old = entry.value;
                entry.value = value;
                return old;
            }
        }

        addEntry(hash, key, value, index);
        return null;
    }

HashMap

数据结构: 数组 +链表/红黑树

线程不安全

put

get 

HashTable实现原理

数据结构: 数组+链表

线程安全

ConcurrentHashMap实现原理

JDK1.6基于分段锁的

JDK1.8 是基于 Synchronized和CAS的

synchronized 的用处: put的时候,节点上加synchronized

final V putVal(K key, V value, boolean onlyIfAbsent) {
        if (key == null || value == null) throw new NullPointerException();
        int hash = spread(key.hashCode());
        int binCount = 0;
        for (Node<K,V>[] tab = table;;) {
            Node<K,V> f; int n, i, fh;
            if (tab == null || (n = tab.length) == 0)
                tab = initTable();
            else if ((f = tabAt(tab, i = (n - 1) & hash)) == null) {
                if (casTabAt(tab, i, null,
                             new Node<K,V>(hash, key, value, null)))
                    break;                   // no lock when adding to empty bin
            }
            else if ((fh = f.hash) == MOVED)
                tab = helpTransfer(tab, f);
            else {
                V oldVal = null;
               // 节点加锁
                synchronized (f) {
                    if (tabAt(tab, i) == f) {
                        if (fh >= 0) {
                            binCount = 1;
                            for (Node<K,V> e = f;; ++binCount) {
                                K ek;
                                if (e.hash == hash &&
                                    ((ek = e.key) == key ||
                                     (ek != null && key.equals(ek)))) {
                                    oldVal = e.val;
                                    if (!onlyIfAbsent)
                                        e.val = value;
                                    break;
                                }
                                Node<K,V> pred = e;
                                if ((e = e.next) == null) {
                                    pred.next = new Node<K,V>(hash, key,
                                                              value, null);
                                    break;
                                }
                            }
                        }
                        else if (f instanceof TreeBin) {
                            Node<K,V> p;
                            binCount = 2;
                            if ((p = ((TreeBin<K,V>)f).putTreeVal(hash, key,
                                                           value)) != null) {
                                oldVal = p.val;
                                if (!onlyIfAbsent)
                                    p.val = value;
                            }
                        }
                    }
                }
                if (binCount != 0) {
                    if (binCount >= TREEIFY_THRESHOLD)
                        treeifyBin(tab, i);
                    if (oldVal != null)
                        return oldVal;
                    break;
                }
            }
        }
        addCount(1L, binCount);
        return null;
    }

CAS 使用

    /**
     * Helps transfer if a resize is in progress.
     */
    final Node<K,V>[] helpTransfer(Node<K,V>[] tab, Node<K,V> f) {
        Node<K,V>[] nextTab; int sc;
        if (tab != null && (f instanceof ForwardingNode) &&
            (nextTab = ((ForwardingNode<K,V>)f).nextTable) != null) {
            int rs = resizeStamp(tab.length);
            while (nextTab == nextTable && table == tab &&
                   (sc = sizeCtl) < 0) {
                if ((sc >>> RESIZE_STAMP_SHIFT) != rs || sc == rs + 1 ||
                    sc == rs + MAX_RESIZERS || transferIndex <= 0)
                    break;
                // CAS 判断是否获得扩容权限
//第一个参数是要修改的对象,第二个参数是对象中要修改变量的偏移量,第三个参数是修改之前的值,第四个参数是预想修改后的值....
                if (U.compareAndSwapInt(this, SIZECTL, sc, sc + 1)) {
                    transfer(tab, nextTab);
                    break;
                }
            }
            return nextTab;
        }
        return table;
    }

 

ConcurrentHashMap 数据结构

问题: List 和 Map 区别,Arraylist 与 LinkedList 区别,ArrayList 与 Vector 区别;

Arraylist

数据结构: 数组

扩容:1.5倍扩容

 private void grow(int minCapacity) {
        // overflow-conscious code
        int oldCapacity = elementData.length;
        int newCapacity = oldCapacity + (oldCapacity >> 1);
        if (newCapacity - minCapacity < 0)
            newCapacity = minCapacity;
        if (newCapacity - MAX_ARRAY_SIZE > 0)
            newCapacity = hugeCapacity(minCapacity);
        // minCapacity is usually close to size, so this is a win:
        elementData = Arrays.copyOf(elementData, newCapacity);
    }

LinkedList

数据结构:链表

add 方法

 public boolean add(E e) {
        linkLast(e);
        return true;
    }
 
void linkLast(E e) {
        final Node<E> l = last;
        final Node<E> newNode = new Node<>(l, e, null);
        last = newNode;
        if (l == null)
            first = newNode;
        else
            l.next = newNode;
        size++;
        modCount++;
    }

Vector

数据结构:数组

线程安全

扩容: 2倍扩容

 private void grow(int minCapacity) {
        // overflow-conscious code
        int oldCapacity = elementData.length;
        int newCapacity = oldCapacity + ((capacityIncrement > 0) ?
                                         capacityIncrement : oldCapacity);
        if (newCapacity - minCapacity < 0)
            newCapacity = minCapacity;
        if (newCapacity - MAX_ARRAY_SIZE > 0)
            newCapacity = hugeCapacity(minCapacity);
        elementData = Arrays.copyOf(elementData, newCapacity);
    }

add 方法

   public synchronized boolean add(E e) {
        modCount++;
        ensureCapacityHelper(elementCount + 1);
        elementData[elementCount++] = e;
        return true;
    }

 

TreeMap

 

 

 

 

 

NIO 

NIO是什么?适用于何种场景?

http://www.importnew.com/21341.html

Java9比Java8改进了什么?

增加了.jshell

.改进了 Stream API

 

 

 

反射

说说反射的用途及实现,反射是不是很慢,我们在项目中是否要避免使用反射;

反射的用途

 

说说自定义注解的场景及实现;

 

 

 

Spring

1、说下你对 Spring 生态的了解?

2、说下你对 Spring AOP 和 IOC 的理解?看过实现原理吗?

3、说下 Bean 在 Spring 中的生命周期?

4、讲下你知道的 Spring 注解有哪些?该什么场景使用?

5、Spring 事务知道吗?有了解过吗?

6、说下你刚才说的 SpringBoot 吧,你觉得 SpringBoot 有什么优点?

7、SpringBoot 自动化配置是怎么做的?有看过实现源码吗?

8、Spring Boot 中最核心的注解 SpringBootApplication 有看过源码分析过吗?

9、你的项目中 SpringBoot 用到了哪些和其他技术栈整合的?

10、使用 Spring 或者 SpringBoot 有遇到过什么印象深刻的问题吗?当时是怎么解决的?

Spring AOP的实现原理和场景?

 

Spring bean的作用域和生命周期

1.实例化

2.按照 Spring 上下文对实例化的 Bean 进行配置, 也就是 IOC 注入。

3.setBeanName 的实现,如果这个 Bean 已经实现了 BeanNameAware 接口,会调用它实现的 setBeanName(String)
方法,此处传递的就是 Spring 配置文件中 Bean 的 id 值

4.BeanFactoryAware 实现,如果这个 Bean 已经实现了 BeanFactoryAware 接口,会调用它实现的 setBeanFactory,
setBeanFactory(BeanFactory)传递的是 Spring 工厂自身(可以用这个方式来获取其它 Bean,
只需在 Spring 配置文件中配置一个普通的 Bean 就可以

5.ApplicationContextAware 实现
如果这个 Bean 已经实现了 ApplicationContextAware 接口,会调用
setApplicationContext(ApplicationContext)方法,传入 Spring 上下文(同样这个方式也
可以实现步骤 4 的内容,但比 4 更好,因为 ApplicationContext 是 BeanFactory 的子接
口,有更多的实现方法)

6.postProcessBeforeInitialization 实现
如果这个 Bean 关联了 BeanPostProcessor 接口,将会调用
postProcessBeforeInitialization(Object obj, String s)方法, BeanPostProcessor 经常被用
作是 Bean 内容的更改,并且由于这个是在 Bean 初始化结束时调用那个的方法,也可以被应
用于内存或缓存技术

7. init-methmod 方法如果 Bean 在 Spring 配置文件中配置了 init-method 属性会自动调用其配置的初始化方法。

8.postProcessAfterInitialization 实现
 如果这个 Bean 关联了 BeanPostProcessor 接口,将会调用
postProcessAfterInitialization(Object obj, String s)方法。
注: 以上工作完成以后就可以应用这个 Bean 了,那这个 Bean 是一个 Singleton 的,所以一
般情况下我们调用同一个 id 的 Bean 会是在内容地址相同的实例,当然在 Spring 配置文件中
也可以配置非 Singleton。

9.Destroy 过期自动清理阶段
当 Bean 不再需要时,会经过清理阶段,如果 Bean 实现了 DisposableBean 这个接口,会调
用那个其实现的 destroy()方法;

10.destroy-method 自配置清理
最后,如果这个 Bean 的 Spring 配置中配置了 destroy-method 属性,会自动调用其配置的
销毁方法。

bean标签有两个重要的属性(init-methmod和destroy-methmod).可以用他们自定义注解的初始化和注销方法,也有响应的注解(@PostConstruct和@PreDestroy)

<bean id="" class="" init-methmod="初始化方法" destroy-methmod="销毁方法">

Spring Boot比Spring做了哪些改进? Spring 5比Spring4做了哪些改进;

 

如何自定义一个Spring Boot Starter?

 

Spring IOC是什么?优点是什么?


SpringMVC、动态代理、反射、AOP原理、

 

六、中间件篇

1、Dubbo的底层实现原理和机制

2、描述一个服务从发布到被消费的详细过程

3、分布式系统怎么做服务治理

4、接口的幂等性的概念

5、消息中间件如何解决消息丢失问题

Dubbo的服务请求失败怎么处理

DubboInvoker.doInvoke//为什么DubboInvoker是个protocol? 因为RegistryDirectory.refreshInvoker.toInvokers: protocol.refer

7、重连机制会不会造成错误

8、对分布式事务的理解

9、如何实现负载均衡,有哪些算法可以实现?

10、Zookeeper的用途,选举的原理是什么?

11、数据的垂直拆分水平拆分。

12、zookeeper原理和适用场景

zookeeper watch机制

允许客户端向服务端注册监听,当一些特定事件触发时,Zookeeper服务器将通知到感兴趣的客户端上去

14、redis/zk节点宕机如何处

15、分布式集群下如何做到唯一序列号

16、如何做一个分布式锁

Dubbo完整的一次调用链路介绍;

 

Dubbo支持几种负载均衡策略?

 

Dubbo Provider服务提供者要控制执行并发请求上限,具体怎么做?

 

Dubbo启动的时候支持几种配置方式?

 

了解几种消息中间件产品?各产品的优缺点介绍;

 

消息中间件如何保证消息的一致性和如何进行消息的重试机制?

 

Spring Cloud熔断机制介绍;

 

Spring Cloud对比下Dubbo,什么场景下该使用Spring Cloud?

 

数据库

 

事务的隔离级别?

PROPAGATION_SUPPORTS --支持当前事务,如果当前没有事务,就以非事物的方式运行

PROPAGATION_MANDATORY 支持当前事务,如果当前没有事务,就抛出异常

PROPAGATION_REQUIRES_NEW 新建事务

锁机制介绍:行锁、表锁、排他锁、共享锁;

 

乐观锁的业务场景及实现方式;

 

事务介绍,分布式事物的理解,常见的解决方案有哪些,什么事两阶段提交、三阶段提交;

 

MySQL记录binlog的方式主要包括三种模式?每种模式的优缺点是什么?

 

MySQL锁,悲观锁、乐观锁、排它锁、共享锁、表级锁、行级锁;

 

分布式事务的原理2阶段提交,同步\异步\阻塞\非阻塞;

 

数据库事务隔离级别,MySQL默认的隔离级别、Spring如何实现事务、JDBC如何实现事务、嵌套事务实现、分布式事务实现;

 

SQL的整个解析、执行过程原理、SQL行转列;

 

SQL 优化

 

Redis

 

Redis为什么这么快?redis采用多线程会有哪些问题?

采用单线程,避免了不必要的上下文切换和竞争条件,也不存在多进程或者多线程导致的切换而消耗 CPU,不用去考虑各种锁的问题,不存在加锁释放锁操作,没有因为可能出现死锁而导致的性能消耗;

 

1.发送命令

2.命令排队

3.执行命令

4.返回结果

Redis支持哪几种数据结构;

 

Redis跳跃表的问题;

zset 使用的是hash 和跳表

Redis单进程单线程的Redis如何能够高并发?

 

Redis如何使用Redis实现分布式锁?

 

Redis分布式锁操作的原子性,Redis内部是如何实现的?

九、其他

 

看过哪些源代码?然后会根据你说的源码问一些细节的问题?(这里主要考察面试者是否对技术有钻研的精神,还是只停留在表面,还是背了几道面经,这个对于很多有强迫症的面试官,如果你连源码都没看过,基本上是会pass掉的,比如我也是这样的!)

 

项目中遇到了哪些比较有挑战性的问题,是如何解决的;(这个很有争议,一方面是你连一个复杂的问题都解决不了,要你过来干什么,还有就是我的能力牛逼啊,但是公司没有业务场景让我展示啊!这个就看你遇到的面试官了,祝你好运!)

 

自我和项目相关

1、自我介绍

2、你觉得自己的优点是?你觉得自己有啥缺点?

3、你有哪些 offer?

4、你为什么要离开上家公司?你上家公司在xxx,我们公司在xxx,离这么远为什么要选择我们这里?

5、上家公司的同事和领导是怎么评价你的?

6、介绍下你的上家公司是做哪块的吧

7、在上家公司你做了哪些项目?

8、你在项目中是什么角色?

9、这个项目的数据量和并发量多大?

10、这个项目用的什么技术?

11、项目过程中有遇到什么很印象深刻的问题吗?

12、是怎么解决的这些问题?

13、项目有没有还可以继续优化的地方?

14、该怎么优化?有什么思路没?

15、叫你设计一个并发xxx,数据存储量xxx 量级的系统,你该如何设计?从你知道的点尽可能的多说出些?

 

数据库

1、你的项目使用的是什么数据库?

2、你对数据库了解多少?说下数据库的索引实现和非主键的二级索引

3、说下 MySQL 的索引原理

4、讲下 InnoDB 和 MyISAM 的区别?使用场景是?

5、有和 ElasticSearch 的索引原理对比过吗?

6、如何判断一个查询 sql 语句是否使用了索引?

7、数据库事务特性和隔离级别

8、项目数据库表是你设计的吗?一般要注意什么?如何考虑扩展性?

9、项目 MySQL 的数据量和并发量有多大?量大后的影响有哪些,有考虑吗?SQL 调优有哪些技巧?

10、说下你项目里面关于数据库印象最深的一个问题?当时是怎么解决的

其他

1、描述下网页一个 Http 请求,到后端的整个请求过程

2、有比较过 Http 和 RPC 吗?如果叫你设计一个高性能的 Http 或者 RPC,你会从哪些方面考虑?

3、项目中我看使用了 xxx (ElasticSearch、Hbase、Redis、Flink 等),有深入了解它们的原理和懂点调优技巧吗?

4、项目中我看使用了 xxx (ElasticSearch、Hbase、Redis、Mysql 等),有深入了解它们数据同步是怎么做吗?

5、项目中我看使用了 xxx (ElasticSearch、Hbase、Redis、Mysql 等),有深入了解它们常见的监控指标吗?

6、如果叫你设计一个秒杀系统,你会从哪些方面考虑?

7、如果叫你设计一个电商系统,你会从哪些方面考虑?

8、如果叫你设计一个监控告警系统,你会从哪些方面考虑?

总结

本文的面试题以 HR & 技术官角度常问的面试题,技术方面从 Java 基础、JVM、Spring、数据库、拓展题等方面考察你,当然面试官可能还会问些其他的技术点,我一篇文章也难以概全。总的来说,还是得多准备充分,面试时灵活答辩,相信你最后能拿到满意的 offer!加油,骚年!

 

 

电话一面

1、自我介绍、自己做的项目和技术领域

2、项目中的监控:那个监控指标常见的有哪些?

3、微服务涉及到的技术以及需要注意的问题有哪些?

4、注册中心你了解了哪些?

5、consul 的可靠性你了解吗?

6、consul 的机制你有没有具体深入过?有没有和其他的注册中心对比过?

7、项目用 Spring 比较多,有没有了解 Spring 的原理?AOP 和 IOC 的原理

8、Spring Boot除了自动配置,相比传统的 Spring 有什么其他的区别?

9、Spring Cloud 有了解多少?

 

15、JDK 中有哪几个线程池?顺带把线程池讲了个遍

16、SQL 优化的常见方法有哪些

   SQL优化

17、SQL 索引的顺序,字段的顺序

18、查看 SQL 是不是使用了索引?(有什么工具)

19、TCP 和 UDP 的区别?TCP 数据传输过程中怎么做到可靠的?

20、说下你知道的排序算法吧

21、查找一个数组的中位数?

22、你有什么问题想问我的吗?


 

电话二面(85 分钟)

1、自我介绍、工作经历、技术栈

2、项目中你学到了什么技术?(把三项目具体描述了很久)

3、微服务划分的粒度

4、微服务的高可用怎么保证的?

5、常用的负载均衡,该怎么用,你能说下吗?

6、网关能够为后端服务带来哪些好处?

8、xml 中配置的 init、destroy 方法怎么可以做到调用具体的方法?

9、反射的机制
 

 

13、hashmap put 方法存放的时候怎么判断是否是重复的

// equal 方法判断
if (p.hash == hash &&
                ((k = p.key) == key || (key != null && key.equals(k))))
                e = p;

14、Object toString 方法常用的地方,为什么要重写该方法

POJO 类必须写 toString 方法。使用 IDE 的中工具: source> generate toString
时,如果继承了另一个 POJO 类,注意在前面加一下 super.toString。
说明: 在方法执行抛出异常时,可以直接调用 POJO 的 toString()方法打印其属性值,便于排
查问题。

Set 和 List 区别?

Set是map改造得到的key值唯一 list 有数组和链表,key可以重复

 

如何保证线程安全问题?

1. ThreadLocal 

2.同步控制

3.原子变量

 

abstract static class Sync extends AbstractQueuedSynchronizer {
        private static final long serialVersionUID = -5179523762034025860L;

        /**
         * Performs {@link Lock#lock}. The main reason for subclassing
         * is to allow fast path for nonfair version.
         */
        abstract void lock();

        /**
         * Performs non-fair tryLock.  tryAcquire is implemented in
         * subclasses, but both need nonfair try for trylock method.
         */
        final boolean nonfairTryAcquire(int acquires) {
            final Thread current = Thread.currentThread();
            int c = getState();
            if (c == 0) {
                if (compareAndSetState(0, acquires)) {
                    setExclusiveOwnerThread(current);
                    return true;
                }
            }
            else if (current == getExclusiveOwnerThread()) {
                int nextc = c + acquires;
                if (nextc < 0) // overflow
                    throw new Error("Maximum lock count exceeded");
                setState(nextc);
                return true;
            }
            return false;
        }

        protected final boolean tryRelease(int releases) {
            int c = getState() - releases;
            if (Thread.currentThread() != getExclusiveOwnerThread())
                throw new IllegalMonitorStateException();
            boolean free = false;
            if (c == 0) {
                free = true;
                setExclusiveOwnerThread(null);
            }
            setState(c);
            return free;
        }

29、volatile 的原子性问题?为什么 i++ 这种不支持原子性?从计算机原理的设计来讲下不能保证原子性的原因

 

30、happens before 原理

31、cas 操作

32、lock 和 synchronized 的区别?

33、公平锁和非公平锁

34、Java 读写锁

35、读写锁设计主要解决什么问题?

36、你项目除了写 Java 代码,还有前端代码,那你知道前端有哪些框架吗?

37、MySQL 分页查询语句

38、MySQL 事务特性和隔离级别

39、不可重复读会出现在什么场景?

40、sql having 的使用场景

41、前端浏览器地址的一个 http 请求到后端整个流程是怎么样?能够说下吗?

42、http 默认端口,https 默认端口

43、DNS 你知道是干嘛的吗?

DNS 域名解析,大概有10个步骤

1.浏览器检查缓存中有没有域名对应的Ip

2. 如果缓存中没有,查找操作系统是否缓存了DNS解析结果,windows 下,一般在 /etc/hosts

目录

3.如何怎么知道域名服务器? 

操作系统将域名发送到LDNS,这个DNS通常是指提供本地互联网的一个DNS解析服务

4. 

你们开发用的 ide 是啥?你能说下 idea 的常用几个快捷键吧?

CTRL +F

CTRK+H

CTRL+K

45、代码版本管理你们用的是啥?

svn

46、git rebase 和 merge 有什么区别?

 

Spring 注解

@Component就是跟<bean>一样,可以托管到Spring容器进行管理。

@Service@Controller , @Repository = {@Component + 一些特定的功能}。这个就意味着这些注解在部分功能上是一样的。

当然,下面三个注解被用于为我们的应用进行分层:

@Controller注解类进行前端请求的处理,转发,重定向。包括调用Service层的方法 
@Service注解类处理业务逻辑 
@Repository注解类作为DAO对象(数据访问对象,Data Access Objects),这些类可以直接对数据库进行操作 
有这些分层操作的话,代码之间就实现了松耦合,代码之间的调用也清晰明朗,便于项目的管理;假想一下,如果只用@Controller注解,那么所有的请求转发,业务处理,数据库操作代码都糅合在一个地方,那这样的代码该有多难拓展和维护。

 

1、多个线程同时读写,读线程的数量远远大于写线程,你认为应该如何解决并发的问题?你会选择加什么样的锁?

2、JAVA的AQS是否了了解,它是干嘛的?

3、除了synchronized关键字之外,你是怎么来保障线程安全的?

4、什么时候需要加volatile关键字?它能保证线程安全吗?

5、线程池内的线程如果全部忙,提交一个新的任务,会发生什什么?队列6、全部塞满了之后,还是忙,再提交会发生什么?

7、Tomcat本身的参数你⼀一般会怎么调整?

8、synchronized关键字锁住的是什么东西?在字节码中是怎么表示的?在内存中的对象上表现为什么?

9、wait/notify/notifyAll方法需不需要被包含在synchronized块中?这是为什么?

10、ExecutorService你一般是怎么用的?是每个service放一个还是一个项目里面放一个?有什么好处?

11、你有没有⽤用过Spring的AOP? 是用来干嘛的? 大概会怎么使用?

12、如果⼀一个接口有2个不同的实现, 那么怎么来Autowire一个指定的实现?

spring

 

13、Spring的声明式事务 @Transaction注解一般写在什么位置? 抛出了14、异常会自动回滚吗?有没有办法控制不触发回滚?

15、如果想在某个Bean生成并装配完毕后执行自己的逻辑,可以什么方式实现?

16、SpringBoot没有放到web容器里为什么能跑HTTP服务?

17、SpringBoot中如果你想使用自定义的配置文件而不仅仅是application.properties,应该怎么弄?

18、SpringMVC中RequestMapping可以指定GET, POST方法么?怎么指定?

19、SpringMVC如果希望把输出的Object(例如XXResult或者XXResponse)这种包装为JSON输出, 应该怎么处理?

20、怎样拦截SpringMVC的异常,然后做自定义的处理,比如打日志或者包装成JSON

 

MySQL

 

21、如果有很多数据插入MYSQL 你会选择什么方式?

22、如果查询很慢,你会想到的第一个方式是什么?索引是干嘛的?

23、如果建了一个单列索引,查询的时候查出2列,会用到这个单列索引吗?

24、如果建了一个包含多个列的索引,查询的时候只用了第一列,能不能用上这个索引?查三列呢?

25、接上题,如果where条件后面带有一个 i + 5 < 100 会使用到这个索引吗?

26、怎么看是否用到了了某个索引?

27、like %aaa%会使用索引吗? like aaa%呢?

28、drop、truncate、delete的区别?

29、平时你们是怎么监控数据库的? 慢SQL是怎么排查的?

30、你们数据库是否支持emoji表情,如果不支持,如何操作?

31、你们的数据库单表数据量是多少?一般多大的时候开始出现查询性能急剧下降?

32、查询死掉了,想要找出执行的查询进程用什么命令?找出来之后一般你会干嘛?

33、读写分离是怎么做的?你认为中间件会怎么来操作?这样操作跟事务有什么关系?

34、分库分表有没有做过?线上的迁移过程是怎么样的?如何确定数据是正确的?

 

JVM性能优化

 

35、你知道哪些或者你们线上使用什么GC策略? 它有什么优势,适用于什么场景?

36、Java类加载器包括几种?它们之间的父子关系是怎么样的?双亲委派机制是什么意思?有什么好处?

37、如何自定义一个类加载器?你使用过哪些或者你在什么场景下需要一个自定义的类加载器吗?

38、堆内存设置的参数是什么?

39、Perm Space中保存什么数据? 会引起OutOfMemory吗?

40、做gc时,一个对象在内存各个Space中被移动的顺序是什么?

41、你有没有遇到过OutOfMemory问题?你是怎么来处理这个问题的?42、处理过程中有哪些收获?

43、1.8之后Perm Space有哪些变动? MetaSpace大小默认是无限的么? 还是你们会通过什么方式来指定大小?

44、Jstack是干什么的? Jstat呢? 如果线上程序周期性地出现卡顿,你怀疑可能是gc导致的,你会怎么来排查这个问题?线程日志一般你会看其中的什么部分?

45、StackOverFlow异常有没有遇到过?一般你猜测会在什么情况下被触发?如何指定一个线程的堆栈大小?一般你们写多少?

 

 

 

 

 

 

 

想获得更多资源,请关注微信公众号:程序员开发者社区

 

 

 

 

展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: Age of Ai 设计师: meimeiellie
应支付0元
点击重新获取
扫码支付

支付成功即可阅读