文章目录

  • 笔试
  • 面试
  • 复盘
    • Java基础
      • String 、StringBuilder、StringBuffer
      • ArrayList 和 LinkedList 使用场景?
      • 完美的 equals() 方法
      • 讲一下 HashMap 的put() 过程
      • IO
      • NIO/同步、异步、阻塞、非阻塞
    • 虚拟机
        • Hosts 文件
      • CPU Load过高怎么排查?该如何快速排查原因?
    • 线程安全有哪些实现方式
      • 线程本地变量
      • Reetrant可重入锁
      • 原子操作类
        • (1)synchronized 同步锁
        • (2)LockSupport 阻塞锁
        • 同步器、锁底层的实现:AQS
        • (3)ReentrantLock lock同步锁
        • (4)ReentrantReadWriteLock 读写锁
      • 三个同步器
        • (5)Semaphore 信号量锁
        • (6)CountDownLatch 共享锁
        • (7)CyclicBarrier 回环屏障
      • 举个例子,子方法要有锁,多次调用子方法,这样子方法用什么锁比较合适?
        • 生产者、消费者模型实现 n、n 的阶乘
        • 按锁的类型分类
      • 并发包中对不同的数据结构的实现
        • (1)并发队列
        • (2)ConcurrentHashMap
        • (3) CopyOnWriteArrayList 是怎么实现的?
        • (4)CopyOnWriteArraySet
    • 今日补充
      • 底层实现系列
      • 了解

蚂蚁金服商家中台事业部

笔试

  • 生产者-消费者模型,线程A产生整数 n,线程B输出 n 的阶乘。
  • 给一个有序数组 和 数字 n,找到数字 n 的下标。

面试

1.Java基础部分

  • String是不可变的,它为什么不可变?
  • StringBuilder 和 StringBuffer 是怎么实现可变的?
  • ArrayList 和 LinkedList 的区别,和使用场景?
  • equals需要满足什么条件?
  • HashMap 为什么要同时实现 equals 和 hashCode 两个方法?
  • HashMap 发生哈希冲突是怎么处理的?
  • Java 的 IO 模型? NIO?

2.OOP部分

  • 抽象类和接口的区别?使用场景举个例子吧。
           为什么你说抽象类不适合维护和更新?
    说到了1.8的 default 方法,问:这个 default 方法有什么好处?
  • 继承和组合有什么区别?使用场景?

3.线程部分

  • ThreadLocal 的作用是什么?使用场景?
  • 线程安全?有哪些实现方式?
  • 了解的锁?锁分几种?说一下它们之间的区别?最好说使用场景。
    举个例子,子方法要有锁,多次调用子方法,这样子方法用什么锁比较合适?
  • 并发过程中常用到的队列?刚刚的笔试看你没有用队列,你是怎样考虑的?
  • 并发中除了队列外还有很多集合类,常见的 Map、List 、Set里面都有哪些并发集合类?
  • CopyOnWriteArrayList 是怎么实现的?

4.虚拟机

  • 内存模型讲一下
  • GC讲一下

5.Linux

  • 你常用到的 Linux 命令有哪些?
  • CPU Load过高使用率过高怎么排查?
  • inode是什么?
  • host 文件是做什么的?
  • 磁盘内存不够了,怎么找到大的文件?

6.数据库

  • 索引的概念及其使用情景
  • 事务的概念
  • 隔离级别
  • 乐观锁和悲观锁的区别?使用场景?
  • 简述 MVCC
  • 查询语句、删除语句怎么写可以使乐观锁失效?

7.算法

  • 常见排序算法、复杂度、使用场景?
  • 怎么理解时间复杂度?空间复杂度?
  • 怎么实现双向链表?好处?怎么插入和删除元素?

8.网络

  • TCP连接的过程,为什么要三次握手四次挥手?
  • 短连接和长连接?哪些是短连接,哪些是长连接?

9.其他

  • 了解深度学习吗?
  • 怎么学习的?主要通过什么渠道学习?
  • 给我推荐几本书?
  • 在学校通过什么渠道驱动写代码?有没有跟着老师做项目?
  • 做项目遇到的有意思的事情?
  • 在学校有和别人合作的经历吗?有不同想法时怎么变?
  • 你写博客积累到什么程度?
  • 参加的竞赛的背景、遇到的困难?
  • 你有什么想问的?
  • 包括社招,看重基础、思维、编码习惯、技术热情,对Spring有封装… …

复盘

Java基础

String 、StringBuilder、StringBuffer

String 的底层是个 final 修饰的 char[ ],是常量,因此初始化后就不会改变了;而 StringBuffer 、 StringBuilder 初始默认 是来自父类的长度为 16 的 char[ ]。
    StringBuffer 几乎每个方法都用了 synchronized 修饰 ,
线程安全。
♥    用 “ + ”联结起两个字符串:
(1)如果是字符串常量,编译时就把它们拼接成了新的 字符串常量。
(2)如果涉及到非常量,创建 StringBuilder 对象,调用 apped() 方法。
     JDK1.5之前是 StringBuffer,1.5之后是 StringBuilder。

ArrayList 和 LinkedList 使用场景?

(1)如果对数据有较多随机访问,ArrayList 效率更高;
( 2 ) 如果更多 插入 或 删除操作,较少的数据读取,LinkedList 更优,不过ArrayList的插入 或 删除操作也不一定比 LinkedList 慢,如果在List靠近末尾的地方插入,那么 ArrayList 只需要移动较少的数据,而 LinkedList 则需要一直查找到列表尾部,反而耗费较多时间,这时ArrayList就比LinkedList要快。

完美的 equals() 方法

(1)首先比较是否引用同一个对象,如果是,直接返回 true 。
(2)比较是否属于同一个类 或者 有无直接、间接的子类继承关系,如果不是、没有,返回 false。如果有继承关系,需要强转成一致的类。
(3)对需要比较的域作比较,基本类型域用“==”,对象域用 equals() 。

讲一下 HashMap 的put() 过程

如果是数组为空,需要先进行 resize 扩容,默认初始容量是 16 。
    对 key 进行 hashcode 计算,对数组长度取余,求得桶索引,如果索引处的 Node 为 null,就直接插入;否则,遍历链表,判断 key值是否相同,如果相同,新 value 覆盖 旧 value,返回 原 value,如果不相同,说明出现了哈希冲突,需要尾插,这里的 “相同”,就是通过 equlas 进行比较的。

IO
NIO/同步、异步、阻塞、非阻塞

(1)BIO、NIO、AIO 总结
    Java 中的 BIO、NIO和 AIO 理解为是 Java 对操作系统的各种 IO 模型的封装。先来回顾一下这样几个概念:同步与异步,阻塞与非阻塞。

同步: 同步就是发起一个调用后,被调用者未处理完请求之前,调用不返回。
异步: 异步就是发起一个调用后,立刻得到被调用者的回应表示已接收到请求,但是被调用者并没有返回结果,此时可以处理其他的请求,被调用者通常依靠事件,回调等机制来通知调用者其返回结果。
    同步和异步的区别最大在于 异步调用者不需要等待处理结果,被调用者会通过回调等机制来通知调用者其返回结果。
    
阻塞: 阻塞就是发起一个请求,调用者一直等待请求结果返回,也就是当前线程会被挂起,无法从事其他任务,只有当条件就绪才能继续。
非阻塞: 非阻塞就是发起一个请求,调用者不用一直等着结果返回,可以先去干其他事情。

    
BIO (Blocking I/O) 同步阻塞
    服务端创建一个 ServerSocket , 然后就是客户端用一个Socket 去连接服务端的那个 ServerSocket, ServerSocket 接收到了一个的连接请求就创建一个Socket和一个线程去跟那个 Socket 进行通讯。接着客户端和服务端就进行阻塞式的通信,客户端发送一个请求,服务端 Socket 进行处理后返回响应,在响应返回前,客户端那边就阻塞等待,什么事情也做不了。
    这种方式的缺点, 每次一个客户端接入,都需要在服务端创建一个线程来服务这个客户端,这样大量客户端来的时候,就会造成服务端的线程数量可能达到了几千甚至几万,这样就可能会造成服务端过载过高,最后崩溃死掉。
    
NIO(Non-blocking IO) 同步非阻塞
    NIO它支持面向缓冲的,基于通道
    ==通道Channel,==用于接收及存储不同的连接与状态 key。
    有 Selector选择器,负责轮询查看不同通道内的请求,做出相应的选择处理。
    
Java中对于NIO的实现:
    首先程序会向选择器 Selector 中注册通道 Channel,和通道所关注的事件,选择器轮询 Channel ,如果其中有某个事件状态符合所注册的通道事件,那么 Selector 就会将它作为 key 集返回给程序,与此同时,类似于读和写这样的事件,就已经将内容存储到了 buffer 中,程序通过 key 感知到对应事件后,可以直接通过 buffer 去做相应的操作。

(比方说,Tomcat 从 6 开始支持 NIO 模型,客户端发送的连接请求都会注册到 多路复用器上,多路复用器轮询到 连接 有 I/O 请求时才启动一个线程进行处理。)

AIO
    异步非阻塞。
     每个连接发送过来的请求,都会绑定一个Buffer,然后通知操作系统去完成异步的读,这个时间你就可以去做其他的事情,等到操作系统完成读之后,就会调用接口,返回操作系统异步读完的数据。这个时候就可以拿到数据进行处理,将数据往回写,在往回写的过程,同样是给操作系统一个 Buffer ,让操作系统去完成写,写完了来通知你。
这里面的主要的区别在于将数据写入的缓冲区后,就不去管它,剩下的去交给操作系统去完成。操作系统写回数据也是一样,写到Buffer里面,写完后通知客户端来进行读取数据。
    
    以上是 Java 对操作系统的各种 IO 模型的封装,【文件的输入、输出】在文件处理时,其实依赖操作系统层面的 IO 操作实现的。【把磁盘的数据读到内存种】操作系统中的 IO 有 5 种:
阻塞、
非阻塞、【轮询】
异步、
IO复用、【多个进程的 IO 注册到管道上】
信号驱动 IO

虚拟机

Hosts 文件

纯文本形式。
    这个文件包含 IP地址 到 HOST name(主机名)的映射关系,提高解析效率。

CPU Load过高怎么排查?该如何快速排查原因?

Load:Linux系统中,进程有 3 种状态:阻塞、可运行的【在运行队列 run queue 种】、正在运行的,Load 是指正在运行 和 准备好运行的进程总数。
    CPU Load 过高可能是代码中有 Bug(如 死循环)或者 Full GC次数太多。
    首先要找到哪几个线程在占用 CPU ,之后再通过线程的 id值在堆栈文件中查找具体的线程,看看出来什么问题。
(1)先查看进程号 top
    通过top命令动态查看进程变化,默认 5 秒一更新,会显示PID 、%CPU 等,执行 shift+p 可以以 CPU 的使用排序显示。比如使用CPU 最多的进程是 xxx。
(2)确定进程后 top -Hp xxx 显示 指定进程的线程
    这时显示的 PID 是线程ID。
(3)将线程 ID 从十进制转化成 十六进制
    可以用 Windows 计算器,也可以用 printf %x 十进制数 将输出十六进制形式。
(4)显示堆栈信息

jstack 进程号 |grep 线程号

显示栈信息,可以关注一下有无 死锁 或者 等待资源、等待获取监视器、阻塞等。
grep: 全局搜索正则表达式,就像在 IDEA 里 ctrl+F 。)

线程安全有哪些实现方式

(1)synchronized 同步方法 、同步块
(2)volatile 保证内存可见性
(3)JUC 包中的 ReentrantLock 可重入锁
(4)线程本地变量,如 ThreadLocal
(5)并发队列
(6)原子操作类

线程本地变量

ThreadLocal 是个工具类,在 Thread 里有变量 ThreadLocalMap 类型的 threadlocals,为每个线程对象维护一个 线程本地变量,ThreadLocalMap 是 ThreadLocal 的静态内部类,以 ThreadLocal 为 key,以 线程本地变量 为 vaule,当调用 ThreadLocal 的 set 方法时,会先获取当前线程,检查有没有为 这个线程对象 绑定 本地变量,如果没有的话,会创建 map;否则覆盖value。 要注意 :如果当前线程不消亡,这些本地变量就会一直存在,可能会造成内存溢出,所以使用完毕要记得调用 ThreadLocal 的 remove方法,它会调用 Entry 的clear() 方法,提醒 GC,Entry 是弱引用类型。
    还可以讲个类似思想的,ThreadLocalRandom 随机数生成器,它继承 Random ,随机数生成的思想是由 种子 seed 生成新种子,再由新种子计算随机数, Random 类为保证线程安全,使用 CAS操作,每次只能有一个线程可以更新老的种子为新的,失败的线程会自旋 ,直到获取到 种子 作为 自己的当前种子,又去算新的种子 ,从而保证各线程随机数的随机性。而自旋降低了性能。所以 ,ThreadLocalRandom 也像 ThreadLocal 一样,是个工具类,在 Thread 类里有 ==long 类型的变量 ThreadLocalRandomSeed,这样每个线程对象都会持有一个本地种子变量,需要使用随机数的时候才会被初始化,计算随机数时是和 系统的当前时间有关系的,从而保证各线程随机数的随机性。

Reetrant可重入锁

ReentrantLock 是使用 AQS 实现的可重入独占锁,AQS 的状态state 是 0 表示当前 锁空闲,大于等于 1 表示该锁已经被占用。该锁内部有 公平锁 和 非公平锁,默认是非公平锁。
    线程调用 lock 方法,表示希望获取锁,如果锁没有被其他线程占用,且当前线程之前没有获取过该锁,则当前线程会获取到锁,将锁的拥有者 设置为 当前线程,并把 AQS 状态值设置为 1,然后直接返回,如果该锁已经被其他线程持有,线程会被放入 AQS 队列后阻塞挂起。
    不适合 写少读多的情况。

原子操作类

JUC包中提供了一系列原子性操作类,都是用 CAS 实现的,比如 AtomicLong、AtomicInteger.等。
(1) AtomicLong
    可以指定初值,使用 递增、递减方法,或者是 CompareAndSet,它是维护一个 volatile 修饰的 long 变量,递增、递减时候,使用 CAS 修改变量的值,如果设置失败则 自旋 直到设置成功。
(2)JDK8新增了 LongAdder
    从 0 开始,不能指定初值,可以用 add() 实现加法,传入正数、负数皆可,或 decrement() 递减,reset() 置零。
    它在内部维护了一个 volatile 修饰的基值 base 和 一个Cell 【内部类,有 volatile 修饰的 value 】类型的数组 cells ,无线程竞争时,也就是 对 base 使用 CAS 成功了,累加 base 值即可;而如果存在线程竞争,就先会初始化 cells 数组,长度为2,当前线程具体访问 cells 数组里的哪一个 cell ,是由 threadLocalRandomProbe 和 数组长度-1 相与 之后求得的,如果再遇到多个线程访问同一个元素才会以 2 倍扩容,重新计算位置,所以数组长度一直是 2 的幂次方,并且不会大于 CPU 个数,这样可以避免伪共享问题。这样,线程在 某个 cell 上 CAS 失败后,不会自旋,而是去另一个 cells 上尝试修改。最后 ,LongAdder 的真实值是 base 和所有 cell 元素的值的累加。 要注意的是:累加的方法 sum() 并没有对 cells 数组加锁,所以如果其他线程有对 cells 修改值,或者扩容,求出的结果就是不准确的。

(1)synchronized 同步锁

进入同步块后,尝试获取 JVM 中给 类 和 对象 关联的 监视器锁

2020 03 15 蚂蚁金服实习电话一面相关推荐

  1. 蚂蚁金服 java电话面_蚂蚁金服前端电话面试(一面)

    1. 自我介绍 2. 介绍项目相关:如何技术选型,遇到最大的问题,如何解决问题,哪个项目让我学到最多,印象最深刻之类的. 3. 性能优化有哪些原则措施,减少http请求为什么能提高性能?有没具体实践过 ...

  2. 9.15蚂蚁金服hr面

    哪里人,为啥叫这个名字? 研究生期间学的是算法,为什么不做算法 就是想做的开发,从保研找老师就已经确定这个方向了 你是怎么确定自己要做开发的呢 谈到了自己选专业,转专业,保研,实习的经历,感觉自己说得 ...

  3. 记录一下蚂蚁金服的电话面试

    明知道自己肯定达不到阿里的要求的,所以自己把相关的面试问题都记录下来,以便以后复习使用. 1.你常用的设计模式有哪些? 2.工厂模式和策略模式的区别有哪些? 3.什么情况下你会用工厂模式或者策略模式? ...

  4. 今天接到蚂蚁金服的电话面试,直接被虐成渣渣

    话不多说,我把问到的主要问题先列出来吧!路还长,慢慢来吧! 1.servlet线程安全性问题,为什么不是线程安全的: 2.spring是如何解决bean的循环依赖问题的 3.spring bean的初 ...

  5. 腾讯CSIG、阿里(蚂蚁金服,支付宝,搜索引擎)、网易互娱、字节跳动面经

    说在前面的话 本人之前有面过腾讯天美工作室,奈何凉凉,有需要的朋友给传送门2021腾讯互娱天美工作室一面凉经 后来又被腾讯CSIG捞了,可惜挂在了二面上,期间有阿里三个部门的面试,也都凉凉(没办法,自 ...

  6. 一次蚂蚁金服的面试经历

    没记错的话,在boss上有个蚂蚁的人找我要了简历,我给了他之后,其实也没啥可期待的,毕竟我16年毕业,大学也是一般的二本,现在工作的公司也属于没人听过的.但想不到一周之后(1月23)号有蚂蚁的人给我打 ...

  7. 诗和远方:蚂蚁金服 Service Mesh 深度实践 | QCon 实录

    敖小剑,蚂蚁金服高级技术专家,十七年软件开发经验,微服务专家,Service Mesh 布道师,ServiceMesher 社区联合创始人.专注于基础架构和中间件,Cloud Native 拥护者,敏 ...

  8. 蚂蚁金服春招算法实习岗电话一面总结 2021.4.3

    总结 整个面试流程比较友好,通话21分钟.蚂蚁金服算法岗主要用到NLP.传统ML运筹优化等相关技术,自己是做CV的,几乎没怎么问自己正在做的东西,论文和比赛内容也没问.问的东西都算比较基础,自己表达得 ...

  9. 微软、百度、腾讯、阿里、蚂蚁金服:实习面经

    1.百度前端 一面: promise async/await promise封装ajax 三栏布局 一个元素和父元素高度一样 选择器 说css结果 一个数组,在第一次出现位置标次数,后边的标0 二面 ...

  10. 【面经】蚂蚁金服一二三面的面经总结(内推实习方面)

    我是2018年毕业的.我大概是从二月中旬的时候就陆续投一些公司的简历,想找一下比较好的暑假实习,一些大公司从二月份中下旬就开始发内推了,貌似我是在牛客网的讨论区刷到内推的机会的,然后就发了简历.等到了 ...

最新文章

  1. 二维树状数组 ---- codeforces341D
  2. 华为报告称2013年大数据将引发IT系统大变革
  3. Houdini Krakatoa Render Plugin
  4. Firefox 修改User Agent
  5. 学习笔记Spark(九)—— Spark MLlib应用(1)—— 机器学习简介、Spark MLlib简介
  6. 【Prometheus + Grafana】 使用 topk 在 grafana 绘制 前 n 个时间序列
  7. Jenkins中构建时提示:Couldn‘t find any revision to build. Verify the repository and branch config
  8. java和js实现电话号码部分隐藏
  9. Spring4.x(3)---工厂模式设计IOC容器
  10. pybamm库学习-tutorial
  11. 多种方法实现二叉树的先序、中序、后序、层序遍历
  12. HDU 1234- 开门人和关门人
  13. [转]二阶巴特沃斯(Butterworth)滤波器
  14. 两台电脑的文件共享方式
  15. 各大AI 开放平台一览
  16. 《全球通史》读书笔记2
  17. ESP32 开发笔记(四)LVGL控件学习 Canvas 画布控件
  18. 南开大学计算机本科论文,南开大学本科(论文)模板.doc
  19. SDNUOJ 1703.字谜|STL库中map的使用/map映射
  20. 传奇服务器都有哪些文件,传奇服务端每个文件夹的含义

热门文章

  1. ACL2021 | 任务型和开放域对话系统
  2. 串口调试助手fx2n_PLC串口调试助手详细讲解(结合实操)
  3. 完全没有建站经验的人,怎么自己做网站
  4. 一文入门智能开关的3种功能形态
  5. 有刷直流电机和无刷直流电机有什么区别?
  6. Android apps 拍立知-功能实现(百度tts语音合成使用)
  7. php openssl iv,PHP-openssl_encrypt,openssl_decrypt密钥,iv
  8. 我的2018OKR年终回顾与2019OKR初步规划
  9. OSChina 周三乱弹 —— 领悟人生,一百块钱都不给?
  10. VUE时间戳和时间相互转换,使用UI库为Ant Design of Vue