【Java】十道校招常见的面试题

Java校招120道面试题目合集 static变量在Java中是属于类的,它在所有的实例中的值是一样的。(接口的作用是用来扩展对象的功能,一个子接口继承多个父接口,说明子接口扩展了多个功能,当类实现接口时,类就扩展了相应的功能)。java中也不可以覆盖private的方法,因为private修饰的变量和方法只能在当前类中使用,如果是其他的类继承当前类是不能访问到private变量或方法的,当然也不能覆盖。“static”是静态修饰符,它用来表明一个成员变量或者是成员方法可以在没有所属的类的实例变量的情况下被访问。(不同平台的机器码不同)。. 阅读详情

前言

只有光头才能变强。

文本已收录至我的GitHub仓库,欢迎Star:https://github.com/ZhongFuCheng3y/3y

0、final关键字

简要说一下final关键字,final可以用来修饰什么?

这题我是在真实的面试中遇到的,当时答得不太好,现在来整理一下吧。

final可以修饰类、方法、成员变量

  • 当final修饰类的时候,说明该类不能被继承

  • 当final修饰方法的时候,说明该方法不能被重写

    • 在早期,可能使用final修饰的方法,编译器针对这些方法的所有调用都转成内嵌调用,这样提高效率(但到现在一般我们不会去管这事了,编译器和JVM都越来越聪明了)

  • 当final修饰成员变量时,有两种情况:

    • 如果修饰的是基本类型,说明这个变量的所代表数值永不能变(不能重新赋值)!

    • 如果修饰的是引用类型,该变量所的引用不能变,但引用所代表的对象内容是可变的!

值得一说的是:并不是被final修饰的成员变量就一定是编译期常量了。比如说我们可以写出这样的代码:private final int java3y = new Randon().nextInt(20);

你有没有这样的编程经验,在编译器写代码时,某个场景下一定要将变量声明为final,否则会出现编译不通过的情况。为什么要这样设计?

在编写匿名内部类的时候就可能会出现这种情况,匿名内部类可能会使用到的变量:

  • 外部类实例变量

  • 方法或作用域内的局部变量

  • 方法的参数

class Outer {    // string:外部类的实例变量    String string = "";    //ch:方法的参数    void outerTest(final char ch) {        // integer:方法内局部变量        final Integer integer = 1;        new Inner() {            void innerTest() {                System.out.println(string);                System.out.println(ch);                System.out.println(integer);            }        };    }    public static void main(String[] args) {        new Outer().outerTest(' ');    }    class Inner {    }}

其中我们可以看到:方法或作用域内的局部变量和方法参数都要显示使用final关键字来修饰(在jdk1.7下)!

640?wx_fmt=png

如果切换到jdk1.8编译环境下,可以通过编译的~

640?wx_fmt=png

下面我们首先来说一下显示声明为final的原因:为了保持内部外部数据一致性

  • Java只是实现了capture-by-value形式的闭包,也就是匿名函数内部会重新拷贝一份自由变量,然后函数外部和函数内部就有两份数据。

  • 要想实现内部外部数据一致性目的,只能要求两处变量不变。JDK8之前要求使用final修饰,JDK8聪明些了,可以使用effectively final的方式

为什么仅仅针对方法中的参数限制final,而访问外部类的属性就可以随意

内部类中是保存着一个指向外部类实例的引用,内部类访问外部类的成员变量都是通过这个引用。

  • 在内部类修改了这个引用的数据,外部类再获取时拿到的数据是一致的!

那当你在匿名内部类里面尝试改变外部基本类型的变量的值的时候,或者改变外部引用变量的指向的时候,表面上看起来好像都成功了,但实际上并不会影响到外部的变量。所以,Java为了不让自己看起来那么奇怪,才加了这个final的限制。

参考资料:

  • java为什么匿名内部类的参数引用时final?

  • https://www.zhihu.com/question/21395848

一、char和varchar的区别

  1. char是固定长度,varchar长度可变。varchar:如果原先存储的位置无法满足其存储的需求,就需要一些额外的操作,根据存储引擎的不同,有的会采用拆分机制,有的采用分页机制。

  2. char和varchar的存储字节由具体的字符集来决定(之前写错了);

  3. char是固定长度,长度不够的情况下,用空格代替。varchar表示的是实际长度的数据类型

选用考量:

  • 如果字段长度较短和字符间长度相近甚至是相同的长度,会采用char字符类型

二、多个线程顺序打印问题

三个线程分别打印A,B,C,要求这三个线程一起运行,打印n次,输出形如“ABCABCABC….”的字符串。

原博主给出了4种方式,我认为信号量这种方式比较简单和容易理解,我这里粘贴一下(具体的可到原博主下学习)..

public class PrintABCUsingSemaphore {    private int times;    private Semaphore semaphoreA = new Semaphore(1);    private Semaphore semaphoreB = new Semaphore(0);    private Semaphore semaphoreC = new Semaphore(0);    public PrintABCUsingSemaphore(int times) {        this.times = times;    }    public static void main(String[] args) {        PrintABCUsingSemaphore printABC = new PrintABCUsingSemaphore(10);        // 非静态方法引用  x::toString   和() -> x.toString() 是等价的!        new Thread(printABC::printA).start();        new Thread(printABC::printB).start();        new Thread(printABC::printC).start();        /*new Thread(() -> printABC.printA()).start();        new Thread(() -> printABC.printB()).start();        new Thread(() -> printABC.printC()).start();*/    }    public void printA() {        try {            print("A", semaphoreA, semaphoreB);        } catch (InterruptedException e) {            e.printStackTrace();        }    }    public void printB() {        try {            print("B", semaphoreB, semaphoreC);        } catch (InterruptedException e) {            e.printStackTrace();        }    }    public void printC() {        try {            print("C", semaphoreC, semaphoreA);        } catch (InterruptedException e) {            e.printStackTrace();        }    }    private void print(String name, Semaphore current, Semaphore next)            throws InterruptedException {        for (int i = 0; i < times; i++) {            current.acquire();            System.out.print(name);            next.release();        }    }}
  • 作者:cheergoivan

  • 链接:https://www.jianshu.com/p/40078ed436b4

  • 來源:简书

2018年9月14日18:15:36  yy笔试题就出了..

三、生产者和消费者

在不少的面经都能看到它的身影哈~~~基本都是要求能够手写代码的。

其实逻辑并不难,概括起来就两句话:

  • 如果生产者的队列满了(while循环判断是否满),则等待。如果生产者的队列没满,则生产数据并唤醒消费者进行消费。

  • 如果消费者的队列空了(while循环判断是否空),则等待。如果消费者的队列没空,则消费数据并唤醒生产者进行生产。

基于原作者的代码,我修改了部分并给上我认为合适的注释(下面附上了原作者出处,感兴趣的同学可到原文学习)

生产者:

import java.util.Random;import java.util.Vector;import java.util.concurrent.atomic.AtomicInteger;public class Producer implements Runnable {    // true--->生产者一直执行,false--->停掉生产者    private volatile boolean isRunning = true;    // 公共资源    private final Vector sharedQueue;    // 公共资源的最大数量    private final int SIZE;    // 生产数据    private static AtomicInteger count = new AtomicInteger();    public Producer(Vector sharedQueue, int SIZE) {        this.sharedQueue = sharedQueue;        this.SIZE = SIZE;    }    @Override    public void run() {        int data;        Random r = new Random();        System.out.println("start producer id = " + Thread.currentThread().getId());        try {            while (isRunning) {                // 模拟延迟                Thread.sleep(r.nextInt(1000));                // 当队列满时阻塞等待                while (sharedQueue.size() == SIZE) {                    synchronized (sharedQueue) {                        System.out.println("Queue is full, producer " + Thread.currentThread().getId()                                + " is waiting, size:" + sharedQueue.size());                        sharedQueue.wait();                    }                }                // 队列不满时持续创造新元素                synchronized (sharedQueue) {                    // 生产数据                    data = count.incrementAndGet();                    sharedQueue.add(data);                    System.out.println("producer create data:" + data + ", size:" + sharedQueue.size());                    sharedQueue.notifyAll();                }            }        } catch (InterruptedException e) {            e.printStackTrace();            Thread.currentThread().interrupted();        }    }    public void stop() {        isRunning = false;    }}

消费者:

import java.util.Random;import java.util.Vector;public class Consumer implements Runnable {    // 公共资源    private final Vector sharedQueue;    public Consumer(Vector sharedQueue) {        this.sharedQueue = sharedQueue;    }    @Override    public void run() {        Random r = new Random();        System.out.println("start consumer id = " + Thread.currentThread().getId());        try {            while (true) {                // 模拟延迟                Thread.sleep(r.nextInt(1000));                // 当队列空时阻塞等待                while (sharedQueue.isEmpty()) {                    synchronized (sharedQueue) {                        System.out.println("Queue is empty, consumer " + Thread.currentThread().getId()                                + " is waiting, size:" + sharedQueue.size());                        sharedQueue.wait();                    }                }                // 队列不空时持续消费元素                synchronized (sharedQueue) {                    System.out.println("consumer consume data:" + sharedQueue.remove(0) + ", size:" + sharedQueue.size());                    sharedQueue.notifyAll();                }            }        } catch (InterruptedException e) {            e.printStackTrace();            Thread.currentThread().interrupt();        }    }}

Main方法测试:

import java.util.Vector;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;public class Test2 {    public static void main(String[] args) throws InterruptedException {        // 1.构建内存缓冲区        Vector sharedQueue = new Vector();        int size = 4;        // 2.建立线程池和线程        ExecutorService service = Executors.newCachedThreadPool();        Producer prodThread1 = new Producer(sharedQueue, size);        Producer prodThread2 = new Producer(sharedQueue, size);        Producer prodThread3 = new Producer(sharedQueue, size);        Consumer consThread1 = new Consumer(sharedQueue);        Consumer consThread2 = new Consumer(sharedQueue);        Consumer consThread3 = new Consumer(sharedQueue);        service.execute(prodThread1);        service.execute(prodThread2);        service.execute(prodThread3);        service.execute(consThread1);        service.execute(consThread2);        service.execute(consThread3);        // 3.睡一会儿然后尝试停止生产者(结束循环)        Thread.sleep(10 * 1000);        prodThread1.stop();        prodThread2.stop();        prodThread3.stop();        // 4.再睡一会儿关闭线程池        Thread.sleep(3000);        // 5.shutdown()等待任务执行完才中断线程(因为消费者一直在运行的,所以会发现程序无法结束)        service.shutdown();    }}
  • 作者:我没有三颗心脏

  • 链接:https://www.jianshu.com/p/3f0cd7af370d

  • 來源:简书

另外,上面原文中也说了可以使用阻塞队列来实现消费者和生产者。这就不用我们手动去写wait/notify的代码了,会简单一丢丢。可以参考:

  • 使用阻塞队列解决生产者-消费者问题:https://www.cnblogs.com/chenpi/p/5553325.html

四、算法[1]

我现在需要实现一个栈,这个栈除了可以进行普通的push、pop操作以外,还可以进行getMin的操作,getMin方法被调用后,会返回当前栈的最小值,你会怎么做呢?你可以假设栈里面存的都是int整数

解决方案:

  • 使用一个min变量来记住最小值,每次push的时候,看看是否需要更新min。

    • 如果被pop出去的是min,第二次pop的时候,只能遍历一下栈内元素,重新找到最小值。

    • 总结:pop的时间复杂度是O(n),push是O(1),空间是O(1)

  • 使用辅助栈来存储最小值。如果当前要push的值比辅助栈的min值要小,那在辅助栈push的值是最小值

    • 总结:push和pop的时间复杂度都是O(1),空间是O(n)。典型以空间换时间的例子。

import java.util.ArrayList;import java.util.List;public class MinStack {    private List<Integer> data = new ArrayList<Integer>();    private List<Integer> mins = new ArrayList<Integer>();    public void push(int num) {        data.add(num);        if (mins.size() == 0) {            // 初始化mins            mins.add(num);        } else {            // 辅助栈mins每次push当时最小值            int min = getMin();            if (num >= min) {                mins.add(min);            } else {                mins.add(num);            }        }    }    public int pop() {        // 栈空,异常,返回-1        if (data.size() == 0) {            return -1;        }        // pop时两栈同步pop        mins.remove(mins.size() - 1);        return data.remove(data.size() - 1);    }    public int getMin() {        // 栈空,异常,返回-1        if (mins.size() == 0) {            return -1;        }        // 返回mins栈顶元素        return mins.get(mins.size() - 1);    }}

继续优化:

  • 栈为空的时候,返回-1很可能会带来歧义(万一人家push进去的值就有-1呢?),这边我们可以使用Java Exception来进行优化

  • 算法的空间优化:上面的代码我们可以发现:data栈和mins栈的元素个数总是相等的,mins栈中存储几乎都是最小的值(此部分是重复的!)

    • 所以我们可以这样做:当push的时候,如果比min栈的值要小的,才放进mins栈。同理,当pop的时候,如果pop的值是mins的最小值,mins才出栈,否则mins不出栈!

    • 上述做法可以一定避免mins辅助栈有相同的元素!

但是,如果一直push的值是最小值,那我们的mins辅助栈还是会有大量的重复元素,此时我们可以使用索引(mins辅助栈存储的是最小值索引,非具体的值)!

最终代码:

import java.util.ArrayList;import java.util.List;public class MinStack {    private List<Integer> data = new ArrayList<Integer>();    private List<Integer> mins = new ArrayList<Integer>();    public void push(int num) throws Exception {        data.add(num);        if(mins.size() == 0) {            // 初始化mins            mins.add(0);        } else {            // 辅助栈mins push最小值的索引            int min = getMin();            if (num < min) {                mins.add(data.size() - 1);            }        }    }    public int pop() throws Exception {        // 栈空,抛出异常        if(data.size() == 0) {            throw new Exception("栈为空");        }        // pop时先获取索引        int popIndex = data.size() - 1;        // 获取mins栈顶元素,它是最小值索引        int minIndex = mins.get(mins.size() - 1);        // 如果pop出去的索引就是最小值索引,mins才出栈        if(popIndex == minIndex) {            mins.remove(mins.size() - 1);        }        return data.remove(data.size() - 1);    }    public int getMin() throws Exception {        // 栈空,抛出异常        if(data.size() == 0) {            throw new Exception("栈为空");        }        // 获取mins栈顶元素,它是最小值索引        int minIndex = mins.get(mins.size() - 1);        return data.get(minIndex);    }}

参考资料:

五、多线程下的HashMap

众所周知,HashMap不是一个线程安全的类。但有可能在面试的时候会被问到:如果在多线程环境下使用HashMap会有什么现象发生呢??

结论:

  • put()的时候导致的多线程数据不一致(丢失数据)

  • resize()操作会导致环形链表

    • jdk1.8已解决环链的问题(声明两对指针,维护两个连链表)

  • fail-fast机制,对当前HashMap同时进行删除/修改会抛出ConcurrentModificationException异常

参考资料:

  • 谈谈HashMap线程不安全的体现:

    • http://www.importnew.com/22011.html

  • jdk1.8 hashmap多线程put不会造成死循环:

    • https://blog.youkuaiyun.com/qq_27007251/article/details/71403647

六、Spring和Springboot区别

一、SpringBoot是能够创建出独立的Spring应用程序的

二、简化Spring配置

  • Spring由于其繁琐的配置,一度被人成为“配置地狱”,各种XML、Annotation配置,让人眼花缭乱,而且如果出错了也很难找出原因。

  • Spring Boot项目就是为了解决配置繁琐的问题,最大化的实现convention over configuration(约定大于配置)。

    • 提供一系列的依赖包来把其它一些工作做成开箱即用其内置一个’Starter POM’,对项目构建进行了高度封装,最大化简化项目构建的配置。

三、嵌入式Tomcat,Jetty容器,无需部署WAR包

七、G1和CMS

G1收集器的设计目标是取代CMS收集器,它同CMS相比,在以下方面表现的更出色:

  • G1是一个有整理内存过程的垃圾收集器,不会产生很多内存碎片。

    • CMS采用的是标记清除垃圾回收算法,可能会产生不少的内存碎片

  • G1的Stop The World(STW)更可控,G1在停顿时间上添加了预测机制,用户可以指定期望停顿时间。

拓展阅读:

  • G1 垃圾收集器介绍:https://javadoop.com/post/g1

八、海量数据解决方案

海量数据的处理也是一个经常考的知识点,无论在面试还是在笔试中都是比较常见的。有幸读了下面的文章,摘录了一些解决海量数据的思路:

  • Bloom filter布隆过滤器

    • 适用范围:可以用来实现数据字典,进行数据的判重,或者集合求交集

  • Hashing

    • 适用范围:快速查找,删除的基本数据结构,通常需要总数据量可以放入内存

  • bit-map

    • 适用范围:可进行数据的快速查找,判重,删除,一般来说数据范围是int的10倍以下

  • 堆

    • 适用范围:海量数据前n大,并且n比较小,堆可以放入内存

  • 双层桶划分----其实本质上就是【分而治之】的思想,重在“分”的技巧上!

    • 适用范围:第k大,中位数,不重复或重复的数字

  • 数据库索引

    • 适用范围:大数据量的增删改查

  • 倒排索引(Inverted index)

    • 适用范围:搜索引擎,关键字查询

  • 外排序

    • 适用范围:大数据的排序,去重

  • trie树

    • 适用范围:数据量大,重复多,但是数据种类小可以放入内存

  • 分布式处理 mapreduce

    • 适用范围:数据量大,但是数据种类小可以放入内存

详细可参考原文:

  • 十道海量数据处理面试题与十个方法大总结:

    • https://blog.youkuaiyun.com/v_JULY_v/article/details/6279498

九、幂等性

9.1HTTP幂等性

昨天去做了一套笔试题,经典的HTTP中get/post的区别。今天回来搜了一下,发现跟之前的理解有点出入。

如果一个人一开始就做Web开发,很可能把HTML对HTTP协议的使用方式,当成HTTP协议的唯一的合理使用方式。从而犯了以偏概全的错误

单纯以HTTP协议规范来说,可能我们之前总结出的GET/POST区别就没用了。(但通读完整篇文章,我个人认为:如果面试中有GET/POST区别,还是默认以Web开发场景下来回答较好,这也许是面试官想要的答案)

参考资料:

  • GET和POST有什么区别?及为什么网上的多数答案都是错的。

  • http://www.cnblogs.com/nankezhishi/archive/2012/06/09/getandpost.html

其中也学习到了幂等性这么一个概念,于是也做做笔记吧~~~

Methods can also have the property of “idempotence” in that (aside from error or expiration issues) the side-effects of N > 0 identical requests is the same as for a single request.

从定义上看,HTTP方法的幂等性是指一次和多次请求某一个资源应该具有同样的副作用。

  • 这里简单说一下“副作用”的意思:指当你发送完一个请求以后,网站上的资源状态没有发生修改,即认为这个请求是无副作用的

HTTP的GET/POST/DELETE/PUT方法幂等的情况:

  • GET是幂等的,无副作用

    • 比如我想要获得订单ID为2的订单:`http://localhost/order/2`,使用`GET`多次获取,这个ID为2的订单(资源)是不会发生变化的!

  • DELETE/PUT是幂等的,有副作用

    • 比如我想要删除或者更新ID为2的订单:`http://localhost/order/2`,使用`PUT/DELETE`多次请求,这个ID为2的订单(资源)只会发生一次变化(是有副作用的)!但继续多次刷新请求,订单ID为2的最终状态都是一致的

  • POST是非幂等的,有副作用的

    • 比如我想要创建一个名称叫3y的订单:`http://localhost/order`,使用`POST`多次请求,此时可能就会创建多个名称为3y的订单,这个订单(资源)是会多次变化的,每次请求的资源状态都会变化!

题外话:

HTTP协议本身是一种面向资源的应用层协议,但对HTTP协议的使用实际上存在着两种不同的方式:一种是RESTful的,它把HTTP当成应用层协议,比较忠实地遵守了HTTP协议的各种规定(充分利用了HTTP的方法);另一种是SOA的,它并没有完全把HTTP当成应用层协议,而是把HTTP协议作为了传输层协议,然后在HTTP之上建立了自己的应用层协议

参考资料:

  • 理解HTTP幂等性

    • http://www.cnblogs.com/weidagang2046/archive/2011/06/04/2063696.html#!comments

  • 如何理解RESTful的幂等性

    • http://blog.720ui.com/2016/restful_idempotent/

  • 浅谈HTTP中Get与Post的区别

    • http://www.cnblogs.com/hyddd/archive/2009/03/31/1426026.html

  • HTTP 请求中 POST 和 GET 请求的区别?

    • https://www.zhihu.com/question/27622127/answer/37676304

9.2接口幂等性

在查阅资料的时候,可以发现很多博客都讲了接口的幂等性。从上面我们也可以看出,POST方法是非幂等的。但我们可以通过一些手段来令POST方法的接口变成是幂等的。

说了那么多,那接口设计成幂等的好处是什么????

举个例子说一下非幂等的坏处:

  • 3y大一的时候是要抢体育课的,但学校的抢课系统做得贼烂(延迟很高)。我想要抢到课,就开了10多个Chrome标签页去抢(即使某个Chrome标签页崩了,我还有另外的Chrome标签页是可用的)。我想抢到乒乓球或者羽毛球。

  • 抢课时间一到,我就轮着点击我要想抢的乒乓球或者羽毛球。如果系统设计得不好,这个请求是非幂等的(或者说事务控制得不好),我手速足够快&&网络足够好,那我很可能抢到了多次乒乓球或者羽毛球的课程了。(这是不合理的,一个人只能选一门课,而我抢到了多门或者多次重复的课)

  • 涉及到商城的应用场景可能就是:用户下了多个重复的订单了

如果我的抢课接口是幂等的话,那就不会出现这个问题了。因为幂等是多次请求某一个资源应该具有同样的副作用。

  • 在数据库后台最多只会有一条记录,不存在抢到多门课的现象了。

说白了,设计幂等性接口就是为了防止重复提交的(数据库出现多条重复的数据)!

网上有博主也分享了几条常见解决重复提交的方案:

  1. 同步锁(单线程,在集群可能会失效)

  2. 分布式锁如redis(实现复杂)

  3. 业务字段加唯一约束(简单)

  4. 令牌表+唯一约束(简单推荐)---->实现幂等接口的一种手段

  5. mysql的insert ignore或者on duplicate key update(简单)

  6. 共享锁+普通索引(简单)

  7. 利用MQ或者Redis扩展(排队)

  8. 其他方案如多版本控制MVCC 乐观锁 悲观锁 状态机等。。

参考资料:

  • 分布式系统接口幂等性

    • http://blog.brucefeng.info/post/api-idempotent

  • 如何避免下重复订单

    • https://www.jianshu.com/p/e618cc818432

  • 关于接口幂等性的总结

    • https://www.jianshu.com/p/6eba27f8fb03

  • 使用数据库唯一键实现事务幂等性

    • http://www.caosh.me/be-tech/idempotence-using-unique-key/

  • API接口非幂等性问题及使用redis实现简单的分布式锁

    • https://blog.youkuaiyun.com/rariki/article/details/50783819

最后

乐于输出干货的Java技术公众号:Java3y。公众号内有200多篇原创技术文章、海量视频资源、精美脑图,不妨来关注一下!

640?wx_fmt=jpeg
帅的人都关注了
觉得我的文章写得不错,不妨点一下 好看 并 分享 给朋友!


秋招攻略!2023最全Java面试题目合集,看完卷死其他人 (含:Redis核心数据结构,Redis持久化机制与安全机制,哨兵与集群架构,Redis缓存穿透,缓存失效,缓存雪崩,Redis缓存设计与性能优化等)(含:分布式架构原理,集群架构原理,分布式锁,分布式事务,分布式协议,分布式配置,海量数据分库分表,分布式调度,等)(含:消息丢失,消息重复消费,消息乱序,消息积压,延时队列,消息回溯消费,消息刷盘机制,MQ中间件集群架构原理等)(含:单例模式,工厂模式,抽象工厂模式,建造者模式,原型模式,适配器模式,装饰器模式,代理模式等23种设计模式) 阅读详情

相关推荐

java面试100题(应届生必备)

=对于基本类型来说是值比较,对于引用类型来说是比较的是引用;而equals默认情况下是引用比较,只是很多类重新了equals方法,比如String、Integer等把它变成了值比较,所以一般情况下equals比较的是值是否相等。...

m0_67401382的博客 1万+

校招会遇到的JAVA基础面试题(含回答技巧)

这一个月偷偷去了几家公司与两三场模拟面、电话面,我会在下面写一些经常被面的题目,有些回答是根据自己的理解回答的,可能会有一些不全面,欢迎大家在评论区里补充(记住最重要的一点:刷面试题的时候千万不要死记硬背,要理解的去背,不然面试官随便换一种方式来问你就有可能答不上来,又想到了第一次面试的时候当时很多内容都有死记硬背的影子,结果可想而知,想到这里心情就......)

忆梦九洲的博客 1411

2024最新Java面试题之总结的十道 JVM 面试真题!(建议收藏)!

一、头条一面:JVM 从 GC 角度看,堆的分区情况?二、美团一面:说下JVM的垃圾回收算法?三、滴滴一面:你知道哪几种垃圾回收器,各自的优缺点?四、字节二面:JVM 各区域间是如何协同工作的?五、蚂蚁金服一面:说下 G1 收集器?六、字节二面:System.gc() 和 Runtime. getRuntime(). gc()会做什么事情?七、京东二面:讲下 jvm 调优思路?八、阿里一面:什么情况下触发垃圾回收?九、美团一面:有在⼯作时间中使⽤过 jstat, jmap, mat⼯具吗?

程序员高级码农的博客 6895

java程序员面试题大全含答案(2018--2019)

java程序员面试题大全含答案(2018--2019) 1、10道经典java面试题_实习生必问! 2、15个Java线程并发面试题和答案 3、15个高级Java多线程面试题及回答 4、2018年java分布式相关最新面试题 5、2018最新java技术面试题与答案 6、4个Spring常见面试题及答案解析 7、css面试题及答案 8、HR常问面试题总结(...

技术研究中心 4142

分享十道Selenium面试题(附答案)

          软件测试培训也是一种提升技术及迅速转行的辅助手段,不管在哪学你都必须先去试听,看看讲课的风格及氛围,是否通俗易懂,课件是否老化,工具是否过时,课程内容及项目是否具有实战性,主要就是了解项目实战周期是多久,工具是否属现在主流,还有你自己喜不喜欢讲师的讲课风格,如果不喜欢讲师的上课风格也会对你的学习进度造成一定的影响,今天给大家分享Selenium的面试题。希望在学习的小伙伴都能...

a575223的博客 3367

每天十道面试题(一)

Java基础部分面试题汇总及解答(一)

锦鲤姑娘的博客 2万+

关于Java基础最易错的十道面试题

类型擦除是发生在Java泛型中的,Java泛型实现是在编译层,由于编译后生成的字节码不包含泛型中的类型信息,所以使用泛型的时候,加上类型参数会在编译器编译的时候去掉,这个过程就是类型擦除,在代码中定义List和List等类型,在编译后都会变成List,JVM看到的只是List,而由泛型附加的类型信息对JVM是看不到的。??????????????????????System.out.println("两者相同吗?????

m0_74824517的博客 947

java开发校招面试题库(附答案与解析)java篇.pdf

牛客网精心整理的面试题,主要包括java基础,mysql,数据结构与算法,集合,多线程,spring,javaee

关于JVM常见的十道面试题

这是一篇关于JVM常见十道面试题,都是比较容易疏忽并且面试的时候,经常会考到的面试题,文章中有详细的解释和底层原理来帮助你更好的来理解面试题!!

loss_rose777的博客 7335

华为JAVA面试题

2018年华为深圳Java面试题答题模板,主要的答题规范和思路整理。

cesium 高程数据使用

cesium 高程数据使用高程数据下载高程数据切片简单数据服务 高程数据下载 使用地理空间数据云平台免费提供的高程数据。地理空间云平台 点击列表中的下载得到数据压缩包。例如:ASTGTM2_N22E114.zip 高程数据切片 使用cesium实验室工具对下载得到的压缩包进行切片。cesium实验室 切片得到的文件夹目录。 简单数据服务 使用nodejs的koa启动简单的资源服务。koajs 项目根目录新建data文件夹,在新建dem文件夹放高程数据。 注意目录自行更换,这里是./data/dem

哎哟这个凉白白的博客 1811

java常考面试题_探讨Java中最常见的十道面试题

探讨Java中最常见的十道面试题第一,谈谈final, finally, finalize的区别。final?修饰符(关键字)如果一个类被声明为final,意味着它不能再派生出新的子类,不能作为父类被继承。因此一个类不能既被声明为 abstract的,又被声明为final的。将变量或方法声明为final,可以保证它们在使用中不被改变。被声明为final的变量必须在声明时给定初值,而在以后的引用中只...

weixin_33544518的博客 94

【有啥问啥】智能座舱CPD技术:毫米波雷达如何守护儿童安全?

本文深入探讨了智能座舱中CPD(Child Presence Detection)技术如何通过毫米波雷达保障儿童安全。毫米波雷达凭借其穿透性检测、微动感知等优势,成为儿童遗留车内的有效解决方案。文章详细解析了技术原理、系统集成方案及安装指南,为智能座舱安全技术提供了实用参考。

weixin_29193259的博客 357

关于JVM常见的十道面试题(超详细!!!)

本文详细介绍了Java中的强引用、软引用、弱引用和虚引用,以及它们的使用场景。同时探讨了垃圾回收算法如标记-清除、标记-整理、复制和分代算法,以及JVM中的常见垃圾回收器G1和CMS的区别,强调了内存管理在Java中的重要性。

2202_75481735的博客 2940

别再只用CANape测数据了!手把手教你用ASAP2 Studio编辑A2L文件(附MAP文件更新避坑指南)

本文深入探讨ASAP2 Studio在ECU开发中的高阶应用,特别是如何利用其编辑A2L文件并同步更新MAP文件,提升测量标定效率。文章详细解析了ASAP2 Studio的双向同步能力、MAP文件更新全流程及变量管理技巧,帮助工程师避免常见错误,优化工作流程。

weixin_26833939的博客 508

sentaurus学习笔记(HFET_pGate_GaN仿真)(五)

`(sdedr:define-constant-profile`和`(sdedr:define-constant-profile-region`命令用于定义并应用一个恒定的活性硼掺杂浓度剖面`"ndop_GaN_gate_const"`到氮化镓栅极层上,其值为`NpGaN_gate`。- `"Oxide"`指定了这一层的材料名称(在这里代表氧化层),而`"nucleation"`是这一层在仿真中的标识名称。- `"GaN"`指定了这一层的材料名称,而`"GaN_gate"`是这一层在仿真中的标识名称。

qq_52640792的博客 940

自学JAVA的我终于拿到阿里offer了,给我的秋招交上满意答卷,分享一下面试题和我的资料!

前言 简单的说一下自己吧,95后的一个江西小青年(ps:95年的也算95后吧),自己在大学的时候就喜欢逛论坛,刷博客,这几年更是喜欢看那些技术博主的文章,感觉我什么时候有能力了,一定要写篇文章回馈给大家!所谓天道酬勤,前几天拿到的阿里offer,算是给我这些年以及这个秋招最满意的答卷了!现在我写上我的第一篇文章,不求跟大佬的一样让你们学到很多,但我把我的会的一定知无不言,我的面试经验,我的资料全部在下面了,希望对你们有帮助! 面经分享 我这里为大家准备了一线大厂面试资料和我原创的超硬核PDF技术文档,以及我

weixin_53170315的博客 3730

从零构建锂电池主动均衡系统:Simulink仿真中的Buck-Boost拓扑实战指南

本文详细介绍了如何在Simulink中从零构建基于Buck-Boost拓扑的锂电池主动均衡系统。通过仿真环境搭建、参数优化、控制策略设计和性能评估,为工程师提供了完整的实战指南,帮助快速验证和优化均衡算法,提升电池组一致性与寿命。

gitlab7runner的博客 896

Java中最常见的十道面试题[精校版]

Address:http://www.xuebuyuan.com/39011.html Name: 学步园 第一,谈谈final, finally, finalize的区别。 final?修饰符(关键字)如果一个类被声明为final,意味着它不能再派生出新的子类,不能作为父类被继承。因此一个类不能既被声明为 abstract的,又被声明为final的。将变量或方法声明为final,...

FeelTouch Labs 559

简单的图书管理系统---SpringBoot+mysql通过前后端分离实现增删查改

SpringBoot+mysql通过前后端分离实现增删查改 上篇文章介绍了如何写后端接口 SpringBoot连接MySQL获取数据写后端接口 这篇文章,我们就介绍一下怎么写前端 点击修改跳出修改界面,点击添加书籍跳出添加书籍界面 点击删除,直接删除一行数据 其他的也没什么解释了,直接上代码(看不懂的可以私聊我哟) <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>

爱笑的博客 2015

基于YOLOv5的人脸识别系统:从构建到应用的全流程指南

本文详细介绍了基于YOLOv5的人脸识别系统开发全流程。首先阐述了YOLOv5模型的高效性和准确性优势,随后分步骤讲解了深度学习环境配置、数据集准备(推荐WIDER FACE数据集)和模型训练方法。重点展示了如何将训练好的模型集成到Tkinter开发的GUI界面中,实现图片上传、人脸检测和结果可视化功能。文章提供完整的代码示例和飞书文档链接(密码:946m22&8),帮助开发者快速构建可交互的人脸识别系统,适用于安防、门禁等多种应用场景。通过该项目,读者可掌握YOLOv5的实际应用和界面集成技术。

FJN110的博客 169
上一篇: 一文带你看懂Spring事务!
下一篇: 一文带你认识Spring事务
Java3y
Java3y 领域专家: 后端开发技术领域 领域专家: 后端开发技术领域
博客等级 码龄9年 1万+粉丝 509原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值