最新2024春招Java后端高频知识点汇总,美团优选面试题java

最后

由于篇幅原因,就不多做展示了

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

虚拟机给每个对象定义了一个对象年龄计数器。如果对象在Eden出生并经过第一次Minor GC后仍然存活,并且能被Survivor容纳的华,将被移动到Survivor空间中,并且对象的年龄设置为 1.对象在Survivor区中每熬过一次Minor GC,年龄就增加1岁,当它的年龄增加到一定程度(默认为15岁)就将会被晋升到老年代中。年龄阈值可通过配置调整-XX:MaxTenuringThreshold参数。

④动态年龄判定

虚拟机并不是永远要求对象的年龄必须达到 MaxTenuringThreshold参数才能晋升到老年代。

如果在Survivor空间中相同年龄所有对象大小总和大于Survivor空间的一半,年龄大于或等于该年龄的对象就可以直接进入老年代,无需等到配置参数中要求的年龄。

⑤空间分配担保

在发生Minor GC之前,虚拟机会先检查老年代最大可用的连续空间是否大于新生代所有对象总空间,如果这个条件成立,那么Minor GC可以确保是安全的。

如果不成立,则虚拟机会查看HandlePromotionFailure设置值是否允许担保失败。如果允许,那么会继续检查老年代最大可用的连续空间是否大于历次晋升到老年代对象的平均大小,如果大于,将尝试着进行一次Minor GC,尽管这次Minor GC是有风险的。如果小于或者设置不允许冒险,这时要改为进行一次Full GC。

6. 如何判断对象是否死亡


堆中⼏乎放着所有的对象实例,对堆垃圾回收前的第⼀步就是要判断哪些对象已经死亡(即不能再被任何途径使⽤的对象)。

①引用计数法

给对象中添加⼀个引⽤计数器,每当有⼀个地⽅引⽤它,计数器就加1;当引⽤失效,计数器就减1;任何时候计数器为0的对象就是不可能再被使⽤的。

(但是,引用计数法很难解决对象之间相互循环引用的问题)

②可达性分析算法

通过一些列的称为GC Roots 的对象作为起始点,从这些节点开始向下搜索,搜索所走过的路径称为引用链,当一个对象到GC Roots之间没有任何引用链相连,则证明这个对象是不可用的。

7. 判断不可达一定会被回收吗


即使在可达性分析算法判断不可达的对象,也并非是“非死不可的”。

如果对象在进行可达性分析后发现没有与GC Roots相连的引用链,那它将会被第一次标记并且进行一次筛选,筛选的条件是此对象是否有必要执行finalize()方法。当对象没有覆盖finalize()方法或者finalize()方法已经被调用过,finalize()方法都不会执行,该对象将会被回收。

如果这个对象被判定为有必要执行finalize()方法,那么这个对象将会被放置在一个叫做F-Queue的队列中,然后由Finalizer线程去执行。GC将会对F-Queue中的对象进行第二次标记,如果对象在finalize()方法中重新与引用链上的任何一个对象建立关联,那么在第二次标记时将会被移除“即将回收”的集合,否则该对象将会被回收。

(比如:把自己(this关键字)赋值给某个类变量(static修饰)或者对象的成员变量)

8. GC Roots 有哪些


1.在虚拟机栈(栈帧中的本地变量表)中引用的对象,譬如各个线程被调用的方法堆栈中使用到的参数、局部变量、临时变量等。

2.在方法区中类静态属性引用的对象,譬如Java类的引用类型静态变量。

3.在方法区中常量引用的对象,譬如字符串常量池里的引用。

4.在本地方法栈中JNI(即通常所说的Native方法)引用的对象。

5.Java虚拟机内部的引用,如基本数据类型对应的Class对象,一些常驻的异常对象(比如NullPointExcepiton、OutOfMemoryError)等,还有系统类加载器。

6.所有被同步锁(synchronized关键字)持有的对象。

7.反映Java虚拟机内部情况的JMXBean、JVMTI中注册的回调、本地代码缓存等。

9. 强引用、软引用、弱引用、虚引用


⽆论是通过引⽤计数法判断对象引⽤数量,还是通过可达性分析法判断对象的引⽤链是否可达,判定对象的存活都与“引⽤”有关。

JDK1.2之前,Java中引⽤的定义很传统:如果reference类型的数据存储的数值代表的是另⼀块内存的起始地址,就称这块内存代表⼀个引⽤。

JDK1.2以后,Java对引⽤的概念进⾏了扩充,将引⽤分为强引⽤、软引⽤、弱引⽤、虚引⽤四种(引⽤强度逐渐减弱)

强引⽤(StrongReference)

强引用就是指类似于“Object obj = new Object()”这类的引用。被强引用关联的对象,垃圾回收器绝不会回收它。当内存空间不⾜时,Java虚拟机宁愿抛出OutOfMemoryError错误,使程序异常终⽌,也不会靠随意回收具有强引⽤的对象来解决内存不⾜问题。

软引⽤(SoftReference)

被软引用关联的对象只有在内存空间不足时才会被回收。软引⽤可⽤来实现内存敏感的⾼速缓存。软引⽤可以和⼀个引⽤队列(ReferenceQueue)联合使⽤,如果软引⽤所引⽤的对象被垃圾回收,JAVA虚拟机就会把这个软引⽤加⼊到与之关联的引⽤队列中。在JDK1.2后,提供了SoftReference

弱引⽤(WeakReference)

弱引⽤与软引⽤的区别在于:只具有弱引⽤的对象拥有更短暂的⽣命周期。在垃圾回收器线程扫描它所管辖的内存区域的过程中,⼀旦发现了只具有弱引⽤的对象,不管当前内存空间⾜够与否,都会回收它的内存。不过,由于垃圾回收器是⼀个优先级很低的线程, 因此不⼀定会很快发现那些只具有弱引⽤的对象。弱引⽤可以和⼀个引⽤队(ReferenceQueue)联合使⽤,如果弱引⽤所引⽤的对象被垃圾回收,Java虚拟机就会把这个弱引⽤加⼊到与之关联的引⽤队列中。

虚引⽤( PhantomReference)

"虚引⽤"顾名思义,就是形同虚设,与其他⼏种引⽤都不同,虚引⽤并不会决定对象的⽣命周期。 如果⼀个对象仅持有虚引⽤,那么它就和没有任何引⽤⼀样,在任何时候都可能被回收 。 为一个对象设置虚引用的唯一目的就是这个对象被垃圾回收器回收时收到一个系统通知 。在JDK1.2之后,提供了PhantomReference类来实现虚引用。

虚引⽤与软引⽤和弱引⽤的⼀个区别在于: 虚引⽤必须和引⽤队列(ReferenceQueue)联合使⽤ 。当垃圾回收器准备回收⼀个对象时,如果发现它还有虚引⽤,就会 在回收对象的内存之前 ,把这个虚引⽤加⼊到与之关联的引⽤队列中。程序可以通过判断引⽤队列中是 否已经加⼊了虚引⽤,来了解被引⽤的对象是否将要被垃圾回收。程序如果发现某个虚引⽤已经被加⼊到引⽤队列,那么就可以在所引⽤的对象的内存被回收之前采取必要的⾏动。

(软引用是在 垃圾回收之后 把引用加入到引用队列中,虚引用是在 垃圾回收之前 把引用加入到引用队列中)

特别注意,在程序设计中⼀般很少使⽤弱引⽤与虚引⽤,使⽤软引⽤的情况较多,这是因为软引⽤可以加速JVM对垃圾内存的回收速度,可以维护系统的运⾏安全,防⽌内存溢出(OutOfMemory)等问题的产⽣。

10. 垃圾收集算法


①标记-清除算法

算法分为“标记”和“清除”阶段:⾸先标记出所有需要回收的对象,在标记完成后统⼀回收所有被标记的对象。它是最基础的收集算法,后续的算法都是对其不⾜进⾏改进得到。这种垃圾收集算***带来两个明显的问题:

1. 效率问题,如果Java堆中包含大量对象,而且其中大部分是需要被回收的,这时必须进行大量标记和清除的动作,导致标记和清除两个过程的执行效率都随对象数量的增长而降低。

2. 空间问题(标记清除后会产⽣⼤量不连续的碎⽚,空间碎片太多可能会导致以后在程序运行过程中需要分配较大对象时,无法找到足够的连续内存而不得不提前触发另一次垃圾回收动作)

②标记-复制算法

标记-复制算法简称“复制算法”

为了解决效率问题,“复制”收集算法出现了。

它可以将内存分为⼤⼩相同的两块,每次使⽤其中的⼀块。当这⼀块的内存使⽤完后,就将还存活的对象复制到另⼀块去,然后再把使⽤的空间⼀次清理掉。这样就使每次的内存回收都是对内存区间的⼀半进⾏回收。

优点:1.解决了标记-清除算法面对大量可回收对象时执行效率低的问题。2.避免了内存碎片。

缺点:将可用空间缩小为原来的一半,空间利用率较低。

新生代中大部分对象“朝生夕灭”,熬不过第一轮收集。因此并不需要按照1:1的比例来划分新生代内存空间。

将新生代划分为一个Eden区和两个Survivor区,大小为8:1:1

每次分配内存时只使用Eden区和其中一个Survivor区。发生垃圾回收时,将Eden和Survior中仍然中存活的对象一次性复制到另外一块Survivor空间中,然后直接清理掉Eden和已经使用过的Survivor区。

③标记-整理算法

根据⽼年代的特点推出的⼀种标记算法,标记过程仍然与“标记-清除”算法⼀样,但后续步骤不是直接对可回收对象回收,⽽是让所有存活的对象向⼀端移动,然后直接清理掉端边界以外的内存。

(复制收集算法在对象存活率较高时就要进行较多的复制操作,效率将会变低。更关键的是,如果不想浪费50%的空间,就需要有额外的空间进行分配担保,以应对被使用的内存中所有对象都100%存活的极端情况,所以在老年代一般不能直接选用这种算法)

优点:不会产生内存碎片。

缺点:移动存活对象并更新引用这些对象的地方将会是一种极为负重的操作,而且这种对象移动操作必须全程暂停用户应用程序才能进行。(即Stop the world)

④分代收集算法

当前虚拟机的垃圾收集都采⽤分代收集算法,根据对象存活周期的不同将内存分为⼏块,⼀般将java堆分为新⽣代和⽼年代,这样我们就可以根据各个年代的特点选择合适的垃圾收集算法。

在 新⽣代 中,每次收集都会有⼤量对象死去,所以可以选择标记-复制算法,只需要付出少量存活对象的复制成本就可以完成每次垃圾收集。

⽼年代的对象存活⼏率是⽐较⾼的,⽽且没有额外的空间对它进⾏分配担保,所以我们必须选择  标记 - 清除  或  标记 - 整理  算法进⾏垃圾收集。

11.垃圾收集器


垃圾收集器主要有:Serial、Serial Old、ParNew、Parallel Scavenge、Parallel Old、CMS、G1

①Serial收集器

Serial收集器一个新生代、单线程的收集器,采用标记-复制算法。它在进行垃圾回收时,必须暂停所有用户线程,直到它收集结束。(stop the world)

②ParNew收集器

ParNew收集器一个新生代、多线程的收集器,采用标记-复制算法。只有Serial和ParNew收集器能与CMS配合工作。ParNew收集器是激活CMS后的默认新生代收集器。

③Parallel Scavenge收集器

Parallel Scavenge收集器是一款新生代收集器,基于标记-复制算法实现的。能够进行并行收集的多线程收集器。

④Serial Old收集器

Serial Old收集器:一个老年代、单线程的收集器,采用标记-整理算法。它在进行垃圾回收时,必须暂停所有用户线程,直到它收集结束。(stop the world)

⑤Parallel Old收集器

Parallel Old收集器是Parallel Scavenge收集器的老年代版本,支持多线程并发收集(多个GC线程),基于标记-整理算法实现。

⑥CMS收集器

CMS收集器是老年代收集器,基于标记-清除算法实现的。

⑦G1收集器

G1收集器:新生代+老年代(将Java堆划分成多个Region),面向全堆的收集器,不需要其他新生代收集器的配合工作。

搭配:

①新生代Serial+老年代Serial Old

②新生代ParNew+老年代Serial Old

③新生代Parallel Scavenge+老年代Parallel Old

④新生代ParNew+老年代CMS(Parallel Scavenge无法与CMS配合)

12. CMS收集器


CMS( Concurrent Mark Sweep )收集器是⼀种以获取 最短回收停顿时间 为⽬标的收集器。它⽽⾮常符合在注重⽤户体验的应⽤上使⽤。

CMS( Concurrent Mark Sweep )收集器是 HotSpot 虚拟机第⼀款真正意义上的并发收集器,它第⼀次实现了让垃圾收集线程与⽤户线程(基本上)同时⼯作。

从名字中的 Mark Sweep 这两个词可以看出,CMS收集器是⼀种  标记 - 清除  算法实现的,它的运作过程相⽐于前⾯⼏种垃圾收集器来说更加复杂⼀些。整个过程分为四个步骤:(初始标记和重新标记这两步仍然要stop the world)

stop the world:除垃圾收集器线程之外的线程都被挂起。

① 初始标记 : 暂停用户线程,并标记下GC Roots能直接关联到的对象,速度很快 ;

② 并发标记 : 同时开启GC和⽤户线程,⽤⼀个闭包结构去记录可达对象。但在这个阶段结束,这个闭包结构并不能保证包含当前所有的可达对象。因为⽤户线程可能会不断的更新引⽤域,所以GC线程⽆法保证可达性分析的实时性。所以这个算法⾥会跟踪记录这些发⽣引⽤更新的地⽅。

从GC Root开始对堆中的对象进行可达性分析,找出存活的对象。

(书本:并发标记阶段就是进行GC Roots Tracing的过程)

③ 重新标记 : 暂停用户线程,重新标记阶段就是为了修正并发标记期间因为⽤户程序继续运⾏⽽导致标记产⽣变动的那⼀部分对象的标记记录,这个阶段的停顿时间⼀般会⽐初始标记阶段的时间稍⻓,远远⽐并发标记阶段时间短。

④ 并发清除 : 同时开启⽤户线程和GC线程,清理掉在标记阶段判断的已经死亡的对象。

CMS收集器的优缺点:

从它的名字就可以看出它是⼀款优秀的垃圾收集器, 主要优点:并发收集、低停顿 。但是它有下⾯ 三个明显的缺点 :

①  CPU 资源敏感

在并发阶段,虽然不会导致用户线程停顿,但是会因为占用了一部分线程(或者说CPU资源)而导致应用程序变慢,总吞吐量会降低。

②⽆法处理浮动垃圾

CMS在并发清理阶段用户线程还在运行, 还会产生新的垃圾,这一部分垃圾产生在标记过程之后,CMS无法再当次过程中处理,所以只有等到下次gc时候在清理掉,这一部分垃圾就称作“浮动垃圾” 。

③它使⽤的回收算法--  标记 - 清除  算法 会导致收集结束时会 有⼤量空间碎⽚产⽣ 。

空间碎片太多的时候,将会给大对象的分配带来很大的麻烦,往往会出现老年代还有很大的空间剩余,但是无法找到足够大的连续空间来分配当前对象的,只能提前触发 full gc。

为了解决这个问题,CMS提供了一个开关参数,用于在CMS顶不住要进行full gc的时候开启内存碎片的合并整理过程,内存整理的过程是无法并发的,空间碎片没有了,但是停顿的时间变长了。

13. G1收集器


G1 (Garbage-First)是⼀款⾯向服务器的垃圾收集器 , 主要针对配备多颗处理器及⼤容量内存的机器。以极⾼概率满⾜ GC 停顿时间要求的同时 , 还具备⾼吞吐量性能特征。

被视为JDK1.7中HotSpot虚拟机的⼀个重要进化特征。

G1收集器采用“标记-复制”和“标记-整理”。从整体上看是基于“标记-整理”,从局部看,两个region之间是“标记-复制”。

它具备⼀下 特点 :

① 并⾏与并发 :G1能充分利⽤CPU、多核环境下的硬件优势,使⽤多个CPU(CPU或者CPU核⼼)来缩短Stop-The-World停顿时间。部分其他收集器原本需要停顿Java线程执⾏的GC动作,G1收集器仍然可以通过并发的⽅式让java程序继续执⾏。

② 分代收集 :虽然G1可以不需要其他收集器配合就能独⽴管理整个GC堆,但是还是保留了分代的概念。

③ 空间整合 :与CMS的“标记–清理”算法不同,G1从整体来看是基于“标记整理”算法实现的收集器;从局部上来看是基于“复制”算法实现的。

④ 可预测的停顿 :这是G1相对于CMS的另⼀个⼤优势,降低停顿时间是G1 和 CMS 共同的关注点,但G1 除了追求低停顿外,还能 建⽴可预测的停顿时间模型,能让使⽤者明确指定在⼀个⻓度为M毫秒的时间⽚段内,消耗在垃圾收集上的时间不得超过N毫秒。

G1收集器的运作⼤致分为以下⼏个步骤:

①初始标记

暂停用户线程,初始标记只是标记下GC Roots能直接关联到的对象,并且修改TAMS(Next Top at Mark Start)的值,让下一阶段用户程序并发运行时,能在正确可用的Region中创建新对象,这阶段需要停顿线程,但耗时很短。

②并发标记

同时开启用户线程和GC线程,并发标记阶段是从GC Root开始对堆中对象进行可达性分析,找出存活对象,这阶段耗时较长,但可与用户程序并发执行。

③最终标记

暂停用户线程,最终标记阶段则是为了修正在并发标记期间因用户程序继续运作而导致标记产生变动的那一部分标记记录,这阶段需要停顿线程,但是可以并行执行。

④筛选回收

暂停用户线程,筛选阶段首先对各个Region的回收价值和成本进行排序,根据用户所期望的GC停顿时间来制定回收计划。

[Regin:G1收集器将整个Java堆划分为多个大小相等的独立区域(Regin)]

G1收集器在后台维护了⼀个优先列表,每次根据允许的收集时间,优先选择回收价值最⼤的 Region( 这也就是它的名字 Garbage-First 的由来 ) 。这种使⽤Region划分内存空间以及有优先级的区域回收⽅式,保证了GF收集器在有限时间内可以尽可能⾼的收集效率(把内存化整为零)。

dd

筛选回收:

对各个Region的回收价值和成本进行排序,根据用户所期望的停顿时间来制定回收计划,可以自由选择任意多个Region构成回收集,然后把决定回收的那一部分Region的存活对象复制到空的Region中,再清理掉个旧的Region的全部空间。这里的操作涉及存活对象的移动, 是必须暂停用户线程 ,由多条收集器线程并行完成的。

G1收集器只有并发标记不会stop the world

14. 为什么CMS采用“标记-清除”算法而不采用“标记-整理”算法


因为CMS作为第一款实现 用户线程和收集线程 并发执行的收集器!当时的设计理念是减少停顿时间,最好是能并发执行!但是问题来了,如要用户线程也在执行,那么就不能轻易的改变堆中对象的内存地址!不然会导致用户线程无法定位引用对象,从而无法正常运行!而标记整理算法和标记复制算法都会移动存活的对象,这就与上面的策略不符!因此CMS采用的是标记清理算法!

15. JDK1.8默认的垃圾回收器


默认:UseParallelGC

UseParallelGC 即 Parallel Scavenge + Parallel Old

UseParallelGC:并行收集器,同时运行在多个cpu之间,物理上的并行收集器,跟上面的收集器一样也是独占式的,但是它最大化的提高程序吞吐量,同时缩短程序停顿时间,另外它不能与CMS收集器配合工作。

16. 为什么新生代和老年代要采用不同的回收算法


在新生代中,每次垃圾收集时都发现有大批对象死去,只有少量存活,那就许选择“标记-复制”算法,只需要付出少量存活对象的复制成本就可以完成收集。而老年代中因为对象存活率高、没有额外空间对它进行分配担保,就必须使用“标记–清除”、“标记整理”算法来进行回收。

标记复制算法在对象存活率较高时就要进行较多的复制操作,效率将会变低。

17. 垃圾回收怎么解决跨代引用的问题


记忆集(Remembered Set):一种用于记录从 非收集区域 指向 收集区域 的 指针集合 的抽象数据结构,在对象层面来说就是非收集区域对象对收集区域对象的引用的记录。

记忆集存放在收集区域,比如在新生代里面存放着老年代对新生代对象的每一个引用。这样在收集新生代的时候,我们就可以根据记忆集知道哪些对象被老年代对象所引用,不能回收,这就解决了跨代引用的问题。

18. 类加载过程


类加载过程: 加载、验证、准备、解析、初始化 。

其中验证、准备、解析3个部分统称为 连接 。

1.加载

①通过一个类的全限定名来获取定义此类的二进制字节流。

②将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构。

③在内存中生成一个代表这个类的java.lang.Class对象,作为方法区这个类的各种数据的访问入口。

2.验证

确保Class文件的字节流中包含的信息符合《Java虚拟机规范》的全部约束要求,保证这些信息被当作代码运行后不会危害虚拟机自身的安全。

验证阶段大致上会完成下面四个阶段的检验动作:文件格式验证、元数据验证、字节码验证和符号引用验证。

3.准备

准备阶段是正式为类中定义的变量(即静态变量,被static修饰的变量)分配内存并设置类变量初始值的阶段。

在准备阶段,进行分配的仅包括类变量,而不包括实例变量,实例变量将会在对象实例化时随着对象一起分配在Java堆中。

假设一个类变量的定义为:public static int value = 123;

变量value在准备阶段过后初始值为0而不是123,因为这时尚未开始执行任何Java方法,而把value赋值为123是在程序被编译后,存放于类构造器()方法之中,所以把value赋值为123的操作要到类的初始化阶段才会被执行。

完结

Redis基于内存,常用作于缓存的一种技术,并且Redis存储的方式是以key-value的形式。Redis是如今互联网技术架构中,使用最广泛的缓存,在工作中常常会使用到。Redis也是中高级后端工程师技术面试中,面试官最喜欢问的问题之一,因此作为Java开发者,Redis是我们必须要掌握的。

Redis 是 NoSQL 数据库领域的佼佼者,如果你需要了解 Redis 是如何实现高并发、海量数据存储的,那么这份腾讯专家手敲《Redis源码日志笔记》将会是你的最佳选择。

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

假设一个类变量的定义为:public static int value = 123;

变量value在准备阶段过后初始值为0而不是123,因为这时尚未开始执行任何Java方法,而把value赋值为123是在程序被编译后,存放于类构造器()方法之中,所以把value赋值为123的操作要到类的初始化阶段才会被执行。

完结

Redis基于内存,常用作于缓存的一种技术,并且Redis存储的方式是以key-value的形式。Redis是如今互联网技术架构中,使用最广泛的缓存,在工作中常常会使用到。Redis也是中高级后端工程师技术面试中,面试官最喜欢问的问题之一,因此作为Java开发者,Redis是我们必须要掌握的。

Redis 是 NoSQL 数据库领域的佼佼者,如果你需要了解 Redis 是如何实现高并发、海量数据存储的,那么这份腾讯专家手敲《Redis源码日志笔记》将会是你的最佳选择。

[外链图片转存中…(img-zAsonVFE-1715621829276)]

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

需要这份系统化的资料的朋友,可以点击这里获取

  • 13
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
2023年3月11日,美团聘笔试中共包含五道编程目。以下是对每道目的简要说明: 1. 目一:这道目要求解决一个数字统计的问。可能涉及到的知识点包括数据结构、循环和条件判断等。解决问的思路可能是使用字典等数据结构来保存统计结果,并使用循环逐个读取输入数据并进行统计。 2. 目二:这道目可能是一个字符串处理的问。需要使用字符串的方法进行操作,如提取、拼接、查找和替换等。可能的解决思路包括使用正则表达式、切片和遍历等。 3. 目三:这道目可能涉及到算法和数据结构的知识。可能是一道涉及到数组、链表、树等数据结构的问。解决思路可能包括遍历、递归、搜索和排序等。 4. 目四:这道目可能是一个动态规划的问。需要根据给定的条件和规则,通过动态规划的方式求解问。解决思路包括定义状态和转移方程,使用递推或记忆化搜索进行求解。 5. 目五:这道目可能是一个图论或网络问。需要根据给定的图或网络结构,解决一个相关的问。可能涉及到广度优先搜索、深度优先搜索、最短路径等知识。解决思路可能包括使用图或网络的相关算法进行求解。 以上只是对这五道编程目的一些可能情况进行的简要描述,具体的目内容可能会有所不同。希望这些信息能对你有所帮助!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值