2020.11.25

概要

本次面试是最近刚面的。

PS:本人java开发2年经验,这次面的是滴滴出行(小桔科技)java开发岗。

2020.11.30

滴滴又打来电话了, 预定12.3.星期四面试,不过是另一个java岗位,还是一面;

说明这次的凉了,然后又被HR捞起来了……

很迷,我都不知道该说什么好……

等面完后再总结一篇新的文章吧……

过程

1.2020年11月16日,本人投给滴滴的简历变成了"被查看"状态(也是在拉勾APP投的),不过多会投的就忘了,应该也是前一二天吧。

PS:投给字节跳动的简历还是"投递成功"状态,甚至没有被查看,看来字节跳动是真的不在拉勾上更新简历进度,不过个人觉得这个也不是很重要,只是记录一下。

2.2020年11月23日,本人接到了滴滴的电话,预约面试时间,本人预约了11月24日20:30的面试。

3.然后收到了邮件,其中写着面试时间,以及面试方式;这次要使用腾讯会议PC版视频面试。

4.2020年11月24日,18:00,HR又打来电话,询问面试时间是否有调整,很周到;本人回复不用调整。

5.2020年11月24日,20:30-21:15,进行了滴滴视频面试。

6.今天25日,等待结果中,希望无论如何给一个结果通知……

面试内容

1.自我介绍。

*期间面试官自言自语说本人工作时间不长,本人目前2年java开发经验,如果还不够的话,难道是必须要3-5年?

2.询问做过的项目,主要问项目问的比较多,以及项目细节。

3.你的项目业务比较复杂吗?

答:是的。然后介绍了一个大批量推送的需求是如何实现的。

4.接第三问:你刚才介绍的是技术实现复杂,不是业务复杂。

答:又扩展介绍了一下项目流程,不过面试官认为又回归到介绍技术实现复杂了;只好回答,那它可能并没有那么复杂。

5.编写一个程序,有三个线程,分别输出A/B/C,现在让它们按顺序输出ABC,并循环十次,你能想到几种实现思路?

答:使用公平锁Reentrantlock(true)实现;有一个java线程池也可以实现;使用线程的wait()与notify()也可以实现。(synchronized个人感觉不能实现,这个是非公平锁,不讲顺序)

6.编码实现第五题(点击腾讯会议的共享屏幕),参考答案如下(终于碰到一个可以做出来的编程题了):

首先创建一个自定义线程类,准备使用Reentrantlock:

importjava.util.concurrent.locks.ReentrantLock;public class MyThread extendsThread{privateReentrantLock lock;privateString str;publicMyThread(String str, ReentrantLock lock){this.str =str;this.lock =lock;

}

@Overridepublic voidrun() {for(int i = 0; i<10; i++){

lock.lock();

System.out.println(str);

lock.unlock();

}

}

}

然后是main方法:

importjava.util.concurrent.locks.ReentrantLock;public classTest {public static voidmain(String[] args) {//有三个线程,分别输出ABC,现在要求线程按顺序输出并且循环10次

ReentrantLock lock = new ReentrantLock(true);

MyThread t1= new MyThread("A",lock);

MyThread t2= new MyThread("B",lock);

MyThread t3= new MyThread("C",lock);

t1.start();

t2.start();

t3.start();

}

}

这样就实现了题目要求。

*之后明显感觉难度开始上升。

7.你知道volatile关键字解析吗?(从来没听过)

百度:

https://blog.51cto.com/12222886/1964228

https://www.cnblogs.com/dolphin0520/p/3920373.html

●Java中的volatile

在Java程序中,如果一个变量被volatile关键字修饰,那么这个变量就具有了有序性和可见性。

有序性:java语言中提供了synchronized和volatile两个关键字保证线程之间操作的有序性,也就是他可以使CPU指令有序。

可见性:当一个线程操作一个被volatile修饰的变量时,这个变量的修改对其他所有线程都是可见的,因为此时的操作不会将该变量读到当前线程的CPU缓存中进行操作,而是直接操作内存

●个人理解与总结

volatile修饰变量后,这个变量会存入内存,变成共享变量,线程读写时直接操作内存中的这个变量,跳过CPU cache这一步,因此在读取这个变量时总会返回最新写入的值;

并且,在操作这个变量时是有序的,CPU指令有序;

并且,在访问volatile变量时不会执行加锁操作,也就不会使执行线程阻塞,因此volatile变量是一种比synchronized关键字更轻量级的同步机制。

●synchronized原理

synchronized可以修饰方法、对象、类;在修饰方法时又分为实例方法、静态方法、代码块。

对于同步块的实现使用了monitorenter和monitorexit指令:他们隐式的执行了Lock和UnLock操作,用于提供原子性保证。

monitorenter指令插入到同步代码块开始的位置、monitorexit指令插入到同步代码块结束位置,jvm需要保证每个monitorenter都有一个monitorexit对应。

这两个指令,本质上都是对一个对象的监视器(monitor)进行获取,这个过程是排他的,也就是说同一时刻只能有一个线程获取到由synchronized所保护对象的监视器。

线程执行到monitorenter指令时,会尝试获取对象所对应的monitor所有权,也就是尝试获取对象的锁;而执行monitorexit,就是释放monitor的所有权。

详情见:https://www.cnblogs.com/wuzhenzhao/p/10250801.html

8.数据库有两个条件分别加了索引,按照两个条件查询时索引怎么走(两个索引同时用吗?不知道)

百度与个人总结(MySql):

(1)首先,索引可以给一个字段加,也可以给多个字段加,如图(Navicat):

其中,名是自己起的,栏位对应表中的字段;

(2)加索引之后,当select对应字段、或group by、或order by、或其它增删改查时,都可能会用到索引,提高sql执行效率。

如果经常用到多个字段(例如group by或order by多个字段),就应该给多个字段加一条索引。

关于order by,只有出现在where条件中,才可能会走索引;group by等也类似。详情见:https://www.cnblogs.com/zhaoyl/archive/2012/05/04/2483513.html

(3)如果两个条件都加了索引,sql执行时,会选择影响行数较少的索引,即区分度大的索引。(使用explain分析结果时,rows的值小的。)详情见:https://blog.csdn.net/qq_22771739/article/details/85853620

9.如何知道一句sql走了哪个索引?(好像是有一个语法是调试sql用的,然而忘了,还是不常用)

百度:参考网址:https://www.cnblogs.com/wqbin/p/12124621.html

使用explain,可以查看sql是否走了索引

explain select * from test group by user

之后,可以查看结果(本人用Navicat执行的sql)。

举个例子:

(1)数据库表

(2)表设计

(3)索引(自己设置的)

(4)执行【explain select * from test group by user】,返回结果:

其中,type为index,说明有索引;(type结果值从好到坏依次是:system > const > eq_ref > ref > fulltext > ref_or_null > index_merge > unique_subquery > index_subquery > range > index > ALL)

key为实际使用的索引,user_index,说明使用了这个字段的索引。

possible_keys为可能需要使用的索引,正常情况下与key相同;这里为空,说明可能用不到索引也能高效完成查询(不过后来发现还是用索引好)。详细原因可见:https://blog.csdn.net/eden_Liang/article/details/108026148

(5)执行【explain select * from test 】返回结果:

可以看到,type为ALL,并且key为空,说明没有使用索引。

10.线程池实现原理(只基本会用,没研究过原理)

百度:

为什么需要使用线程池?

●当使用大量线程时,减少大量的new线程与GC回收线程的额外开销。

首先,java有四种线程池:

●newSingleThreadExecutor

创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。

●newFixedThreadPool

创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。

●newScheduledThreadPool

创建一个可定期或者延时执行任务的定长线程池,支持定时及周期性任务执行。

●newCachedThreadPoo

创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。

原理:

所谓线程池本质是一个hashSet。多余的任务会放在阻塞队列中。

只有当阻塞队列满了后,才会触发非核心线程的创建。所以非核心线程只是临时过来打杂的。直到空闲了,然后自己关闭了。

线程池提供了两个钩子(beforeExecute,afterExecute)给我们,我们继承线程池,在执行任务前后做一些事情。

线程池原理关键技术:锁(lock,cas)、阻塞队列、hashSet(资源池)

详情网址:

https://www.cnblogs.com/rinack/p/9888717.html

https://www.cnblogs.com/franson-2016/p/13291591.html

11.线程interrupt()作用(已经被问蒙了,这个也不会了)

百度:

interrupt() 方法只是改变中断状态而已,它不会中断一个正在运行的线程。*相当于只是改变了isIntrerrupt()返回的boolean值。(当然还有些其它操作,不过主要是改变这个值,其它方法中会根据这个方法判断当前线程状态。)

如果线程阻塞前调用这个方法,那么当该线程遇到阻塞时,会抛异常,停止运行;

如果线程处于阻塞状态,调用这个方法,也能让线程抛异常,停止运行。

更确切的说,如果线程被Object.wait, Thread.join和Thread.sleep三种方法之一阻塞,此时调用该线程的interrupt()方法,那么该线程将抛出一个 InterruptedException中断异常(该线程必须事先预备好处理此异常),从而提早地终结被阻塞状态。

如果线程没有被阻塞,这时调用 interrupt()将不起作用,直到执行到wait(),sleep(),join()时,才马上会抛出 InterruptedException。

详情见:https://blog.csdn.net/liujian8654562/article/details/79875853

再总结下线程基本方法:

●线程有五种状态,新建,就绪,运行,阻塞,死亡

●newThread()创建的线程,是新建状态的。

●使用start()方法,线程进入就绪状态;等待获得资源后,执行run()方法中的内容,此时算运行状态。

●线程运行状态中,遇到某些情况时会进入阻塞状态,如需要执行输入输出但是资源不足;或者人为使用sleep(),suspend(),wait()方法,也会让线程处于阻塞状态。

●线程调用stop(),destory(),或者run()方法执行完毕,就会进入死亡状态。

●sleep()方法可以让线程等待一段时间后再运行,此时是阻塞状态,不释放资源;此时会让出cpu,但是不释放锁。

●wait()方法可以让线程进入阻塞状态,释放资源;JVM把这个线程放入等待池;需要等待其它线程使用notify()或notifyAll()

●wait(longtimeout)方法可以让线程进入阻塞状态,释放资源;需要等待其它线程使用notify()或notifyAll(),或者超过时间后,这个线程变为就绪状态

●notify()方法可以让线程从阻塞状态变为就绪状态,JVM把这个线程从等待池中取出;一般是其它线程调用这个方法。

●suspend()使线程阻塞,resume()唤醒线程,这两个方法及其它所有方法在线程阻塞时都不会释放占用的锁(如果占用了的话);而wait()和notify()这一对方法会释放锁。

●yield()的作用是让步,它能够让当前线程从“运行状态”进入到“就绪状态”,从而让其他等待线程获取执行权,但是不能保证在当前线程调用yield()之后,其他线程就一定能获得执行权,也有可能是当前线程又回到“运行状态”继续运行。

详情见:https://blog.csdn.net/wordwarwordwar/article/details/85924858

●需要注意,sleep(),suspend(),resume(),yield(),start(),stop(),destory()这些方法的主体是线程,如new Thread().suspend();

●而wait(),notify(),notifyAll()的主体可以是任何对象,例如new String().wait();具体使用方式见下方网址:

关于notify()与notifyAll():https://blog.csdn.net/qq_42547338/article/details/107448668

●还需要注意,java中,destory()方法并没有被实现,例如new Thread().destory(),调用该方法只会抛出一个异常:NoSuchMethodError();这个方法需要自己继承Thread类后重写。

●还需要注意,直接使用stop(),会立即停止线程,可能导致文件流、数据库连接没有关闭,因此不推荐使用。推荐标志位与interrupt()等组合使用来停止线程,详细使用如下(记住只用interrupt()是不会真的停止线程的):

https://www.cnblogs.com/liyutian/p/10196044.html

12.你还有什么问题?

后记

这些问题的答案本人会继续完善。

整体感觉,前半部分还可以,后半部分就都不会了,感觉明显从编程题后难度提升了。

好不容易遇到一个会做的编程题,这次不想又不明不白的凉了。

希望有戏吧……

滴滴java开发面试题_滴滴出行(小桔科技)亲身面试经验分享,java开发岗相关推荐

  1. 滴滴java开发面试题_滴滴java开发工程师面试问题解答(第一回)

    有位同学写了一个滴滴面试拿offer的经历,据说还面了滴滴的CTO,我就好奇,这CTO面又能是个啥水平呢?对他在文章中提到的部分问题做个解答吧. 原文请见滴滴CTO五轮面试真是太刺激了,Java高级工 ...

  2. 滴滴java开发面试题_滴滴java面试重点汇总

    java基础 集合 集合分为两大块:java.util包下的非线程安全集合和java.util.concurrent下的线程安全集合. List ArrayList与LinkedList的实现和区别 ...

  3. 美国道富java开发面试题_从事Java开发五年,面试9家拿到7家offer,1096面试+67笔试题...

    个人情况 时间总是在不经意间流逝,我们也在人生的旅途上不断前行,转眼间在微软的美国总部工作近两年了.生活总给我们带来新的挑战,同时也有新的惊喜.这两年在陌生的国度里用着不太流利的英语和各种肤色的人交流 ...

  4. 滴滴java开发面经_滴滴 Java研发 社招面经

    自我介绍 为什么离职 当前平台发展有限,项目进入稳定期,新需求不多,维护为主,对个人发展不利 说一下HashMap的数据结构,复杂度 这里可以以put方法作为切入点,把put方法分析出来,数据结构和复 ...

  5. 中软国际java开发面试题_中软国际java面试题及参考答案

    面试题是中软国际java个人求职者在面试过程中的敲门砖,以下是小编为大家收集到的,希望对大家有帮助! :填空题 1Java语言具有许多优点和特点,下列选项中,哪个反映了Java程序并行机制的特点? B ...

  6. JAVA开发面试题_网络_操作系统_JAVA基础_JVM虚拟机

    目录 网络篇 OSI七层模型与TCP/IP 五层模型 常见应用层协议和运输层.网络层协议,以及硬件如路由器之类在哪一层 TCP与UDP区别和应用场景,基于TCP的协议有哪些,基于UDP的有哪些 TCP ...

  7. 思科java开发面试题

    思科java开发面试题 1.mybatis怎么用的 2.MySQL怎么用的 3.git怎么用的 4.hashmap和hashtable 5.建立多线程 6.设计模式 7.程序的优化 8.程序的安全

  8. 2023年最新大厂开发面试题(滴滴,华为,京东,腾讯,头条)

    2023年最新大厂开发面试题!!! 滴滴篇 B+树.B-树的区别? 数据库隔离级别,幻读和不可重复读的区别? 有 hell, well, hello, world 等字符串组,现在问能否拼接成 hel ...

  9. 初级测试开发面试题_初级开发人员在编写单元测试时常犯的错误

    初级测试开发面试题 自从我编写第一个单元测试以来已经有10年了. 从那时起,我不记得我已经编写了成千上万的单元测试. 老实说,我在源代码和测试代码之间没有任何区别. 对我来说是同一回事. 测试代码是源 ...

最新文章

  1. 抽象工厂模式java_Java之抽象工厂模式(Abstract Factory)
  2. C#中out 及 ref 区别
  3. SharePoint KB
  4. webpack快速构建项目
  5. centos查看网关地址
  6. 分布式系统的面试题5
  7. 修正IE6中FIXED不能用的办法,转载
  8. xfce的开始菜单增加搜索框
  9. 服务器控件开发之基本概念
  10. php 智能输入提示插件,PHP结合jQuery.autocomplete插件实现输入自动完成提示的功能_php实例...
  11. [APIO2013]机器人[搜索、斯坦纳树]
  12. 让AI打工!搜狗全体员工于3月12日狗胜节放假一天
  13. U 盘无法拷贝大于 4GB 文件的解决方法
  14. Java 多线程(三)优先级、休眠(未完待续...)
  15. 根据判断浏览器类型屏幕分辨率自动调用不同CSS的代码
  16. 企业框架源码 SpringMVC mybatis ehcache shiro maven
  17. 从stm32转向Linux,STM32MP1Distrib
  18. html语言单个单元格背景颜色,html如何设置表格和单元格的背景颜色
  19. C语言基本变量类型及变量的定义
  20. 如何把固态硬盘系统克隆到固态硬盘,笔记本硬盘复制到另一个硬盘

热门文章

  1. 偷偷爆料下国内比较大型的 IT 软件外包公司名单(2023 最新版!)
  2. 数据结构-3 堆积木
  3. 人脸检测:RetinaFace(开源简化版)详细解读
  4. 在python程序中数据的来源可以是-python起源,变量,用户交互,流程语句
  5. rmvb 文件格式解析
  6. 交易模拟器 android,为Android/Chrome融合打基础? 谷歌收购模拟器团队
  7. ScrollPic.js——图片左右滚动插件(单一功能)
  8. Principles of fMRI 1课程笔记8--fMRI的数据预处理
  9. android导入support-v4包(导包通用教程)
  10. 反调试/反汇编技术、TEB/PEB部分说明