查漏补缺第七期(美团到店一面)

本文涉及的产品
数据传输服务 DTS,数据迁移 small 3个月
推荐场景:
MySQL数据库上云
检索分析服务 Elasticsearch 版,2核4GB开发者规格 1个月
数据传输服务 DTS,数据同步 small 3个月
推荐场景:
数据库上云
简介: 前言目前正在出一个查漏补缺专题系列教程, 篇幅会较多, 喜欢的话,给个关注❤️ ~本专题主要以Java语言为主, 好了, 废话不多说直接开整吧~tcp和udp区别TCP(传输控制协议)和UDP(用户数据报协议)是两种常见的互联网传输协议,用于在计算机之间传输数据。它们在设计和功能上有一些显著的区别,下面是它们的详细比较:

前言

目前正在出一个查漏补缺专题系列教程, 篇幅会较多, 喜欢的话,给个关注❤️ ~

本专题主要以Java语言为主, 好了, 废话不多说直接开整吧~

tcp和udp区别

TCP(传输控制协议)UDP(用户数据报协议)是两种常见的互联网传输协议,用于在计算机之间传输数据。它们在设计和功能上有一些显著的区别,下面是它们的详细比较:

  1. 可靠性:
  • TCP是一种面向连接的协议,提供可靠的数据传输。它通过使用确认、重传和流量控制等机制,确保数据在发送和接收之间的可靠传递。如果发生数据丢失或损坏,TCP会自动重传丢失的数据,以确保数据的完整性和正确性。
  • UDP是一种无连接的协议,不提供可靠的数据传输保证。它仅将数据报发送到目标地址,不对数据传输进行确认或重传。因此,UDP在速度和效率上比TCP更快,但可能会导致数据丢失或乱序。
  1. 连接性:
  • TCP建立一个面向连接的通信链路,首先通过三次握手建立连接,然后传输数据,最后通过四次握手关闭连接。这种连接性可以确保数据按照顺序到达目标,并且可以进行流量控制和拥塞控制。
  • UDP是无连接的,每个数据包都是独立传输的,不需要建立和断开连接。这使得UDP更适合于实时应用程序,如音频和视频传输,其中小的数据延迟比数据完整性更重要。
  1. 传输方式:
  • TCP以字节流方式传输数据,将数据切割为TCP报文段,并在接收端重新组装。TCP使用序列号来跟踪和排序数据,确保按照发送顺序正确地重新组装数据。
  • UDP将数据分割为用户数据报(Datagram),每个用户数据报独立发送。每个数据报都有自己的标识,但它们之间没有顺序关系,接收方必须自行处理数据的顺序和完整性。
  1. 拥塞控制:
  • TCP具有拥塞控制机制,它可以根据网络的拥塞程度调整发送数据的速率。当网络拥塞时,TCP会减少发送速率以避免丢失数据或进一步加重网络拥塞。
  • UDP没有内置的拥塞控制机制,它仅仅是尽力而为地将数据发送出去,不会关心网络拥塞的情况。这意味着在拥塞的网络中,UDP可能会导致数据丢失或延迟增加。

总结:TCP适用于对数据完整性和顺序性要求较高的应用,如文件传输、网页浏览和电子邮件。UDP适用于实时应用,如音频和视频传输,以及对实时性要求较高、可以容忍少量数据丢失的应用,如语音通信和在线游戏。选择使用TCP还是UDP取决于应用程序的需求,对可靠性、延迟和拥塞控制的重要性有不同的考量。

https用的是对称加密还是非对称加密

HTTPS(Hypertext Transfer Protocol Secure)使用的是混合加密机制,包括对称加密和非对称加密。

在HTTPS通信中,对称加密用于加密和解密实际的数据传输,以保证数据的机密性和完整性。对称加密使用相同的密钥进行加密和解密操作,因此在通信双方之间需要共享密钥。对称加密算法的特点是加密和解密速度快,适合大数据量的加密和解密操作。

然而,对称加密并不能解决密钥交换的问题,因此需要非对称加密来解决这个问题。非对称加密使用公钥和私钥两个不同的密钥进行加密和解密操作。公钥可以被广泛分发给通信双方,而私钥只保留在服务器端。在HTTPS通信建立时,服务器会将自己的公钥发送给客户端,客户端使用该公钥加密一个用于对称加密的随机密钥,并发送给服务器。服务器使用自己的私钥解密该随机密钥,并与客户端共享对称密钥,用于后续的数据传输加密和解密。

通过结合对称加密和非对称加密,HTTPS实现了数据传输的机密性、完整性和身份验证。对称加密保证了数据传输的效率和速度,而非对称加密解决了密钥交换的安全性问题。这样可以确保在公开网络上进行安全的、加密的通信。

进程和线程的区别

进程线程是计算机中两个重要的执行单元,它们具有以下区别:

  1. 定义:
  • 进程(Process)是正在运行的程序的实例。它是操作系统资源分配的基本单位,包含了程序的代码、数据和执行环境等。
  • 线程(Thread)是进程中的一个独立执行路径。一个进程可以包含多个线程,每个线程都可以独立执行代码。
  1. 资源占用:
  • 进程是独立的资源分配单位,每个进程都有自己的内存空间、文件描述符、系统资源等。进程之间的通信和资源共享需要通过特定的机制,如进程间通信(IPC)。
  • 线程是在进程内部创建和调度的执行单元,共享进程的资源。多个线程共享同一进程的内存空间、文件描述符和系统资源,它们之间可以通过共享内存进行通信。
  1. 切换开销:
  • 由于进程拥有独立的地址空间和资源,进程间的切换开销相对较大。切换进程需要保存和恢复进程的上下文,涉及到内存切换和资源重分配等操作。
  • 线程切换开销较小,因为线程共享同一进程的资源和地址空间。线程之间的切换仅需要保存和恢复线程的上下文,开销较小。
  1. 并发性:
  • 进程之间是独立的,每个进程有自己的执行流。多个进程可以并发执行,各自独立进行。
  • 线程是进程内的执行单元,多个线程共享同一进程的资源。线程之间可以并发执行,共享进程的上下文,实现更细粒度的并发性。
  1. 系统支持:
  • 进程由操作系统进行管理和调度,操作系统分配资源、控制进程的执行,并提供进程间通信的机制。
  • 线程由操作系统的线程库进行管理,调度和执行。线程的创建、销毁和切换由线程库提供的函数实现。

总结:

进程是独立的资源分配单位,拥有独立的内存空间和资源,进程间切换开销较大;线程是进程内的执行单元,共享进程的资源,线程切换开销较小。进程适合用于并行执行、独立性较强的任务,线程适合用于并发执行、共享资源的任务。

进程切换和线程切换都会干什么

进程切换和线程切换是操作系统进行任务调度资源分配时的重要操作,它们的主要作用如下:

进程切换:

  1. 保存上下文:当操作系统决定将 CPU 的控制权从当前进程切换到另一个进程时,它首先会保存当前进程的上下文(包括程序计数器、寄存器、内存映像等)到进程控制块(PCB)中。
  2. 切换内存空间:进程切换还涉及将当前进程的内存空间与下一个进程的内存空间进行切换。操作系统会更新内存管理单元和页表,将新进程的地址空间映射到物理内存上。
  3. 加载新进程:操作系统从就绪队列中选择一个新的进程,并加载其上下文和内存映像到对应的硬件寄存器和内存区域中。
  4. 恢复上下文:最后,操作系统会将保存在新进程的 PCB 中的上下文信息恢复到硬件寄存器中,使得新进程可以从上次中断的地方继续执行。

线程切换:

  1. 保存上下文:当操作系统决定将 CPU 的控制权从当前线程切换到另一个线程时,它会保存当前线程的上下文(如程序计数器、寄存器等)到线程控制块(TCB)中。
  2. 切换堆栈:线程切换涉及将当前线程的堆栈切换到下一个线程的堆栈。操作系统会更新堆栈指针,使得下一个线程可以从正确的堆栈帧中恢复执行。
  3. 加载新线程:操作系统从就绪队列中选择一个新的线程,并加载其上下文和堆栈信息到对应的硬件寄存器和堆栈区域中。
  4. 恢复上下文:最后,操作系统会将保存在新线程的 TCB 中的上下文信息恢复到硬件寄存器中,使得新线程可以从上次中断的地方继续执行。

总结:

进程切换和线程切换都涉及保存和恢复上下文信息,切换内存空间或堆栈,以及加载新的任务信息。进程切换还需要处理地址空间的切换,而线程切换则主要涉及堆栈的切换。这些操作是为了实现多任务并发执行和资源分配的需要。

Java中都有哪里用到了红黑树

在Java中,红黑树(Red-Black Tree)是一种自平衡的二叉搜索树,它在许多核心的数据结构和算法中得到广泛应用。

  • TreeMap:Java标准库中的TreeMap类实现了基于红黑树的有序映射(key-value对)。它通过红黑树的特性来维护键的有序性,并提供了一系列的查找、插入和删除操作。
  • TreeSet:Java标准库中的TreeSet类实现了基于红黑树的有序集合。它使用红黑树来存储元素,并且保持集合元素的有序性。
  • ConcurrentSkipListMap:Java并发库中的ConcurrentSkipListMap类是一种基于跳表(Skip List)红黑树的并发有序映射。它提供了高效的并发操作,并且能够保持映射中的键有序。
  • ConcurrentSkipListSet:Java并发库中的ConcurrentSkipListSet类是一种基于跳表红黑树的并发有序集合。它提供了高效的并发操作,并且保持集合元素的有序性。
  • java.util.concurrent包中的一些并发集合和同步容器(如HashMapConcurrentHashMapConcurrentLinkedQueue等)在内部的实现中也使用了红黑树来保持数据的有序性和高效的并发访问。

红黑树在上述场景中被使用的原因是它能够提供高效的查找、插入和删除操作,同时保持数据的有序性。它的自平衡特性确保了树的高度较低,从而保证了这些操作的时间复杂度能够在对数时间范围内。这使得红黑树在需要频繁更新和查询有序数据的场景中得到了广泛的应用。

红黑树相比avl树优点在哪里

红黑树AVL树都是自平衡的二叉搜索树,它们在某些方面有相似的特性,但也存在一些区别。以下是红黑树相比AVL树的一些优点:

  1. 平衡性维护成本较低:红黑树通过引入颜色标记和相对较松的平衡条件来维护平衡性。相比之下,AVL树要求严格的平衡条件,需要在每次插入或删除操作后进行更频繁的旋转调整来维持平衡。因此,红黑树的平衡性维护成本相对较低,适合于频繁进行插入和删除操作的场景。
  2. 更高的插入和删除性能:由于红黑树对平衡性的要求较松,插入和删除操作相对AVL树更快。在红黑树中,旋转调整的次数相对较少,因此插入和删除操作的时间复杂度为O(logN),其中N是树的节点数量。而AVL树由于严格的平衡性要求,可能需要更多的旋转调整操作,导致插入和删除操作的时间复杂度更高。
  3. 更好的空间效率:红黑树通过引入额外的颜色标记来存储平衡信息,相比AVL树,红黑树的内存消耗较少。AVL树需要为每个节点额外存储平衡因子(balance factor),而红黑树只需要存储一个比特位的颜色标记。

总体而言,红黑树在插入和删除操作上相对AVL树更具有优势,而AVL树在某些场景下,如对搜索操作的频繁性能要求较高的情况下,可以选择AVL树来获得更好的搜索性能。选择使用红黑树还是AVL树取决于具体的应用需求和对平衡性、插入删除性能的重要性权衡。

volatile的用处,除了保证可见性还能够干什么

除了保证可见性外,volatile还有以下作用:

  1. 禁止指令重排序:在多线程环境中,编译器和处理器为了提高执行效率,可能会对指令进行重排序。然而,有些情况下重排序可能会导致程序的行为不符合预期。通过使用volatile关键字,可以禁止特定类型的指令重排序,保证指令按照程序的原始顺序执行。
  2. 保证有序性:在多线程环境中,volatile关键字可以保证被标记变量的读写操作具有全局的有序性。也就是说,volatile变量的读写操作不能被重排序到其他内存操作之前或之后,从而确保了操作的顺序性。
  3. 部分替代锁的功能:对于某些特定场景,volatile关键字可以替代显式的锁机制,实现一些简单的同步需求。由于volatile变量的读写操作具有原子性和可见性,可以在一些场景中使用它来保证线程安全性,避免使用锁带来的额外开销和复杂性。

需要注意的是,尽管volatile可以提供可见性和一定的有序性保证,但它并不能解决所有的线程安全问题。对于复合操作(例如自增或自减操作)以及需要原子性保证的操作,仍然需要使用更强大的同步机制,如锁或原子类。

JVM中哪里会发生OOM

Java虚拟机(JVM)中,Out-Of-Memory(OOM)错误可能发生在以下几个地方:

  1. 堆内存溢出(Heap Space):堆内存用于存储对象实例,包括新创建的对象和运行时动态分配的对象。当堆内存无法满足新对象的分配请求时,会抛出堆内存溢出异常(OutOfMemoryError)。这通常是最常见的OOM错误类型。
  2. 方法区/元空间溢出(Metaspace):方法区用于存储类的元数据、静态变量、常量池等信息。在较早的JVM版本中,方法区被实现为永久代(Permanent Generation),而在较新的JVM版本中,方法区被实现为元空间(Metaspace)。当类的元数据信息过多,或者加载的类数量过多时,方法区/元空间可能会溢出,导致OOM错误。
  3. 栈溢出(Stack Overflow):每个线程在JVM中都有一个对应的栈,用于存储方法调用和局部变量。当递归调用层级太深,或者线程请求的栈帧超过了栈的最大深度限制,就会导致栈溢出错误(StackOverflowError)。
  4. 本地方法栈溢出(Native Method Stack):本地方法栈用于存储调用本地(Native)方法的相关信息。类似于栈溢出,当本地方法的调用层级太深或者请求的栈帧超过了栈的最大深度限制时,就会发生本地方法栈溢出错误(StackOverflowError)。
  5. 直接内存溢出(Direct Memory):直接内存是一种不受JVM管理的内存,通常通过NIO进行操作。当程序频繁使用直接内存而没有正确释放或者申请过多的直接内存时,会导致直接内存溢出错误(OutOfMemoryError)。

这些是常见的导致OOM错误的地方,不同的错误类型在不同的情况下可能发生。出现OOM错误时,一般需要根据错误信息、堆栈轨迹以及相关的监控工具进行分析和排查,以找到导致问题的具体原因,并进行相应的优化或调整。

下面写一个造成OOM错误的方法:

public class OOMExample {
    public static void main(String[] args) {
        List<byte[]> list = new ArrayList<>();
        try {
            while (true) {
                byte[] arr = new byte[1024 * 1024]; // 分配1MB的字节数组
                list.add(arr);
            }
        } catch (OutOfMemoryError e) {
            System.out.println("OOM error occurred!");
            // OOM error occurred!
        }
    }
}

思考一下,这个错误发生在哪个区域呢?

上述代码中的 OutOfMemoryError(OOM)错误将发生在堆内存区域。通过创建大量的字节数组并将其添加到List<byte[]>列表中,逐渐消耗堆内存的可用空间。当堆内存无法分配更多的对象实例时,JVM 将抛出 OutOfMemoryError

Java 中,堆内存用于存储对象实例,包括在运行时动态分配的对象。它是 JVM 运行时数据区域中的一部分,用于存储运行时对象的实例和数组。因此,当我们不断分配大量的对象并占用了大部分可用堆内存时,就会发生堆内存溢出(OutOfMemoryError)错误。

如何让元空间发生OOM错误呢?

在Java 8及以上版本的JVM中,方法区(或称为永久代)已经被元空间(Metaspace)所取代。元空间是用于存储类的元数据、静态变量、常量池等信息的区域。因此,我们可以编写一个方法来模拟元空间OOM错误。

import javassist.ClassPool;
public class MetaspaceOOMExample {
    public static void main(String[] args) {
        try {
            ClassPool classPool = ClassPool.getDefault();
            int count = 0;
            while (true) {
                String className = "Class" + count++;
                classPool.makeClass(className).toClass();
            }
        } catch (OutOfMemoryError e) {
            System.out.println("Metaspace OOM error occurred!");
        }
    }
}

上述代码使用 Javassist 库来动态创建类并加载到元空间。在一个无限循环中,我们不断创建新的类,每个类都具有唯一的名称。随着不断创建类并加载到元空间元空间的可用空间将逐渐耗尽。当元空间无法分配更多的类的元数据时,JVM 将抛出 OutOfMemoryError,并打印"Metaspace OOM error occurred!"。

请注意,在运行此示例代码时,需要根据实际情况调整 JVM 的元空间大小限制(通过设置-XX:MaxMetaspaceSize参数),以及足够的物理内存资源。

如何让发生OOM错误呢?

Java中,栈(Stack)用于存储方法调用和局部变量等信息。栈的大小是有限的,当递归调用层级太深或者线程请求的栈帧超过了栈的最大深度限制时,就会发生栈溢出错误(StackOverflowError)。

以下是一个示例方法,可以用于模拟栈的OOM错误:

public class StackOOMExample {
    public static void recursiveMethod() {
        recursiveMethod();
    }
    public static void main(String[] args) {
        try {
            recursiveMethod();
        } catch (StackOverflowError e) {
            System.out.println("Stack Overflow error occurred!");
        }
    }
}

上述代码中的recursiveMethod方法是一个递归方法,它会不断地调用自身。在main方法中,我们调用recursiveMethod方法,由于递归没有终止条件,栈的深度会不断增加,直到达到栈的最大深度限制。当栈无法再容纳更多的栈帧时,JVM 将抛出StackOverflowError异常,并打印"Stack Overflow error occurred!"。

请注意,在运行此示例代码时,递归深度可能非常大,可能导致程序异常终止。

上述问题其实都是考察我们对JVM的理解

JVM什么时候会将对象从新生代移动到老年代

JVM(Java虚拟机)使用分代垃圾回收(Generational Garbage Collection)算法来管理内存。内存被分为不同的代,主要包括新生代(Young Generation)老年代(Old Generation)

在新生代中,内存被进一步划分为Eden空间和两个Survivor空间(通常称为From空间和To空间)。当创建对象时,它们首先被分配在Eden空间中。垃圾回收器定期扫描新生代,将仍然活跃的对象复制到其中一个Survivor空间中,同时清除未被引用的对象。经过多次垃圾回收后,仍然存活的对象会被移动到To空间。

当一个对象在Survivor空间中经历了一定数量的垃圾回收(通常是在Survivor空间中经历了15次垃圾回收),它将被晋升老年代。此外,大对象(占用大量内存的对象)也可能会直接被分配到老年代。

老年代是用于存储长期存活的对象和大对象的内存区域。当老年代空间不足时,将触发一次Full GC(Full Garbage Collection),对整个堆内存进行垃圾回收。在Full GC期间,所有的对象都会被扫描,未被引用的对象将被清除,而仍然存活的对象将被保留。

总结起来,对象何时从新生代移动到老年代取决于它在新生代中存活的时间(经过多次垃圾回收)以及是否属于大对象。这种策略的目的是尽量在新生代中回收短期存活的对象,以减少Full GC的频率和成本。

结束语

大家可以针对自己薄弱的地方进行复习, 然后多总结,形成自己的理解,不要去背~

本着把自己知道的都告诉大家,如果本文对您有所帮助,点赞+关注鼓励一下呗~

相关文章

项目源码(源码已更新 欢迎star⭐️)

往期设计模式相关文章

设计模式项目源码(源码已更新 欢迎star⭐️)

Kafka 专题学习

项目源码(源码已更新 欢迎star⭐️)

ElasticSearch 专题学习

项目源码(源码已更新 欢迎star⭐️)

往期并发编程内容推荐

推荐 SpringBoot & SpringCloud (源码已更新 欢迎star⭐️)

博客(阅读体验较佳)




















相关文章
|
6月前
|
NoSQL Java 关系型数据库
蚂蚁金服+拼多多+抖音+天猫(技术三面)面经合集助你拿大厂offer
很多Java开发者面试之前,可能没有较长的工作时间或者较为丰富的工作经验,所以不知道互联网公司或者一线互联网公司技术面试都会问哪些问题? 再加上可能自己准备也不充分,去面试没几个回合就被面试官几个问题打蒙了,最后以惨败收场。针对这些的读者朋友,小编整理了一些知名大厂的面经,在这分享给读者朋友们参考,让即将面试或是有想法跳槽的读者朋友们了解一下一线大厂面试时都喜欢问那些问题。
|
6月前
|
机器学习/深度学习 算法 定位技术
美团、滴滴、蔚来、货拉拉、Momenta、易智瑞、昆仑万维等暑期实习、日常实习技术岗面试汇总
美团、滴滴、蔚来、货拉拉、Momenta、易智瑞、昆仑万维等暑期实习、日常实习技术岗面试汇总
133 1
为什么头条和抖音上这么多人月入好几万?
为什么头条和抖音上这么多人月入好几万?
|
消息中间件 缓存 算法
社招一年半面经分享(含阿里美团头条京东滴滴)
重点放在专业技能和项目经验两块1.你的简历就是你给面试官提供的考点,简历上的东西必须自己Hold住,万一自己写的东西被问住了,会很尴尬,给面试官留下的印象也不好,所以就是会啥写啥2.技术栈最好不要写精通,你敢写面试官就敢问,被问倒了很尴尬的,写熟悉,了解就行怎么投简历我这里强烈建议找人内推,这样简历通过的概率大些,如果找不到,可以试试脉脉,我就是从脉脉投的简历,把状态改成寻找机会就行,会有很多人找你的推荐一个简历制作模版,我一直用的,https://www.polebrief.com/index算法这个该刷还是得刷,别偷懒,我个人感觉刷完下面几个已经够了,大家可以根据自己的基础情况选择剑指Of
|
消息中间件 设计模式 存储
查漏补缺第六期(京东一面)
前言 目前正在出一个查漏补缺专题系列教程, 篇幅会较多, 喜欢的话,给个关注❤️ ~ 本专题主要以Java语言为主, 好了, 废话不多说直接开整吧~ Kafka的应用场景有哪些,在项目里是如何应用的 Kafka 是一个高吞吐量、可扩展的分布式流处理平台,主要用于构建实时数据流应用程序和数据管道。以下是一些Kafka的应用场景:
|
信息无障碍
阿里公益孙利军和盲人按摩师聊了聊
前几天,阿里巴巴公益基金会理事长孙利军和北京盲人按摩师何亚君,一起在线上聊了聊天。他们都聊了些什么呢?以下是聊天实录,小益来分享给大家。
126 0
阿里公益孙利军和盲人按摩师聊了聊
|
存储 XML SQL
阿里巴巴2021春招二面(淘宝商家平台实习生)
支付的时候提交订单以后会调用远程支付接口,比如支付宝,如何保证在复杂的网络环境下不会重复支付? 商城平台都有物流追踪功能,如果现在某个订单平台上已经显示物流配送完毕,订单结束,但这时物流公司比较拉跨,过了一段时间又发过来了这个物流信息显示正在配送中,应该怎么办?
|
运维 监控 架构师
饿了么技术往事(上)
作为一个互联网创业公司,饿了么从初创到壮大,在移动互联网时代,业务量和技术团队的体量经历了10倍增长,这其中的经历,是互联网领域许多创业公司技术团队的一个缩影。在这里把我们成长过程中的体会和教训记录下来。——黄晓路
15184 7
饿了么技术往事(上)
|
缓存 监控 容灾
饿了么技术往事(下)
在商业竞争中,技术团队和其他团队一样,作为组织的一部分,应该是荣辱与共的。但是,就行业而言,饿了么创造的社会价值也是显而易见的,而且,饿了么塑造了这个行业最初的模样,对社会创造的价值影响是长远的!
9034 7
饿了么技术往事(下)
|
运维 安全 前端开发
饿了么技术往事(中)
在上一篇文章《饿了么技术往事(上)》中,我介绍了饿了么最早期 All in One 阶段的架构,以及第二阶段业务系统拆分与团队运营的一些思考,以及我对于架构师职责的感受,接下来我会详细介绍饿了么全面服务化的架构演进历程。
9225 9
饿了么技术往事(中)