【面经】多益网络客户端开发

一 java三大特性

        封装。封装最好理解了。封装是面向对象的特征之一,是对象和类概念的主要特性。封装,也就是把客观事物封装成抽象的类,并且类可以把自己的数据和方法只让可信的类或者对象操作,对不可信的进行信息隐藏。

        继承。继承是指这样一种能力:它可以使用现有类的所有功能,并在无需重新编写原来的类的情况下对这些功能进行扩展。通过继承创建的新类称为“子类”或“派生类”,被继承的类称为“基类”、“父类”或“超类”。

        多态性。它是指在父类中定义的属性和方法被子类继承之后,可以具有不同的数据类型或表现出不同的行为,这使得同一个属性或方法在父类及其各个子类中具有不同的含义。

二 多态实现原理

        本质上多态分两种:编译时多态(又称静态多态)和运行时多态(又称动态多态)

        重载(overload)就是编译时多态的一个例子,编译时多态在编译时就已经确定,运行的时候调用的是确定的方法。我们通常所说的多态指的都是运行时多态,也就是编译时不确定究竟调用哪个具体方法,一直延迟到运行时才能确定。这也是为什么有时候多态方法又被称为延迟方法的原因。

        Java实现多态有 3 个必要条件:继承、重写和向上转型。只有满足这 3 个条件,开发人员才能够在同一个继承结构中使用统一的逻辑实现代码处理不同的对象,从而执行不同的行为。

  • 继承:在多态中必须存在有继承关系的子类和父类。

  • 重写:子类对父类中某些方法进行重新定义,在调用这些方法时就会调用子类的方法。

  • 向上转型:在多态中需要将子类的引用赋给父类对象,只有这样该引用才既能可以调用父类的方法,又能调用子类的方法。

三 java垃圾回收算法

        标记-清除算法(Mark-Sweep)垃圾收集器首先标记所有可达对象,随后清除未标记的对象,适合于老年代对象的清理。

        复制算法(Copying)主要用于新生代,将内存区域分为两块,当一块内存用完时,复制存活的对象到另一块内存,然后清空原来的内存块。

        标记-整理算法(Mark-Compact)类似标记-清除,但清除后会将存活的对象向内存一端移动,避免内存碎片化。

        分代收集算法(Generational Garbage Collection)根据对象的生命周期分为新生代和老年代,分别使用不同的垃圾回收算法,新生代常用复制算法,老年代使用标记-清除或标记-整理。

四 链表使用场景优缺点

        使用场景:当数据需要频繁插入或删除时(如实现队列、堆栈等),链表比数组效率高。适用于需要动态扩展的场景,避免数组扩展时的性能开销。

        优点:插入和删除操作效率高,特别是在不需要遍历链表的情况下,时间复杂度为 O(1)。动态分配内存,不需要事先确定大小。

        缺点:链表的随机访问性能差,查找某个元素需要 O(n) 时间复杂度。由于链表的节点需要额外的指针域,空间开销较大。

五 进程、线程、协程

1.定义

        进程:一个独立的执行环境,它包括一个程序计数器、一组CPU寄存器、一个堆栈、一组环境变量以及至少一个打开文件的集合等。它是系统进行资源分配和调度的一个独立单位,可以看作应用程序的一次动态执行过程。

        线程:运行在进程上下文中的逻辑流,是程序执行流的最小单元。线程包括线程ID、当前指令指针、寄存器和堆栈等。一个进程可以包含多个线程,这些线程共享进程的资源,如内存空间和文件描述符。

        协程:一种用户级的轻量级线程,完全由用户控制。协程拥有自己的寄存器上下文和栈,在调度切换时保存和恢复这些上下文,避免内核切换的开销,因此比线程更加高效。

2.资源分配

        进程:独立拥有系统资源,每个进程有独立的地址空间,互不影响。进程间的资源隔离增加了安全性,但同时也增加了资源消耗。

        线程:共享其所属进程的资源,如内存地址空间和文件描述符。这种资源共享减少了资源消耗,但也带来了线程间数据同步的挑战。

        协程:不直接操作或持有操作系统资源,而是通过运行时库在用户模式下进行调度。协程使用的资源远少于线程和进程,因此在高并发场景下性能优势明显。

3.上下文切换

        进程:上下文切换时需要保存和恢复较多的状态信息,包括内存空间、全局变量和打开的文件描述符等,因此切换成本较高。

        线程:虽然共享一些进程资源,但仍需保存和恢复线程局部存储(如堆栈)、寄存器等状态,切换成本低于进程但高于协程。

        协程:只需保存和恢复寄存器上下文和栈,且完全在用户态进行,避免了内核态的切换,因此上下文切换非常快。

4.并发与并行

        进程:在多核处理器上支持真正的并行执行。多个进程可以同时在不同的处理器核心上运行,充分利用多核系统的并行能力。

        线程:同样支持多核并行执行,但由于共享资源,线程间的调度和同步比进程复杂。

        协程:主要实现的是并发而非并行,适用于IO密集型任务。通过在一个线程内切换协程,可以有效利用等待IO操作的时间。

5.适用场景

        进程:适用于需要独立资源空间和强隔离性的应用场景,如不同的用户请求处理。

        线程:适合于同一进程内部需要并行执行多个子任务的场景,如多线程下载。

        协程:适用于IO密集型和高并发应用,如网络服务器的请求处理。

六 线程安全

        线程安全是指在多线程环境下,代码能够正确同步执行,不会出现竞态条件和数据不一致的情况。

        加锁机制: 使用 synchronized 关键字或 Lock 类,确保共享资源在同一时间只被一个线程访问。

        原子操作: 使用 Java 提供的原子类(如 AtomicInteger)或操作确保线程间的数据操作是原子的。

        volatile: 关键字 volatile 可以确保变量的修改对所有线程可见,避免线程缓存导致数据不一致。

        线程安全类: 使用线程安全的集合类(如 ConcurrentHashMapCopyOnWriteArrayList)。

七 常用的排序算法

【思路详解+详细注释】小白都能看懂的力扣算法详解——排序算法(多语言版本代码示例)-CSDN博客

冒泡排序(Bubble Sort)时间复杂度:O(n²)。通过多次遍历,将相邻元素进行比较并交换,把最大的元素“冒泡”到数组末端。

        选择排序(Selection Sort)时间复杂度:O(n²)。每次遍历找到最小的元素放到数组的前面,依次进行。

        插入排序(Insertion Sort)时间复杂度:O(n²)。通过构建有序序列,将未排序的数据插入到已排序部分的适当位置。

        归并排序(Merge Sort)时间复杂度:O(n log n)。采用分治法,递归将数组分成两半,分别排序后合并。

        快速排序(Quick Sort)时间复杂度:O(n log n)。通过选择一个“基准”元素,将数组分成两部分,分别排序。

        堆排序(Heap Sort)时间复杂度:O(n log n)。利用堆这种数据结构,通过构建最大(最小)堆进行排序。

        计数排序(Counting Sort)时间复杂度:O(n+k)。适用于数据范围较小的整数排序,基于元素值的统计。

        桶排序(Bucket Sort)时间复杂度:O(n+k)。将元素分配到不同的桶中,再对每个桶进行单独排序。

        基数排序(Radix Sort)时间复杂度:O(nk)。通过逐位比较进行排序,适用于数据位数较小的情况。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值