首页 > 其他分享 >京东YOUNG-后端实习一面凉经

京东YOUNG-后端实习一面凉经

时间:2024-09-26 19:21:54浏览次数:9  
标签:Java String 对象 YOUNG 线程 内存 凉经 京东 monitor

文章目录

声明

面试问题来源:牛客
总结为个人总结,可能有的地方有错误或者不充分,欢迎大家评论指正!
我只是一个小菜鸡,很多知识还没有太深入理解,大家轻喷。
如果大家有好的面试问题也可以推荐一下,我会抽时间去写。
只是抽出来八股来进行总结,项目问题与实习问题不涉及,因此看起来问题会比较少,但是总结也蛮费时间

Java基础

1. Java语言有哪些特点?

  • 封装:把一个对象的状态信息(也就是属性)封装在对象的内部,不允许外部的对象直接访问对象的内部信息,但是可以提供一些被外界访问的方法来操作属性。
  • 继承:在已有类的基础上建立新类,新类的定义可以增加新的属性和方法,也可以用父类的方法,但是不能选择性的继承。
    • 子类拥有父类的所有属性和方法(包括私有方法和私有属性),但是父类的私有方法和私有属性子类无法访问
    • 子类可以拥有自己的属性和方法,即子类可以对父类进行扩展
    • 子类可以用自己的方式去重写父类的方法
  • 多态:表示一个对象具有的多种状态,具体表现为父类的引用指向子类的实例
    • 对象类型和引用类型之间具有继承/实现的关系
    • 引用类型发出的方法调用到底是哪个类的方法,必须在程序运行期间才能确定
    • 多态不能调用只在子类存在而在父类不存在的方法

2. Java虚拟机如何实现平台无关性?

Java通过其’编译一次,到处运行’的理念实现了平台无关性。这个理念主要依赖于Java虚拟机和字节码的设计。

  • Java的源代码首先通过编译器(javac)编译成字节码(.class)文件,字节码是一种中间表示形式,与具体的硬件平台无关,可以在任何支持JVM的环境中运行
  • 每种操作系统和硬件平台都有对应的JVM实现,所有JVM都遵循Java虚拟机规范,确保字节码在不同平台上的一致性。

JVM提供一个抽象层,屏蔽了底层硬件和操作系统的差异,使得字节码可以在不同平台上运行.

3. String和StringBuffer的区别

  • 可变性:String是不可变的,StringBuffer都是可变的
  • 线程安全:String中对象是不可变的,可以理解为线程安全,StringBuffer对象方法加了同步锁,也是线程安全的
  • 性能:String类型改变的时候都会生成一个新的String对象,然后将指针指向新的对象并改变对象引用,StringBuffer每次都会对对象本身进行操作,而不是生成新对象,StringBuffer更好

4. String str1 = “a”; String str2 = “b”; String str3 = str1 + str2; 这个过程一共创建了几个对象?

  • String str1 = “a”,JVM检查字符串常量池中是否存在字符串"a",如果常量池中不存在"a",则创建一个新的字符串对象并放入常量池中,如果存在则直接引用该对象
  • String str2 = “b”,JVM检查字符串常量池中是否存在字符串"b",如果常量池中不存在"b",则创建一个新的字符串对象并放入常量池中,如果存在则直接引用该对象
  • String str3 = str1 + str2;JVM会创建一个StringBuilder对象,用于拼接字符串创建1个新的字符串对象(“ab”)

为什么会创建StringBuilder呢?
由第三个问题其实也可以想到,String是不可变的,这意味着每次对字符串进行修改(例如拼接)时,都会创建一个新的字符串对象。为了提高字符串拼接的效率,Java编译器和JVM在处理字符串拼接操作时会使用StringBuilder类。

综上所述:

  • String str1 = “a”;:可能创建1个对象(如果常量池中不存在"a")。
  • String str2 = “b”;:可能创建1个对象(如果常量池中不存在"b")。
  • String str3 = str1 + str2;:
    • 创建1个StringBuilder对象。
    • 创建1个新的字符串对象(“ab”)。

JUC

1. 什么是线程和进程?进程和线程的区别是什么?

进程是正在运行的程序实例,线程从属于进程,是进程当中的一条执行流程

  • 进程是资源分配的单位,线程是CPU调度的单位
  • 线程更加轻量,能减少并发执行的时间和空间开销
  • 进程拥有的是完整的资源,线程只独享必不可少的资源,如寄存器和栈

2. 什么是死锁?

两个或多个进程或线程因相互等待对方释放资源而进入无限等待状态的现象。

死锁需要同时满足以下四个条件:

  • 互斥条件:资源某一时刻只能由一个进程占用
  • 占有且等待:一个进程已经持有至少一个资源,并且正在等待获取额外的资源,而这些资源被其他进程占有,等待过程不会释放自己的资源
  • 不可剥夺:资源不能被强制从进程中剥夺,必须由占有资源的进程主动释放
  • 循环等待:存在一个进程链,使得每个进程都在等待链中的下一个进程所持有的资源,从而形成一个循环等待

3. 如何预防和避免死锁?

产生死锁的四个条件是需要同时满足的,因此只要破坏其中一个则就能避免死锁问

题。最常见的并且可行的就是使用资源有序分配法,来破环环路等待条件。

  • 资源有序分配:线程 A 和 线程 B 获取资源的顺序要一样,当线程 A 是先尝试获取资源 A,然后尝试获取资源 B 的时候,线程 B 同样也是先尝试获取资源 A,然后尝试获取资源 B。也就是说,线程 A 和 线程 B 总是以相同的顺序申请自己想要的资源。(参考小林coding)
  • 设置优先级:高优先级可以抢占资源,破坏了不可剥夺的条件

个人感觉简单说两个就好,如果不够后续再补充

4. volatile关键字有什么作用?

  • 保证线程变量的可见性:对于有volatile关键字修饰的变量,对于值的修改会立即写入到主存中,每次使用它都到主存中进行读取。这样保证了不同线程对这个变量进行操作的可见性
  • 禁止指令重排序
    • 当程序执行到volatile变量的读操作或者写操作时,在其前面的操作的更改肯定全部已经进行,且结果已经对后面的操作可见;在其后面的操作肯定还没有进行
    • 在进行指令优化时,不能将在对volatile变量的读操作或者写操作的语句放在其后面执行,也不能把volatile变量后面的语句放到其前面执

参考 Java中violate关键字详解(2)?真正了解violate

5. volatile关键字的可见性底层是如何实现的?

从JMM和内存屏障两方面来说:

  • 对于加了volatile修饰的变量,JVM就会向处理器发送一条lock前缀的指令,将这个变量在缓存行的数据写回到主存。这时只是写回到主存,但其他处理器的缓存行中的数据还是旧的,要使其他处理器缓存行的数据也是新写回到主存的数据,就需要实现缓存一致性协议。即在一个处理器将自己缓存行的数据写回到系统内存后,其他的每个处理器就会通过嗅探在总线上传播的数据来检查自己缓存的数据是否已过期,当处理器发现自己缓存行对应的内存地址的数据被修改后,就会将自己缓存行缓存的数据设置为无效,当处理器要对这个数据进行修改操作的时候,会重新从系统内存中把数据读取到自己的缓存行,重新缓存。
  • 当进行写操作时,会在写操作之后插入一个写屏障,确保所有之前的操作在voletile变量的写操作之前完成,读操作时,会在读操作之前插入一个读屏障,确保所有对volatile变量的读操作在后续操作之前完成

参考https://blog.csdn.net/qq_42764468/article/details/106898608

6. synchronized底层原理了解吗?

回答的大体思路:简单介绍一下monitor、介绍同步代码块底层、介绍同步方法底层
synchronized底层和Monitor对象有关。Monitor对象被称为监视器锁,在Java中,每一个对象实例都会关联一个Monitor对象。这个Monitor对象既可以与对象一起创建销毁,也可以在线程试图获取对象锁时自动生成。当这个Monitor对象被线程持有后,它便处于锁定状态。
在HotSpot虚拟机中,Monitor是由ObjectMonitor实现的,有五个重要的部分

  • _ower 用来指向持有monitor的线程,它的初始值为NULL,表示当前没有任何线程持有monitor。当一个线程成功持有该锁之后会保存线程的ID标识,等到线程释放锁后_ower又会被重置为NULL;
  • _WaitSet 调用了锁对象的wait方法后的线程会被加入到这个队列中;
  • _cxq 是一个阻塞队列,线程被唤醒后根据决策判读是放入cxq还是EntryList;
  • _EntryList 没有抢到锁的线程会被放到这个队列;
  • count 用于记录线程获取锁的次数,成功获取到锁后count会加1,释放锁时count减1

如果线程获取到对象的monitor后,就会将monitor中的ower设置为该线程的ID,同时monitor中的count进行加1. 如果调用锁对象的wait()方法,线程会释放当前持有的monitor,并将owner变量重置为NULL,且count减1,同时该线程会进入到_WaitSet集合中等待被唤醒。在多条线程竞争monitor锁的时候,所有没有竞争到锁的线程会被封装成ObjectWaiter并加入_EntryList队列。当调用锁对象的notify方法后,会根据不同的情况来决定是将_WaitSet集合中的元素转移到_cxq队列还是_EntryList队列。等到获得锁的线程释放锁后,又会根据条件来执行_EntryList中的线程或者将_cxq转移到_EntryList中再执行_EntryList中的线程。

  • 在同步代码块中,通过分析字节码文件,可以看到monitorentermoniterexit两条指令。当执行到monitorenter指令时,线程就会去尝试获取该对象对应的Monitor的所有权,即尝试获得该对象的锁。当该对象的 monitor 的计数器count为0时,那线程可以成功取得 monitor,并将计数器值设置为 1,取锁成功。如果当前线程已经拥有该对象monitor的持有权,那它可以重入这个 monitor ,计数器的值也会加 1。而当执行monitorexit指令时,锁的计数器会减1。倘若其他线程已经拥有monitor 的所有权,那么当前线程获取锁失败将被阻塞并进入到_EntryList,直到等待的锁被释放为止。也就是说,当所有相应的monitorexit指令都被执行,计数器的值减为0,执行线程将释放 monitor(锁),其他线程才有机会持有 monitor 。
  • 同步方法:同步方法中没有了monitorenter和moniterexit两条指令,而是在方法的flag上加入了ACC_SYNCHRONIZED的标记位。这其实也容易理解,因为整个方法都是同步代码,因此就不需要标记同步代码的入口和出口了。当线程线程执行到这个方法时会判断是否有这个ACC_SYNCHRONIZED标志,如果有的话则会尝试获取monitor对象锁。

参考https://juejin.cn/post/6973571891915128846

JVM

1. OOM排查分析思路

  • 查看OOM错误日志:初步了解OOM异常的基本信息,重点关注OOM的错误类型,最常见的有
    • java.lang.OutOfMemoryError: Java heap space ------>java堆内存溢出
    • java.lang.OutOfMemoryError: PermGen space ------>java永久代溢出
    • java.lang.StackOverflowError ------> 不会抛OOM error,但也是比较常见的Java内存溢出
  • 捕获内存Dump:获取系统在OOM发生时的堆内存快照
    • 配置JVM参数:-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/path/to/dump
    • 使用工具(jmap)生成Heap Dump文件:jmap -dump:format=b,file=/path/to/dump <pid>
  • 工具分析堆内存Dump
    • 如果是内存溢出:可以考虑调整JVM参数,增加堆内存,例如-Xmx2g,调整GC策略,例如新生代和老年代的比例-XX:NewRatio=<ratio>
    • 如果是内存泄露:可以考虑优化代码实现

这里我相信很多找实习的同学没有接触过OOM排查,包括我自己在内,但是回答的时候不要说自己不会,可以给出自己的思考,可以按下面的逻辑:

  1. 介绍一下什么是OOM:全称"Out Of Memory",当JVM因为没有足够的内存来为对象分配空间并且垃圾回收器也已经没有空间可回收时,就会抛出这个error
  2. 然后可以介绍一下为什么会产生OOM
  • 分配的少了:比如虚拟机本身可使用的内存(一般通过启动时的JVM参数指定)太少。
  • 应用用的太多,并且用完没释放,浪费了。
    此时就引出了内存泄漏和内存溢出
  • 内存溢出:程序在申请内存时,没有足够的内存空间供其使用
  • 内存泄漏:程序在申请内存后,无法释放已申请的内存空间,一次内存泄露危害可以忽略,但内存泄露堆积后果很严重,无论多少内存,迟早会被占光
  1. 然后可以介绍一下可能会引起OOM的场景
  • JVM一次性加载的数据过多导致OOM
  • JVM本地缓存了过多数据且无法被回收
  • Java堆本身内存不足,对于给定大小的堆,应用程序已经无法创建任何额外的对象
  • 使用没有最大线程数量限制的线程池导致无限创建线程的OOM
  1. 最后可以简单提一下上面写的分析思路。

标签:Java,String,对象,YOUNG,线程,内存,凉经,京东,monitor
From: https://blog.csdn.net/qq_70134930/article/details/142516301

相关文章

  • 京东金融APP的鸿蒙之旅:技术、挑战与实践
    一、背景在今年6月份的华为开发者大会上,华为宣布HarmonyOSNEXT面向开发者和先锋用户启动Beta升级,并将于今年四季度正式商用。在9月21日的华为2024全联接大会上华为终端总裁宣布,已有超过1万个应用和元服务上架HarmonyOSNEXT应用市场。此外,华为每年投入超过60亿元人民币激励开......
  • 京东金融APP的鸿蒙之旅:技术、挑战与实践
    一、背景在今年6月份的华为开发者大会上,华为宣布HarmonyOSNEXT面向开发者和先锋用户启动Beta升级,并将于今年四季度正式商用。在9月21日的华为2024全联接大会上华为终端总裁宣布,已有超过1万个应用和元服务上架HarmonyOSNEXT应用市场。此外,华为每年投入超过60亿元人民币激励开发者......
  • 183天打造行业新标杆!BOE(京东方)国内首条第8.6代AMOLED生产线提前全面封顶
    2024年9月25日,BOE(京东方)投建的国内首条第8.6代AMOLED生产线全面封顶仪式在成都市高新区举行,该生产线从开工到封顶仅用183天,以科学、高效、高质的速度再树行业新标杆。这不仅是BOE(京东方)创新突破、打造新质生产力的又一重大举措,也是OLED领域的里程碑事件,极大推动OLED显示产业快速迈......
  • 183天打造行业新标杆!BOE(京东方)国内首条第8.6代AMOLED生产线提前全面封顶
    2024年9月25日,BOE(京东方)投建的国内首条第8.6代AMOLED生产线全面封顶仪式在成都市高新区举行,该生产线从开工到封顶仅用183天,以科学、高效、高质的速度再树行业新标杆。这不仅是BOE(京东方)创新突破、打造新质生产力的又一重大举措,也是OLED领域的里程碑事件,极大推动OLED显示产业快速迈......
  • Android Wear 开发 (一),阿里、腾讯、华为、京东等多家大厂最新安卓面试题
    importandroid.support.v4.app.NotificationCompat.WearableExtender;普通通知栏手机:普通的通知栏在手机上的效果应该都不陌生,这里就不展开说明手表:手表端的效果是由2张卡片构成的,第一张是手机通知栏的信息组成,第二张是点击开发手机应用,具体的效果与手机通知栏的点击事......
  • 全员20薪的京东,在大厂是什么水平
    超千亿真金白银的投入,“先人后企”公司战略,京东建立起了与员工“共同富裕”的公司样本。转载:@新熵 原创作者丨白露 编辑丨蕨影京东又加薪了!一时间,“京东20薪”话题引爆互联网圈和职场圈,京东人开始成为广大打工人艳羡的对象。9月13日,京东集团宣布再次启动加薪,自......
  • 电商数据驱动决策:京东商品详情API返回值的力量
    在电商领域,数据驱动决策的重要性日益凸显,而京东商品详情API提供了一个强大的工具,使得商家和开发者能够获取到丰富的商品信息,从而做出更加精准的市场判断和运营决策。京东商品详情API的力量京东商品详情API能够返回包括商品基本信息、价格变动、库存状态、用户评价、销售排行等在内......
  • 京东云轻量云主机快速搭建WordPress个人网站教程!
    WordPress是使用最广泛的博客和内容管理系统,支持丰富的插件和模板,功能强大,易于扩充功能。您可以使用它快速搭建独立的博客、论坛等网站,也可以做CMS使用。创建轻量云主机访问轻量云主机创建实例页选择WordPress镜像,以及套餐版本、时长等内容,进行下单创建轻量云主机实例查看应用详情......
  • 京东短网址高可用提升最佳实践
    什么是短网址?短网址,是在长度上比较短的网址。简单来说就是帮您把冗长的URL地址缩短成8个字符以内的短网址。当我们在腾讯、新浪发微博时,有时发很长的网址连接,但由于微博只限制140个字,所以微博就自动把您发的长网址给转换成短网址了。在微博和手机短信提醒等限制字数的地方来使用......
  • 京东云JoyCoder荣获AI4SE“银弹”优秀案例
    近日,中国人工智能产业发展联盟智能化软件工程工作组(AIforSoftwareEngineering,下文简称AI4SE)发布2024AI4SE“银弹”案例征集结果。京东云智能编程助手JoyCoder荣获2024AI4SE“银弹”案例优秀案例。 这项由中国人工智能产业发展联盟(AIIA)针对AI+软件工程(AI4SE)发起的专项征集,......