title: 2021年4月22日 阿里供应链Java开发实习面试(三面)
tags: 面经


2021年4月22日 阿里供应链Java开发实习面试(三面)

上来就手撕一道代码--输入一个数,然后顺时针打印出矩阵
然后开始聊人生和项目
计算机为什么是二进制呢?
计算机怎么去做加法运算,减法运算呢?(这个地方答的真的不好)
http,tcp,ip这三者之间的关系
Java的RPC了解吗?(答的不了解)
客户端和服务器之间是怎么交互的?(http的请求过程)
服务端之间交互,你觉得他们会怎么交互呢?(socket)
你的应用和数据库之间怎么连接呢?
Spring的IOC了解吗?
为什么需要IOC呢?(为了将手动创建对象的控制权交给Spring框架来管理,这样只要配置好xml文件,在需要的地方引用就行,这大大增加了项目的可维护性并且降低了开发难度。)
bean之间有依赖关系,如果注入的时候A依赖B,B依赖C,C依赖A,这种情况Spring会考虑这种循环关系吗?
假设我们自己来设计,我们怎么阻止这种死循环呢?(根据上一个问题提出来的)
为什么需要JVM这样的东西呢?
为什么JVM中要有s0和s1这两个东西呢?
那你知道full GC和young GC的区别吗?
除了synchronized,那你觉得还有什么关键字实现线程安全呢?(lock)
为什么有了synchronized,还要有lock这个关键字呢?
反问环节
(面试官说是二面的,但是的确是我的第三次面,所以阿里面试很迷,气场感觉不是很合)
(面了好几次阿里了,真的感觉自己跟阿里的气场不是很合,算辽算辽,平常心!!!)

1.1 计算机为什么是二进制呢?

① 从电路实现层面来讲,更容易实现。当计算机工作的时候,电路通电工作,于是每个输出端就有了电压。电压的高低通过模数转换即转换为二进制:高电平由1表示,低电平由0表示。也就是说将模拟电路换成为数字电路,这样电路只要能识别高低即可,实现起来更为简单;

② 二进制在物理上容易实现存储。可以通过磁极的取向、表面的凹凸、光照的有无来记录;

③ 便于进行加、减运算和计数编码。两个二进制数和、积运算组合各有三种,运算规则简单,有利于简化计算机内部结构,提高运算速度。

④ 便于逻辑判断(是或非)。适合逻辑运算:逻辑代数是逻辑运算的理论依据,二进制只有两个数码,正好与逻辑代数中的“真”和“假”相吻合。二进制的两个数码正好与逻辑命 题中的“真(Ture)”、“假(False)或称为”是(Yes)、“否(No)相对应。

⑤ 用二进制表示数据具有抗干扰能力强,可靠性高等优点。因为每位数据只有高低两个状态,当受到一定程度的干扰时,仍能可靠地分辨出它是高还是低。

1.2 计算机怎么去做加法运算,减法运算呢?

1.3 http,tcp,ip这三者之间的关系

TPC/IP协议是传输层协议,主要解决数据如何在网络中传输,而HTTP是应用层协议,主要解决如何包装数据。

“IP”代表网际协议,TCP和UDP使用该协议从一个网络传送数据包到另一个网络。把IP想像成一种高速公路,它允许其它协议在上面行驶并找到到其它电脑的出口。TCP和UDP是高速公路上的“卡车”,它们携带的货物就是像HTTP,文件传输协议FTP这样的协议等。

1.4 bean之间有依赖关系,如果注入的时候A依赖B,B依赖C,C依赖A,这种情况Spring会考虑这种循环关系吗?假设我们自己来设计,我们怎么阻止这种死循环呢?(根据上一个问题提出来的)

其实,这就是一个Spring循环依赖的问题。

Spring如何解决循环依赖的呢?

Spring通过三级缓存解决了循环依赖,其中一级缓存单例池(singletonObjects),二级缓存为早期曝光对象earlySingletonObjects,三级缓存为早期曝光对象工厂(singletonFactories)。

当A、B两个类发生循环引用时,在A完成实例化后,就使用实例化后的对象去创建一个对象工厂,添加到三级缓存中,如果A被AOP代理,那么通过这个工厂获取到的就是A代理后的对象,如果A没有被AOP代理,那么这个工厂获取到的就是A实例化的对象。

当A进行属性注入时,会去创建B,同时B又依赖了A,所以创建B的同时又会去调用getBean(a)来获取需要的依赖,此时的getBean(a)会从缓存中获取:

第一步:先获取到三级缓存中的工厂;

第二步:调用对象工工厂的getObject方法来获取到对应的对象,得到这个对象后将其注入到B中。紧接着B会走完它的生命周期流程,包括初始化、后置处理器等。

第三步:当B创建完后,会将B再注入到A中,此时A再完成它的整个生命周期。至此,循环依赖结束!

1.5 为什么需要 JVM 这样的东西呢?

因为JVM能够实现一次编译,到处运行的效果,可以跨平台运行。Java编译时,并不直接翻译为相依于某平台的0101指令,而是翻译为中介格式的位元码(byte code)。Java 的原始码文件格式名为***.java**,经过编译器翻译过后,会变成***.class**的格式文件位元码。如果想要执行这个位元码档案,目标平台上必须安装有JVM(Java Virtual Machine)。JVM会将位元码翻译为相应平台支持的语言。

而C/C++在不同的平台上必须使用不同的编译器来编译你的代码,在Windows平台上编译好的程序,也不能直接拿到Linux等其它平台上执行,而必须经过重新编译的动作,让编译器将你的程式编译为该平台可以执行的指令。

总结:

Java 虚拟机(JVM)是运⾏ Java 字节码的虚拟机。 JVM 有针对不同系统的特定实现
(Windows, Linux, macOS),⽬的是使⽤相同的字节码,它们都会给出相同的结果。字节码和不同系统的 JVM 实现是 Java 语⾔**“⼀次编译,随处可以运⾏”**的关键所在。

1.6 为什么JVM中要有s0和s1这两个东西呢?

参考博客:请你谈谈JVM设置Eden、S0、S1的理由?

Survivor的存在意义:就是减少被送到老年代的对象,进而减少Full GC的发生,Survivor的预筛选保证,只有经历16次Minor GC还能在新生代中存活的对象,才会被送到老年代。

设置两个Survivor区最大的好处就是解决了碎片化,为什么一个Survivor区不行?假设现在只有一个survivor区:刚刚新建的对象在Eden中,一旦Eden满了,触发一次Minor GCEden中的存活对象就会被移动到Survivor区。这样继续循环下去,下一次Eden满了的时候,问题来了,此时进行Minor GCEdenSurvivor各有一些存活对象,如果此时把Eden区的存活对象硬放到Survivor区,很明显这两部分对象所占有的内存是不连续的,也就导致了内存碎片化。碎片化带来的风险是极大的,堆中没有足够大的连续内存空间,无法为一个内存需求很大的对象分配内存。所以应该建立两块Survivor区,刚刚新建的对象在Eden中,经历一次Minor GC,Eden中的存活对象就会被移动到S0,Eden被清空;等Eden区再满了,就再触发一次Minor GC,Eden和S0中的存活对象又会被复制送入第二块S1(这个过程非常重要,因为这种复制算法保证了S1中来自S0和Eden两部分的存活对象占用连续的内存空间,避免了碎片化的发生)。

1.7 那你知道full GC和young GC的区别吗?

参考博客:young GC和Full GC的区别、什么时候触发young gc和Full GC、如何优化GC

young GC(新生代GC):指发生在新生代的垃圾收集动作,新生代中的对象朝生夕死,所以 Minor GC 非常频繁,回收速度也比较快。当新生代中的eden区分配满的时候触发。

Full GC(老年代GC):指发生在老年代的GC,速度一般比 Minor GC 慢十倍以上。Full GC 会 Stop-The-World。Full GC是对收集整堆(新生代、老年代)和方法区的垃圾收集。当老年代满时会引发Full GC,Full GC将会同时回收新生代、年老代 ;当永久代满时也会引发Full GC,会导致Class、Method元信息的卸载 。

拓展:

参考博客:JVM 垃圾回收之Minor GC、Major GC和Full GC之间的区别

  • Minor GC清理 新生代中的Eden区Survivor区满时不会触发 ;当年轻代(Eden区)满时就会触发 Minor GC,这里的年轻代满指的是 Eden区满。
  • Major GC 是 **清理 老年代 **;CMS收集器中,当老年代满时会触发 Major GC。目前,只有CMS收集器会有单独收集老年代的行为。其他收集器均无此行为。

1.8 为什么有了synchronized,还要有lock这个关键字呢?

为什么提供了synchronized,还要提供Lock呢?

我们使用synchronized加锁是无法主动释放锁的,这就会涉及到死锁的问题。

如果我们的程序使用synchronized关键字发生了死锁时,synchronized关键字是是无法破坏**“不可剥夺”这个死锁的条件的。这是因为synchronized**申请资源的时候, 如果申请不到, 线程直接进入阻塞状态了, 而线程进入阻塞状态, 啥都干不了, 也释放不了线程已经占有的资源。

然而,在大部分场景下,我们都是希望**“不可剥夺”这个条件能够被破坏。也就是说对于“不可剥夺”**这个条件,占用部分资源的线程进一步申请其他资源时, 如果申请不到, 可以主动释放它占有的资源, 这样不可剥夺这个条件就破坏掉了。

synchronized关键字的局限性:

有时候用synchronized修饰的代码,访问它需要很长时间,下一个要访问同一代码块的线程就要等待阻塞很长的时间。如果我想要下一个线程在等待一段时间后,如果还没有得到锁的话,就放弃等待,这就可以使用Lock锁,来设置等待时间。synchronized 是互斥锁,同一时间只能有一个线程可以访问被它修饰的代码块。而Lock锁可以实现互斥锁,也可以实现共享锁(同一时间支持多条线程访问)。

如果我们的程序使用synchronized关键字发生了死锁时,synchronized关键是是无法破坏**“不可剥夺”这个死锁的条件的。这是因为synchronized**申请资源的时候, 如果申请不到, 线程直接进入阻塞状态了, 而线程进入阻塞状态, 啥都干不了, 也释放不了线程已经占有的资源。

手撕算法题:

/***
评测题目一: 已知一只贪吃蛇长度为 n*n,每截以数字从小到大代表。将这只贪吃蛇摆成一个盘旋的正方形。例如:
给定 n = 2,输出:
1 2
4 3给定 n = 3,输出:
1 2 3
8 9 4
7 6 5给定 n =4,输出:1  2  3  4
12 13 14  5
11 16 15  6
10  9  8  7输入 n,输出贪吃蛇图形
***/
public class Print {public static void main(String[] args) {int n = 3;int[][] res = Print(3);for(int i = 0; i < n; i++){for(int j = 0; j < n; j++){System.out.print(res[i][j]);}System.out.println();}}public static int[][] Print(int n){int[][] arr = new int[n][n];int l = 0, r = n - 1;int t = 0, b = n - 1;int count = 0;while(true){for(int i = l; i <= r; i++){arr[t][i] = count + 1;count += 1;}t++;if(t > b) break;for(int i = t; i <= b; i++){arr[i][r] = count + 1;count += 1;}r--;if(r < l) break;for(int i = r; i >= l; i--){arr[b][i] = count + 1;count += 1;}b--;if(b < t) break;for(int i = b; i >= t; i--){arr[i][l] = count + 1;count += 1;}l++;if(l > r) break;}return arr;}
}

2021年4月22日 阿里供应链Java开发实习面试(三面)(含总结)相关推荐

  1. 2021年4月16日 阿里供应链Java研发实习面试(二面)

    title: 2021年4月16日 阿里供应链Java研发实习面试(二面) tags: 面经 2021年4月16日 阿里供应链Java研发实习面试(二面)(70min) 自我介绍 介绍自己的研究生项目 ...

  2. 2021年4月12日 阿里供应链Java研发实习面试(一面)(含总结)

    title: 2021年4月12日 阿里供应链Java研发实习面试(一面) tags: 面经 2021年4月12日 阿里供应链Java研发实习面试(一面) 自我介绍介绍项目你用哪个版本的Java呢?( ...

  3. 2021年3月16日 北京快手Java开发实习面试(海外增长方向)

    title: 2021年3月16日 北京快手Java开发实习面试(海外增长方向) tags: 面经 2021年3月16日 北京快手Java开发实习面试(海外增长方向) 自我介绍你能讲一下你的项目吗?你 ...

  4. 2021年4月28日 深圳头条后台开发实习面试(hr面)

    title: 2021年4月28日 深圳头条后台开发实习面试(hr面) tags: 面经 2021年4月28日 深圳头条后台开发实习面试(hr面) 自我介绍 为什么当时高考报考了机械行业呢? 你对机械 ...

  5. 2021年4月19日 深圳头条后台开发实习面试(二面)(含总结)

    title: 2021年4月19日 深圳头条后台开发实习面试(二面) tags: 面经 2021年4月19日 深圳头条后台开发实习面试(二面) 自我介绍 面试直接跟我讲你想让我问哪个方面的问题呢?(这 ...

  6. 2021年4月19日 深圳头条后台开发实习面试(一面)(含总结)

    title: 2021年4月19日 深圳头条后台开发实习面试(一面) tags: 面经 2021年4月19日 深圳头条后台开发实习面试(一面) 自我介绍 谈了一下数学建模的经历,以及跟我现在做的深度学 ...

  7. 2021年3月9日 北京快手Java开发–用户增长方向 实习面经(一面)

    title: 2021年3月9日 北京快手Java开发–用户增长方向 实习面经(一面) tags: 面经 2021年3月9日 北京快手Java开发–用户增长方向 实习面经(一面) 自我介绍你能介绍一下 ...

  8. 诛仙手游服务器维护中,诛仙手游2021年7月22日更新维护公告

    在诛仙手游中2021年7月22日更新情况内容又是什么样的呢?想了解本次更新情况如何的话,下面就让我们一起来看一下吧~! 诛仙手游2021年7月22日更新维护公告 为了给您提供更优质的游戏体验,< ...

  9. 2021年3月29日 阿里菜鸟实习面试(一面)(含部分总结)

    title: 2021年3月29号 阿里菜鸟实习面试(一面) tags: 面经 2021年3月29日 阿里菜鸟实习面试(一面) 自我介绍 你为什么想做Java开发工程师 你还做了除了飞机大战,还做了什 ...

最新文章

  1. Spring官网阅读(一)容器及实例化
  2. 使用C语言进行面向对象的开发--GObject入门[2]
  3. Simple DNS Plus 5.2 build 117
  4. Linux CentOS7/RHEL7关闭ctrl+alt+delete功能键
  5. linux sed 循环多行,linux sed 多行处理详细总结
  6. 【uoj#142】【UER #5】万圣节的南瓜灯 乱搞+并查集
  7. 系统封装接口层 cmsis_os
  8. Notepad++没有插件管理器(Plugin Manager)的解决方法
  9. 「06」回归的诱惑:一文读懂线性回归(Python实战篇)
  10. 三维重建笔记_重建方法简介与汇总
  11. Windows下程序猿开发利器
  12. 教你轻松解决CSRF跨站请求伪造攻击
  13. 计算机制图视频教程,机械制图视频教程
  14. 用单片机测量流体流速的_基于LMS算法的流体流速测量系统
  15. 通用模块脚本使用案例:玩家与NPC对话
  16. Java随意输入字符串,如果含有$将该字符及之前一个字符的去掉
  17. Excel日期显示为数字,不能正常显示为日期
  18. mac 不显示 外接屏幕_苹果电脑外接显示器显示不出来 - 卡饭网
  19. 插空排序C语言(直接插入排序)
  20. 宝塔Linux面板问题QA汇总

热门文章

  1. Android多点触摸交互处理,放大缩小图片
  2. 3d slicer调整窗宽窗位_3D人脸模型月销量上千单,谁在打印,谁在帮打?
  3. Python自动化测试框架之Pytest教程【让你小鸡变老鹰】
  4. matlab中阈值计算方法,三种阈值计算方法在MatLab6.5中的实现
  5. aidl生成java文件_Android Studio编写AIDL文件后如何实现自动编译生成
  6. linux 关机 司机,Linux 关机
  7. gram矩阵_ZEN-基于N-gram的中文Encoder
  8. java程序运行结果题_(Java程序设计)试题
  9. properties 配置回车_非常全面的讲解SpringCloud中Zuul网关原理及其配置,看它就够了!...
  10. 在一个3*4数组中查找最大最小值