实用 - Java后端面试经历(经验分享)适用于2~3年

前言

因为某些个人原因,或者其他不可控因素,IT行业跳槽肯定在所难免。

这也意味着,你会离开一个熟悉的环境,想方设法的去融入另一个陌生的环境,接触新的同事。希望你的同事人都超级棒~

这篇博客可能只适用于一些2~3年,每天勤勤恳恳写代码,按时完成日常任务的中级程序猿。

毕竟,技术宅男都是大佬,随便换工作,公司都是抢着要。

准备工作

求职简历:简历里面,我觉得有一点很重要,就是如果你对某个框架底层原理并不熟悉,只是项目中使用到了,那么,建议在简历里面这样写:了解并使用xxx框架/技术。

求职App:目前,App主要推荐:猎聘,Boss直聘。 诈骗公司,培训机构相对而言较少,HR回复也比较快(个人感触),app上面的信息都一一完善,包括个人信息,工作经验,项目经验等,尽可能的多写,不要嫌麻烦~~~ 朋友内推也是一种途径

小小建议

1、所谓不打无准备的仗,复习几天,再开始投简历!!不然,你一点没准备,突然通知你面试,又是你很想去的公司,那可能就错过了~

2、准备得差不多了,就可以试着投简历。投简历时仔细看公司招聘要求,有选择性,目的性的投(至少他写的技术你要会一大半吧)。

3、多面试,积累经验。一次两次没面上无所谓,总结失败原因(下来看技术面试时没答上来,或者自己一知半解的知识点,要有针对性的去学习,实践),为下一次面试做准备。

如何复习

工作这几年,每次面试之后,把面试中问到的技术包括一些题做了汇总。分享给大家,大体知识点如下:

一、Java基础

1.显示转换和隐式转换

2.== 和 equals()区别

3.集合源码

4.位运算(源码里面经常用到)

5.多线程

6.Java众多设计模式中常用的几种

7.反射机制

8.封装,继承,多态,抽象

9.java的八大基本数据类型你得记得吧?

10.java的自动拆箱和装箱

11.CountDownLatch的作用和源码

@SpringBootTest

class JavaStudyTest {

    @Autowired

    // @Qualifier("student")

    // @Resource

    private StudentService studentService;

    public static void main(String[] args) {

        System.out.println("ss");

        Person person = new Student();

        person.eat();

        Integer i = 12;

        Integer ii = Integer.valueOf(129);

        Executors.newFixedThreadPool(4);

    }

    /**

     * 1.显示转换和隐式转换

     *

     * byte -> char -> short -> int -> long ->float -> double -> boolean

     * 隐式转换,计算时会编译器自动转换,从小到大

     * 可查看target文件夹下面对应的字节码文件,编译之后的代码

     */

    @Test

    public void test1() {

        try {

            short s = 1;

            //s += 1   ==   s=(short)(s+1)

            s += 1.1D;

            System.out.println("s........." + s);

            System.out.println("这里的s从double强转成short,会确实精度,结果不是2.1,而是2");

            // s = s + 1;

            String str = "abcd";

            boolean equals = str.equals("ddd");

        } catch (Exception e) {

        }

    }

    /**

     * 2.== 和 equals()区别

     *

     * java.lang.Object    getClass(),equals(),hashcode(),toString(),wait(),notify(),notifyAll,finalize(),

     *

     * Integer 能用==判断相等吗?-128  ~ 127 ,为什么?主要要有个缓存概念

     */

    @Test

    public void test2() {

        String str1 = new String("abc");//这个过程是运行时在堆内存中实时创建一个对象。

        String str2 = new String("abc");//这个过程是运行时在堆内存中实时创建一个对象。

        System.out.println(str1.equals(str2));//比较的是两个对象的值,是true

        System.out.println(str1 == str2);//比较的是两个对象地址,是false

    }

    /**

     * 3.集合

     *

     * Collection   ->  List        -> ArrayList(初始化大小10,扩容为为之前的1.5倍),LinkedList,Vector(线程安全,扩容为之前的2倍)          Set -> HashSet,

     * Map    ->  HashMap (阈值16,2的倍数,负载因子为0.75,当map的size超过0.75就扩容为之前的2倍),TreeMap,HashTable(线程安全,key不能为null)  ->CurrentHashMap (高并发,保证线程安全)

     *

     * 重点:HashMap,CurrentHashMap(线程安全)的源码,包括默认的一些参数,put(),get()时大致流程,什么时候扩容,扩容过程,尽可能记清楚。

     */

    @Test

    public void test3() {

        List list = new ArrayList();

        List list1 = new LinkedList();

        list1.add("");

        Map map = new HashMap();

        map.put("number", "");

        Set set = new HashSet();

        list.add("e");

        if (list != null & "e".equals("d")) {

            System.out.println("");

        }

        int[] intArray = new int[10];

        intArray[0] = 1;

        String[] strArray = {};

        strArray[0] = "ll";

        ConcurrentHashMap concurrentHashMap = new ConcurrentHashMap();

        concurrentHashMap.put("test", "xjc");

        concurrentHashMap.get("test");

        System.out.println(concurrentHashMap.get("test"));

        /**

         *

         * ------

         * 一. HashMap put过程

         *

         *

         *

         * 二. ConcurrentHashMap: put()过程   cas + synchronized

         * https://www.jianshu.com/p/5dbaa6707017 (很详细)

         *

         * 1.计算key的hash值,

         *

         * 插入过程使用无条件自循环

         * table Node[]  table;

         * 3.如果table为空,还没初始化,先调用initTable()初始化, cas, sizeCtl = -1:说明有其他线程在初始化

         *

         * 如果新node的hash=-1, 帮助扩容??扩容很复杂

         *

         * 4.如果索引所在位置为null,就直接使用cas(unsafe.compareAndSwapObject())插入数组

         *

         * 5.否则,hash冲突,A.判断当前为链表,    B.当前节点为红黑树,将新的键值插入到红黑树

         * 6. 插入完  再判断是否需要转换成红黑树

         * 7。检查是否需要扩容,如果超过了  实际大小*加载因子  就需要扩容 addCount

         *

         *

         * HashMap、Hashtable、ConccurentHashMap三者的区别?

         * HashMap线程不安全,数组+链表+红黑树

         * Hashtable线程安全,锁住整个对象,数组+链表

         * ConccurentHashMap线程安全,CAS+同步锁,数组+链表+红黑树

         * HashMap的key,value均可为null,其他两个不行

         */

    }

    /**

     * 4.位运算

     *

     * >>  右移  / 2

     * <<  左移  * 2

     * >>> 无符号右移

     * &   与    两个操作数中位都为1,结果才为1,否则结果为0,

     * |   或    两个位只要有一个为1,那么结果就是1,否则就为0,

     * ^   异或  两个操作数的位中,相同则结果为0,不同则结果为1。        不使用中间变量,交换两个变量的值

     *

     * https://www.cnblogs.com/shuaiding/p/11124974.html

     * https://blog.csdn.net/weixin_37490221/article/details/90905087

     */

    @Test

    public void test4() {

        int a = 1;

        int b = 2;

        /*

         * 1.任何数和自己进行异或操作结果都为0

         * 2.异或符合交换律,即a ^ b = b ^ a

         * 3.任何数和0进行异或都是任何数本身

         * a = a ^ b;

         * b = b ^ a = b ^ (a ^ b) = a;

         * a = a ^ b = (a ^ b) ^ (b ^ (a ^ b)) = (a ^ b) ^ a = b;

         */

        a = a ^ b;

        b = b ^ a;

        a = a ^ b;

    }

    /**

     * 5.多线程

     * https://www.cnblogs.com/wxd0108/p/5479442.html

     * https://www.cnblogs.com/zsql/p/11144688.html

     *

     * 实现方式:Runnable接口(run()),Thread类,Callable接口(call())

     *

     * 多线程: 联想到线程安全

     *

     *

     * synchronized  原子性、可见性和有序性   --> 阻塞锁,也叫悲观锁,锁住资源,其他使用该资源的线程全部进入阻塞队列,直到资源被释放

     * volatile  可见性和有序性

     * lock         ---> 也叫非阻塞锁, 主要实现方式 cas算法, aqs, 也叫乐观锁    ---> cas -- 又有公平锁和非公平锁,源码在ReentrantLock相关类里面

     *

     * 搞清楚悲观锁和乐观锁的定义?对应实现方式?

     *

     * 多线程  --->  线程池  --->

     * 关于线程池的源码和使用,看ThreadPoolExecutor源码,一定要搞清楚这个类里面的几个参数是什么意思,

     * 通过Executors创建线程池存在的弊端,如何使用ThreadPoolExecutor创建线程池?(可能会问,答案是通过Executors创建的线程池,对应参数都设置的max)

     */

    @Test

    public void test5() {

        VolatileTest thread1 = new VolatileTest("thread1");

        thread1.start();

        try {

            Thread.sleep(10000);

            System.out.println("Now stop thead1.");

            thread1.stopIt();

        } catch (InterruptedException e) {

            e.printStackTrace();

        }

        /* ExecutorService executorService = Executors.newFixedThreadPool(4);

        Future future = executorService.submit(new Runnable() {

            @Override

            public void run() {

                System.out.println("ss");

            }

        });

        Future callFuture = executorService.submit(new Callable() {

            @Override

            public Object call() throws Exception {

                return null;

            }

        });

        try {

            Object o = callFuture.get(1000, TimeUnit.SECONDS);

        } catch (InterruptedException | ExecutionException | TimeoutException e) {

            e.printStackTrace();

        }*/

    }

    /**

     * 6.Java众多设计模式中常用的几种

     */

    public void test6() {

        /**

         * 动态代理模式(AOP)

         * 单例模式 (懒汉/饿汉)

         * 工厂模式(beanFactory)

         * 装饰器模式

         * 观察者模式

         * 生产者-消费者模式

         *

         */

         // 需要你能举例,最好是把每种模式的代码码一遍。其次,动态代理用到的类,大致方法(Proxy类,InvocationHandle接口 --> invoke())

    }

    /**

     * 7.反射机制

     * 程序运行过程中,根据类名,class 动态调用类的属性和方法,

     */

    public void test7() throws Exception {

        Class cl = Class.forName("com.example.demo.entity.Student");

        Object o = cl.newInstance();

        Field name = cl.getField("name");

        name.get(cl);

    }

    /**

     * 8.封装,继承,多态,抽象

     *

     * java的多态。什么叫多态?

     *

     * 注意:在使用多态后的父类引用变量调用方法时,会调用子类重写后的方法。

     */

/**

 * 9.

 * java的八大基本数据类型你得记得吧?

     * 每种基本数据类型对应得包装类型?

 /

    /**

     * 10.

     * java自动装箱:jvm编译时自动将基本类型转换成对应的对象(包装类型)  拆箱

     * 要有缓存的概念,提高程序的效率和减少内存的占用

     * https://www.cnblogs.com/haitaofeiyang/p/7711558.html

     * https://www.jianshu.com/p/0ce2279c5691  (讲得很好)

     *

     * Integer i = 1;  ----> jvm编译时会将1转换成Integer对象,valueOf()    intValues()

     *

     * int i=1;Integer j = 2; i + j   ----> 这种在进行计算操作时,jvm编译会将Integer对象转换为int类型,这种操作叫自动拆箱

     */

}

二、Spring 相关(有点杂乱)

1.Spring mvc的工作流程?

2.servlet 生命周期 (单实例,多线程)

3.分布式是什么?分布式锁?Mysql,redis,zookeeper如何实现分布式锁?

4.接口改为异步,提高系统的吞吐量 使用DeferredResult和CompletableFuture

5.Jsp 九大内置对象?

6.Spring aop,ioc (重点,一定要去看源码,我下面贴的一篇视频讲得很明白)

7.JVM调优 和 GC (重点,必问)

8.@Autowired + @Qualifier = @Resource 注入bean(type,name)

9.@Value(${spring.test: default}) value注解,:后面跟默认值, 表达式中#和$ 区别

/**

     * 1.servlet 生命周期 (单实例,多线程)

     *

     * 用户第一次请求的时候,servlet容器会调用init()进行初始化,生成一个servlet实例。真正执行请求的方法service()  ->  doGet(),doPost(),doDelete()

     * 最后,当服务器关闭(tomcat stop),会调用destroy(),该方法也只会调用一次

     *

     * 问:servlet实例是在什么时候初始化的,又是什么时候销毁的??

     */

     

/**

     * 2.分布式

     *

     */

    public void test8() {

        /**

         * 分布式技术: 当一个系统的业务量原来越大,代码越来越多,就需要考虑将一个庞大的系统拆分为多个子系统(多个微服务),每个子系统也不能是单机,需要做集群。

         * 通过这样的方式,来提高我们系统的吞吐量,保证系统的稳健性。

         *

         * 分布式用微服务架构实现,目前主流的有两种,一种基于Http协议(spring cloud ), 一种基于Rpc(阿里的dubbo)

         *

         *

         * 每天100w 搜索访问量,qps  100w / (8 * 3600) = 35   QPS平时一般是50左右,高峰期 80 - 120, 平均响应时间3s。  并发量 = QPS * 平均响应时间  = 50 * 3 = 150

         */

        /**

         * 分布式锁:(mysql redis(setnx(key,value)) zookeeper)

         *  https://blog.csdn.net/xlgen157387/article/details/79036337

         */

        // https://blog.csdn.net/qq_25026989/article/details/89103843

    }

    /**

     * 3.接口改为异步,提高系统的吞吐量 使用DeferredResult  和  CompletableFuture   thenApply,thenApplyAsync

     * Spring基础学习-SpringMVC异步处理模式分析(DeferredResult/SseEmitter等)

     */

    public void test12() {

        // tomcat容器的连接线程池的数量是有限制的。每一个请求都会占用一个连接数。如果接口耗时很长,会长时间的占用连接,一直不被释放,那么一但连接线程池里都被占用了,就无法继续对外提供服务了。

        // Java8 异步编程: https://zhuanlan.zhihu.com/p/63734729

        // https://blog.csdn.net/icarusliu/article/details/79539105

        // 为什么使用DeferredResult? https://www.cnblogs.com/theRhyme/p/10846349.html

    }

    /**

     * ---------------------------------

     * 4.

     * Jsp 九大内置对象?

     * request response session(用户第一次请求的时候,服务器会记录一个session)  application(应用不关闭,一直存在)  page pageContent  out   config   exception

     *

     *

     * ---------------------------------

     * 重定向:redirect   转发:forward ??

     * 区别:1.redirect是在浏览器端跳转,forward是在服务器端跳转,所以redirect的时候,浏览器的地址会变,而forward不会;2.重定向,请求域(request)里面的数据会丢失, 转发不会;

     *

     *

     * ---------------------------------

     * jsp 动作include与指令的区别?

     * 编译时,page,会编译到同一个jsp文件中,可以使用变量

     * 动作include则是编译两个jsp,不可以使用变量,会报错,编译不过

     */

    public void test10() {

    }

  /**

     * 5.

     * spring aop

     *

     * 看这个视频,足以:https://www.bilibili.com/video/av81268629?from=search&seid=4974281176459987245

     *

     * 面向切面编程,常用的使用场景:1.日志监控(执行controller之前,之后,记录)  2.service执行耗时

     *

     * aop的实现,底层原理: 动态代理    spring aop: 如果去看源码 , JdkDynamicAopProxy(被代理对象实现了接口)  和  CglibAopProxy(对没有实现接口类的提供代理),两种

     *

     * 再往下看源码, InvocationHandler 接口  -> invoke()方法,在这里面,可以代理对象,并做一些其他的事情  和 Proxy类  -> new ProxyClass 得到一个代理对象

     *

     * 用到了java的反射

     * Class,Method,Filed

     *

     * P7面试题: 为什么我们java动态代理被代理的对象必须实现了接口?

     * 答:因为java是单继承,多实现。而生成的代理对象默认实现了Proxy对象。

     */

    @Test

    public void test11() throws Exception {

        // 动态代理

        // AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(DemoApplication.class);

        // // StudentService studentService1 = annotationConfigApplicationContext.getBean(StudentService.class);

        // StudentService studentService1 = (StudentService) annotationConfigApplicationContext.getBean("studentService");

        // studentService1.queryStudentById();

        // System.out.println("Test proxy...jdkDym..Proxy");

        // 代理对象字节码

        byte[] $proxies = ProxyGenerator.generateProxyClass("$proxy", new Class[]{StudentService.class});

        FileOutputStream fileOutputStream = new FileOutputStream("E:\\Proxy.class");

        fileOutputStream.write($proxies);

        fileOutputStream.flush();

        fileOutputStream.close();

    }

    /**

     * 6.

     * spring ioc:

     *

     * 依赖注入,是spring的一种设计思想,项目启动时,将需要交给spring管理的bean装配到spring容器中,交给spring容器统一管理。使用的时候,直接从spring容器里面取,而不用反复创建

     *

     * BeanFactory  和ClassPathXmlApplicationContent

     */

/**

     * 7.

     * JVM调优 和 GC

     */

    public void test14() {

        // https://www.jianshu.com/p/5d899b0dcc8d

        // https://blog.51cto.com/zero01/2150696   (博客很棒,可以跟着试试jvm调优)

        // https://www.zhihu.com/question/56206572

        /**

         * java 里面的gc,垃圾回收器。jvm回收时,会调用finalize()方法

         *

         * 回收的对象,垃圾对象:长时间或以后都不可能被使用的对象,

         *

         * 有两种算法:1种是计数器,每个对象都有一个计数器,如果这个对象有引用,+1  如果计数器为0,则标记为垃圾对象   2:可达性算法,GC Roots

         *

         * 垃圾回收算法: 1. 标记-清除 (扫描内存里面的对象,对存活的对象进行标记,标记完毕之后,对未标记的对象进行回收,, 会造成内存碎片)

         * 2.标记-整理 (跟标记-清除类似,标记完之后,将存活的地下往空闲空间移动,再清除  解决内存碎片问题)

         * 3.复制算法

         * 4.内存回收算法

         * 新生代,老年代,永久代

         * Full gc..

         * jvm调优,没有调过。一般代码里面遇到内存溢出,out of memory,都是从代码层面去解决,所以要试着去调优

         */

    }

三、关系型数据库相关

最常用的Mysql,还有Orcale,SQL Server等,这里主要是Mysql,中小型企业用得最多吧;

1.基本的CURD你得记住(哪怕你平时开发很少写sql)

2.order by, group by , where , having的用法,in, not in, is null等等…

3.函数:sum() avg() count() min() max() limit distinct(去重)

4.触发器,储存过程(了解,尽量能写,有些公司要考)

5.最重要的Mysql如何调优

6.什么是脏数据? --> 事务,事务的4大特性,4大隔离级别,

7.索引有哪些?mysql对应的引擎?Innodb,Myisam等,引擎各自的优缺点 (多了解,有些公司会问)

   /**

     * Mysql 调优 - 脏数据,事务

     */

    public void test1() {

        // 优化Mysql:  优化sql,加索引

        // limit 1 : 比如我们要查找是否有未成年用户,limit 1,如果发现有,会立即停止搜索效率高

        // 经常where的字段添加索引

        // 避免 SELECT *

        // 尽量避免where时使用!=, ,否则将引擎放弃使用索引而进行全表扫描

        // like %test  势必会进行全表扫描

        // 分区,分表,分库

        // mysql count(1)和count(*)区别,mysql5.5效率一样.之前很多都说count(1)效率更快

        // 事务: 多个增删改查操作的集合。原子性,一致性,隔离性,持久性

        // 4大隔离级别, Read uncommitted,Read committed, (脏读 不可重复读 幻读)

        // https://blog.csdn.net/wang_keng/article/details/77741451  (讲得很清晰明了)

        问1、 not in   /   not exists (区别)

        问2、 java中,mysbatis和hibernate是否都支持批量插入?如果我有10w条数据,应该考虑如何批量插入??

        答案:这里,你应该能考虑到10w条数据同时批量插入,肯定耗时很长,可以考虑分页,一页100条,每次批量插入一页,开启事务。(个人看法)

    }

    /**

     * 经典sql:

     * 表名:购物信息

     * 购物人 商品名称 数量

     * A 甲 2

     * B 乙 4

     * C 丙 1

     * A 丁 2

     * B 丙 5

     * 给出所有购入商品为两种或两种以上的购物人记录;

     */

    public void testMysql() {

        /*

         * 表:shop

         * 字段:id shopper  goods_name  number

         *

         * select * from shop where shop.shopper in (select s.shopper shopper from shop s group by s.shopper having count(s.shopper) >= 2)

         *

         *

         */

        /**

         * create table(

         * 'id' int,

         * 'name' varchar(255)

         * )

         */

    }

三、Nosql相关

常用的应该就Redis,MongoDb,尽可能多的了解。

这个就需要考你平时开发中的积累了,有些公司可能会问:

1.讲讲Redis和MongoDb的优缺点?实际使用场景?

2.缓存穿透、缓存击穿、缓存雪崩区别和解决方案??(redis)

/**

  * Redis:

  *

  * 1.基本的数据类型 :string, list, set, zset, hash

  * 2.使用场景: 电商系统里面的排行榜,网站的访问量统计,分布式锁(setnx(key,value) -- > 成功返回1,失败返回0)

  *

  *

  *

  * MongoDb:

  * 1. database(数据库)   -->  collection (表) --> document --> index

  * 2. find(),sort(),limit(),skip(),match(),aggregate()聚合操作。

  */

四、前端

熟练掌握js、Jquery等前端技术,包括javaScript,jquey,html,css,bootstrap等,会得越多越好…vue,react啊

简单的说,开发后台管理系统,写jsp页面你要会。朝着全栈发展就对了。

五、MQ

1.消息队列的消费方式?JMS?点对点,多对点?

2.消息丢失和重复消费?如何解决

3.常用的MQ优缺点?RebbitMq,Kafka,ActiveMq? 这里,要深入了解其中一种才行

    /**

     * zookeeper  + kafka  https://blog.csdn.net/liyiming2017/article/details/82805479 (很棒的博客)

     *

     * leader 控制消息分发   分区,多个消费者同时消费,大大提高了kafka的吞吐量

     *

     * zookeeper: 配置管理,分布式系统协调服务,   存储结构,Znode:树型,跟linux的文件系统路径相似;znode,可以往这个节点存储或获取数据,

     * 基本命令: create   (-s/-e)  /node_1  "data" //创建节点    ls /  //查看节点   set node_1  //赋值    get  /node_1   //查询该节点下面的值

     * znode节点类型: 4种,持久节点,持久顺序节点,临时节点,临时顺序节点

     *

     *

     * zookeeper kafka --  topic消费方式,点对点,多对点。

     *

     * 消息消费模型(JMS,区别就在于会不会被重复消费):2种 1. 点对点 queue,每个消息只会被一个消费者消费     2:发布/订阅  topic: 如果topic被多个消费者订阅,就会重复消费

     *

     * 问:如何解决kafka数据丢失和重复消费?

     * 答:数据丢失主要考虑生产者,kafkaProducer   ack = all/1 ;只要保证集群稳定的情况下,可以保证数据不丢失 (at least once)

     * 重复消费主要考虑消费者,kafkaConsumer     enabled.auto.commit = true .消费者消费完消息之后,再自动提交offset。(at least once)

     * kafka事务指kafka一系列 生产、消费消息等操作组成一个原子操作

     *

     * 幂等操作和事务,保证生产者和消费者都是原子操作。

     *

     *

     */

六、Spring boot + Spring cloud

一些面试题:

Spring boot:

1.spring boot自动配置怎么实现的?@EnableAutoConfiguration,@Import,@ConfigurationProperties  

2.spring boot中,yml和properties的区别,加载顺序,优先级?

Spring cloud:

...待补充,spring cloud微服务,我也只是使用过,里面的大部分组件,原理都不清楚。

// 相关博客

/**

  * springboot自动配置的原理

  * https://blog.csdn.net/u014745069/article/details/83820511

  * https://cloud.tencent.com/developer/article/1442150 (实践,写得很棒)

  *

  */

17

七、Linux Shell

会常用的命令和简答的脚本编写。。例如服务的打包,运行

如果,你还会Jenkins持续集成,那就更棒了

总结

1.上面提到的六点,如果你都没问题了,那么在成都找个10-13k的工作应该是没问题的(中级-3年)。(3-5年,18k,应该算高级吧)

2.最近面试,我发现,很多公司或多或少都会问spring cloud微服务相关的。看样子,目前spring boot,spring cloud全家桶在IT界的使用越来越普遍了。

3.在复习的时候,建议多敲多写。比如一个知识点,你看完了,默想一遍,然后从头到尾,把自己的理解在在本子上写一遍(提升记忆)。

4.面试的时候,举一反三。。。这个就是考验自己掌握知识点的广度了。

比如,面试官问,一个后台管理系统,他想记录每个操作对应的操作人,操作时间,该怎么实现?这个就是AOP常用的使用场景,日志监控。 @Pointcut,@Around…紧接着底层使用了动态代理模式实现,继续动态代理涉及到的两个类(Proxy,InvocationHandler -> invoke()方法) ,动态代理里面有用到了java的反射机制,Class,Method,Field等类。。

最后 – 成都多点公司面试

 /**

   *

   * 电话面试 -- 高级 -----------------

   * 成都多点公司(要求较高,对相关开源框架的底层原理,jvm,gc,集合,等问得特别详细):

   *

   * jvm如何调优,一些调优参数了解吗?  -xmx        GC: 内存主要有哪几块,新生代,老生代,永久代,(标记算法,回收算法),    哪块内存用那种算法,

   *

   * zookeeper kafka --  1. jms消费模型 topic消费方式,点对点,多对点。    2.kafka数据丢失和重复消费?如何解决?3.zk的存储结构, 4,kafka里面的broker,consumer group,offset。。

   *

   * 数据结构:queue(队列)(先进先出) 栈(heap):桶,先进后出      java内存:  堆 栈 常量池  程序计数器

   * 数据结构&算法(一)_堆、栈(桶)(堆栈)、队列、链表   https://www.cnblogs.com/hedeyong/p/7841548.html

   *

   * 多线程:1.乐观锁,悲观锁,  如何加锁(原理)   2.sleep,join,wait 区别,  释放锁(资源)? 为什么?    3. lock  CAS(CAS算法) aqs

   * CAS:  https://mp.weixin.qq.com/s?__biz=MzI3NzE0NjcwMg==&mid=2650122072&idx=1&sn=63690ad2cbf2b5390c3d8e1953ffbacf&chksm=f36bba79c41c336fbea8b56289fc2a71e829042f6c3616e3ba051c2542b48f0a3936e3d852f6&mpshare=1&scene=1&srcid=0225xcUOCP6bBS8aCrcd1jBd#rd

   *

   * 集合:1. concurrentHashMap (线程安全hashMap) 原理  【重点】  2.HahMap 源码, 扩容,

   *

   * 数据库: 1. mysql 引擎有哪几种(5种,Innodb(支持事务), mylsam(不支持事务)),各自优点?

   *         2.索引类型  普通索引(normal),唯一索引(unique),全文索引(FullText),   索引方法:btree  hash?

   *

   * spring cloud 微服务架构    http://blog.didispace.com/spring-cloud-learning/

   *

   * redis: 基本数据类型?使用场景?如何备份???缓存雪崩?

   */

如果你在求职中,工作经验2~3年,可以花点时间,认认真真将文中提到的知识点过一遍,敲一遍,或许会对你有些帮助。如果能够帮助到你,我很开心。【付出和收获总是成正比的】

找工作不急,多面几家,对比。面试如果有戏,面试官问你还有什么问题的时候,建议问一下他们项目组目前你去了之后负责的项目是什么?用到了什么框架?项目组人员结构,后端几个?这些都问一下,不然去了之后,和自己想像的不太一致。 我有个朋友就是,入职第一天,才晓得他们那个项目就两个人开发,ssm和ssh都没用到。持久层用的原生jdbc开发,没有分MVC。

如果本文对你有帮助,别忘记给我个3连 ,点赞,转发,评论,

咱们下期见!答案获取方式:已赞 已评 已关~

学习更多知识与技巧,关注与私信博主(03)

 

你可能感兴趣的:(面试,后端,java,java,面试,经验分享,jvm,算法)