1、对线程安全的理解

线程安全是指在多线程环境下,某个函数、类或数据结构能够正确地处理多个线程的并发访问,而不会出现数据竞争、不一致或其他不可预期的行为。线程安全的实现通常需要考虑以下几点:

  • 原子性:操作是不可分割的,要么全部执行,要么全部不执行。

  • 可见性:一个线程对共享数据的修改能够及时被其他线程看到。

  • 有序性:程序的执行顺序符合预期,避免指令重排导致的问题。

实现线程安全的方法包括:

  • 使用同步机制(如锁、信号量)。

  • 使用线程安全的数据结构(如 ConcurrentHashMap)。

  • 避免共享状态(如使用局部变量或线程本地存储)。

2、对链表的使用和理解,链表有哪几种并举例应用场景

链表是一种线性数据结构,由节点组成,每个节点包含数据和指向下一个节点的指针。链表的类型包括:

  1. 单向链表:每个节点只有一个指针指向下一个节点。

    • 应用场景:实现栈、队列、简单的动态集合。

  2. 双向链表:每个节点有两个指针,分别指向前一个和后一个节点。

    • 应用场景:需要双向遍历的场景(如浏览器的前进后退、LRU缓存)。

  3. 循环链表:尾节点指向头节点,形成环。

    • 应用场景:轮询调度、环形缓冲区。

链表的优点是插入和删除高效(O(1)),缺点是随机访问慢(O(n))。

3、TCP 相对于 UDP 有哪些优点,两者的不同点

TCP的优点

  • 可靠传输:通过确认、重传、流量控制和拥塞控制确保数据不丢失、不重复、按序到达。

  • 面向连接:通信前需要建立连接(三次握手),通信后释放连接(四次挥手)。

  • 适合对可靠性要求高的场景(如文件传输、网页浏览)。

TCP vs UDP

特性TCPUDP
可靠性可靠不可靠
连接面向连接无连接
传输效率较低(开销大)较高(开销小)
数据顺序保证顺序不保证顺序
应用场景HTTP、FTP、SSH视频流、DNS、游戏
4、讲述一下TCP 的传送数据的过程
  1. 建立连接(三次握手):

    • 客户端发送 SYN=1, seq=x

    • 服务端回复 SYN=1, ACK=1, seq=y, ack=x+1

    • 客户端发送 ACK=1, seq=x+1, ack=y+1

  2. 数据传输

    • 发送方将数据分割为报文段,按序发送。

    • 接收方确认收到数据(ACK)。

    • 发送方未收到ACK时会重传。

  3. 释放连接(四次挥手):

    • 客户端发送 FIN=1, seq=u

    • 服务端回复 ACK=1, ack=u+1

    • 服务端发送 FIN=1, seq=v

    • 客户端回复 ACK=1, ack=v+1

5、原子性和一致性
  • 原子性(Atomicity):事务中的操作要么全部成功,要么全部失败(如转账:A减钱和B加钱必须同时完成)。

  • 一致性(Consistency):事务执行前后,数据库从一个一致状态变到另一个一致状态(如满足约束条件)。

6、数据库的索引和事务是什么
  • 索引:加速查询的数据结构(如B+树索引)。优点:提高查询速度;缺点:占用空间,降低插入/更新速度。

  • 事务:一组操作的逻辑单元,满足ACID特性(原子性、一致性、隔离性、持久性)。

7、数据库查询操作有哪些可以提高查询效率的优化
  1. 使用索引。

  2. 避免 SELECT *,只查询需要的列。

  3. 优化JOIN操作(小表驱动大表)。

  4. 避免全表扫描(如避免对索引列使用函数)。

  5. 分库分表(大数据量时)。

  6. 使用缓存(如Redis)。

8、手写快排的代码
public class QuickSort {public static void quickSort(int[] arr, int low, int high) {if (low < high) {int pivotIndex = partition(arr, low, high);quickSort(arr, low, pivotIndex - 1);  // 递归排序左子数组quickSort(arr, pivotIndex + 1, high); // 递归排序右子数组}}private static int partition(int[] arr, int low, int high) {int pivot = arr[high];  // 选择最右元素作为基准int i = low - 1;         // i是小于基准的元素的边界for (int j = low; j < high; j++) {if (arr[j] < pivot) {i++;swap(arr, i, j);  // 将小于基准的元素放到左侧}}swap(arr, i + 1, high);  // 将基准放到正确位置return i + 1;}private static void swap(int[] arr, int i, int j) {int temp = arr[i];arr[i] = arr[j];arr[j] = temp;}public static void main(String[] args) {int[] arr = {3, 6, 8, 10, 1, 2, 1};quickSort(arr, 0, arr.length - 1);System.out.println(Arrays.toString(arr)); // 输出: [1, 1, 2, 3, 6, 8, 10]}
}
9、展示曾经写过的项目代码并讲述功能

为什么选择做安卓

我选择做安卓开发的原因主要有以下几点:

  • 用户基数大:Android 是全球市场份额最大的移动操作系统,拥有庞大的用户群体。

  • 开放性和灵活性:相比 iOS,Android 系统更开放,允许开发者更自由地定制和优化应用。

  • 技术生态丰富:Android 开发涉及 UI/UX、性能优化、多线程、网络通信等多个领域,技术挑战性强。

  • 跨平台趋势:Kotlin、Flutter、Jetpack Compose 等技术的发展让 Android 开发更具扩展性。

此外,我对移动端交互和性能优化有浓厚兴趣,Android 开发能让我深入理解系统底层机制(如 Binder、Handler 等),提升综合技术能力。

安卓了解多少,技术非技术都可以
技术方面
  • 开发语言:Java(传统)、Kotlin(官方推荐,更简洁安全)。

  • 核心组件:Activity(界面)、Service(后台)、BroadcastReceiver(广播)、ContentProvider(数据共享)。

  • UI 框架:XML + View 体系、Jetpack Compose(声明式 UI)。

  • 架构模式:MVC → MVP → MVVM(DataBinding + ViewModel + LiveData)。

  • 性能优化:内存泄漏(LeakCanary)、卡顿分析(Systrace)、APK 瘦身(ProGuard)。

  • 新技术:协程(Kotlin Flow)、KMM(跨平台)、Android 12/13 新特性(如 Material You)。

非技术方面
  • 市场现状:Android 占据全球约 70% 移动市场份额,但国内厂商深度定制(如 MIUI、EMUI)。

  • 开发者生态:Google Play 审核较宽松,但国内需适配各大应用商店。

  • 挑战:碎片化严重(系统版本、屏幕尺寸、厂商 ROM 差异)。

聊项目,登录采用的redis+cookie的分布式session解决方案,具体聊聊

在分布式系统中,Session 需共享,避免用户登录状态丢失(如服务器重启或负载均衡切换)。

实现方案
  1. 登录流程

    • 用户输入账号密码,服务端校验通过后生成唯一 SessionID

    • 将 SessionID:UserInfo 存入 Redis(设置过期时间)。

    • 通过 Set-Cookie 将 SessionID 返回给浏览器。

  2. 后续请求

    • 浏览器自动携带 Cookie(SessionID)

    • 服务端从 Redis 查询 SessionID,获取用户信息。

  3. 安全性优化

    • Cookie 设置 HttpOnly 防 XSS,Secure 强制 HTTPS。

    • Redis 存储的 Session 可加密(如 JWT)。

优点
  • 无状态:服务端无需存储 Session,适合横向扩展。

  • 高可用:Redis 集群保障 Session 不丢失。

登录过程当中对密码的校验,存储讲讲
校验流程
  1. 前端对密码做初步校验(如长度、复杂度)。

  2. 服务端二次校验(防恶意请求),例如:

    if (password.length() < 8 || !containsLetterAndDigit(password)) {throw new InvalidPasswordException();
    }

存储方案
  • 哈希加密:使用 BCrypt(推荐)或 PBKDF2,避免明文存储。

    String hashedPassword = BCrypt.hashpw(rawPassword, BCrypt.gensalt());

  • 加盐(Salt):防止彩虹表攻击,每个用户密码使用独立随机盐值。

面向对象的三大特性具体讲解下

封装(Encapsulation)

  • 隐藏内部实现,暴露安全接口。

继承(Inheritance)

  • 子类复用父类属性和方法(extends)。

多态(Polymorphism)

  • 同一方法在不同子类中有不同实现(覆盖 @Override + 父类引用指向子类对象)。

讲讲java的权限控制(protect继承关系,default是包访问权限)
修饰符类内同包子类其他包
private
default
protected
public
  • protected:子类可访问(即使跨包)。

  • default(包权限):仅同包内可见。

java基本类型的以及占空间大小
类型大小取值范围
boolean1字节true/false
byte1字节-128 ~ 127
short2字节-32768 ~ 32767
int4字节-2³¹ ~ 2³¹-1
long8字节-2⁶³ ~ 2⁶³-1
float4字节IEEE 754 单精度浮点
double8字节IEEE 754 双精度浮点
char2字节Unicode 字符(0~65535)

注意:JVM 可能对 boolean 优化为 1 bit,但数组中占 1 字节。

boolean类型占多大内存,int占多少,double(8字节)

如上

java循环的使用
(1) for 循环
(2) while 循环

(3) do-while 循环

(4) 增强 for(遍历集合)

java的反射机制,单例模式被反射机制破环,具体是反射的哪些Api进行破环的

Java 反射可以过 Class.getDeclaredConstructor() 和 Constructor.setAccessible(true) 绕过单例模式的私有构造方法限制,从而创建多个实例。

防御反射攻击的方法
  • 枚举单例(推荐):JVM 保证枚举实例的唯一性,反射无法破坏。

  • 构造方法中抛出异常

简单介绍单例模式的实现方式都有哪些
实现方式特点线程安全防反射
饿汉式类加载时初始化,可能浪费资源
懒汉式第一次调用时初始化,需加锁解决线程问题❌(需同步)
双重检测锁延迟加载 + 同步块优化性能
静态内部类利用类加载机制保证线程安全,延迟加载
枚举最安全,JVM 保障唯一性,天然防反射和序列化破坏
双重检测锁的模式可以解决懒汉式单例的存在的多线程问题,请问枚举可以解决单例模式存在的
单例模式的优势
  1. 线程安全:JVM 在加载枚举类时保证实例唯一。

  2. 防反射攻击Constructor.newInstance() 会直接抛出异常。

  3. 防序列化破坏:枚举的序列化由 JVM 特殊处理,不会创建新实例。

java当中的集合八股
集合框架分类
  • Collection

    • List:有序可重复(ArrayListLinkedList)。

    • Set:无序不重复(HashSetTreeSet)。

    • Queue:队列(LinkedListPriorityQueue)。

  • Map

    • HashMap:数组 + 链表/红黑树。

    • TreeMap:基于红黑树有序。

    • ConcurrentHashMap:线程安全。

高频考点
  • ArrayList vs LinkedList

  • HashMap 的哈希冲突解决(拉链法 + 红黑树)。

  • ConcurrentHashMap 的分段锁(JDK7)和 CAS + synchronized(JDK8)。

HashMap的扩容机制
  1. 触发条件:当元素数量超过 容量 × 负载因子(默认 0.75) 时扩容。

  2. 扩容过程

    • 新建一个 2 倍大小的数组。

    • 重新计算每个键值对的哈希值,分配到新数组(JDK8 优化:高位掩码判断位置是否变化)。

  3. JDK8 优化:链表长度 ≥8 时转红黑树(提高查询效率)。

Java多线程当中的锁
锁的分类
  1. synchronized

    • 修饰方法或代码块,JVM 级别实现。

    • 可重入,非公平锁。

  2. ReentrantLock

    • API 级别锁,需手动 lock()/unlock()

    • 支持公平锁、可中断、条件变量(Condition)。

  3. ReadWriteLock

    • 读写分离(ReentrantReadWriteLock),提高读多写少场景性能。

  4. StampedLock

    • 乐观读锁,避免写线程饥饿。

在项目当中使用过哪些锁,怎么使用的

new对象的时候,JVM底层的一个过程(类加载机制)

当执行 new MyClass() 时,JVM 底层会经历以下步骤:

(1) 类加载(若未加载)
  • 加载(Loading)

    • 通过类加载器(ClassLoader)查找 .class 文件,将字节码加载到方法区。

    • 生成 Class 对象(存储在堆中,作为方法区数据的访问入口)。

  • 验证(Verification):检查字节码合法性(如魔数、语法)。

  • 准备(Preparation):为静态变量分配内存并赋默认值(如 int 初始化为 0)。

  • 解析(Resolution):将符号引用(如类名、方法名)转为直接引用(内存地址)。

  • 初始化(Initialization):执行静态代码块(static{})和静态变量赋值。

(2) 对象实例化
  • 分配内存

    • 指针碰撞(堆内存规整时):移动指针分配连续空间。

    • 空闲列表(堆内存不规整时):从空闲内存块列表中选择合适区域。

  • 内存空间初始化:将所有字段置为默认值(如 int 为 0,引用为 null)。

  • 设置对象头:存储 Mark Word(哈希码、GC 分代年龄等)和类元数据指针(指向方法区的 Class 对象)。

  • 执行构造方法<init>):调用用户定义的构造函数,完成字段赋值。

(3) 对象引用关联
  • 将堆中对象的内存地址赋给栈中的引用变量(如 MyClass obj)。

讲讲网络当中Https

HTTPS = HTTP + SSL/TLS,核心是通过加密和证书保障安全:

(1) 加密流程(TLS 握手)
  1. 客户端发起请求

    • 发送支持的加密算法列表和随机数(Client Random)。

  2. 服务器响应

    • 返回选择的加密算法、服务器证书(含公钥)和随机数(Server Random)。

  3. 证书验证

    • 客户端用 CA 机构的公钥验证证书合法性(防中间人攻击)。

  4. 生成会话密钥

    • 客户端用服务器公钥加密一个 Pre-Master Secret 并发送。

    • 双方通过 Client Random + Server Random + Pre-Master 生成对称密钥(Session Key)。

  5. 加密通信

    • 后续数据传输使用 Session Key 对称加密(如 AES)。

(2) 关键点
  • 非对称加密:用于密钥交换(RSA/ECDHE)。

  • 对称加密:用于数据传输(AES)。

  • 数字证书:验证服务器身份,由 CA 机构签发。

刚刚提到的Https是基于Http,Http使用的是Tcp,那么Tcp的四次挥手当中第三次挥手是谁向谁进行挥手

在 TCP 四次挥手中:

  1. 第一次挥手:客户端 → 服务器,发送 FIN=1(客户端主动关闭)。

  2. 第二次挥手:服务器 → 客户端,发送 ACK=1(确认收到 FIN)。

  3. 第三次挥手:服务器 → 客户端,发送 FIN=1(服务器准备关闭)。

  4. 第四次挥手:客户端 → 服务器,发送 ACK=1(确认收到 FIN)。

关键问题答案

  • 第三次挥手是服务器向客户端发送 FIN,表示服务器数据已发送完毕,准备关闭连接。

为什么需要四次挥手?
  • TCP 是全双工的,双方需独立关闭自己的发送通道。

  • 第二次和第三次挥手不能合并:服务器可能还有数据要发送(延迟确认)。

总结:

  1. new 对象过程:类加载 → 分配内存 → 初始化 → 构造方法调用。

  2. HTTPS:通过 TLS 握手建立安全通道,混合使用非对称加密和对称加密。

  3. TCP 挥手:第三次挥手是服务器通知客户端关闭连接。

数据结构当中栈和队列在项目使用过嘛

算法题:两个栈实现一个队列

队列(Queue)是 先进先出(FIFO) 的数据结构,而栈(Stack)是 后进先出(LIFO) 的数据结构。我们可以利用 两个栈(stack1 和 stack2 来模拟队列的操作:

核心思想
  1. 入队(enqueue:直接压入 stack1

  2. 出队(dequeue

    • 如果 stack2 为空,则把 stack1 的所有元素弹出并压入 stack2(此时 stack2 的栈顶就是最早入队的元素)。

    • 如果 stack2 不为空,直接弹出栈顶元素。

.工作内容简单介绍(10min)

2.介绍一下TCP三握四次挥手(10min)
三次握手(建立连接)
  1. SYN(Client → Server):

    • 客户端发送 SYN=1, seq=x(随机序列号)。

  2. SYN+ACK(Server → Client):

    • 服务端返回 SYN=1, ACK=1, seq=y, ack=x+1(确认客户端的 x,并发送自己的 y)。

  3. ACK(Client → Server):

    • 客户端发送 ACK=1, seq=x+1, ack=y+1(确认服务端的 y)。

✅ 目的:确保双方都有发送和接收能力,防止历史连接干扰。

四次挥手(关闭连接)
  1. FIN(Client → Server):

    • 客户端发送 FIN=1, seq=u(表示不再发送数据)。

  2. ACK(Server → Client):

    • 服务端返回 ACK=1, ack=u+1(确认收到 FIN)。

  3. FIN(Server → Client):

    • 服务端发送 FIN=1, seq=v(表示服务端也准备关闭)。

  4. ACK(Client → Server):

    • 客户端返回 ACK=1, ack=v+1(确认服务端的 FIN)。

✅ 为什么需要四次?

  • TCP 是全双工的,双方需独立关闭自己的发送通道。

2.1为什么第四次挥手要超时等待2MSL

MSL(Maximum Segment Lifetime):报文最大生存时间(Linux 默认 60s)。

  • 目的 1:确保最后一个 ACK 能到达服务端。

    • 如果服务端没收到 ACK,会重发 FIN,客户端在 2MSL 内还能响应。

  • 目的 2:让本次连接的所有报文在网络中消失,避免影响后续新连接。

2.2如果有大量的time_wait,close_wait,你会如何检测分析,原因?出现阶段?以及如何避免
(1)TIME_WAIT(客户端状态)
  • 出现阶段:主动关闭连接的一方(如 HTTP 客户端、微服务调用方)。

  • 原因

    • 短连接频繁建立和关闭(如爬虫、API 频繁调用)。

    • 没有复用 TCP 连接(如 HTTP/1.1 未启用 Keep-Alive)。

  • 解决

  • 复用连接(HTTP/1.1 Keep-Alive、连接池)。

  • 调整内核参数(慎用):

(2)CLOSE_WAIT(服务端状态)
  • 出现阶段:被动关闭连接的一方(如服务端未正确调用 close())。

  • 原因

    • 代码 Bug:未关闭 Socket(如 Java 未调用 socket.close())。

    • 线程阻塞:处理请求时卡住,无法执行关闭逻辑。

  • 解决

    • 检查代码确保资源释放(try-with-resources 或 finally 块)。

    • 优化服务端性能(避免阻塞)。

2.3什么情况下syn请求丢弃,失效?如何分析,如何解决,不考虑防火墙
(1)SYN 被丢弃的原因
  • 半连接队列(SYN Queue)满

    • 服务端未及时处理 SYN,导致队列溢出(默认大小 net.ipv4.tcp_max_syn_backlog)。

  • SYN Flood 攻击

    • 攻击者发送大量 SYN 但不完成握手,耗尽服务端资源。

  • 网络问题

    • 中间路由器丢弃 SYN(如拥塞、TTL 过期)。

(2)如何分析?
  • 服务端统计

  • 抓包分析

(3)解决方案
  • 增大半连接队列

  • 启用 SYN Cookie(防攻击):

  • 优化服务端

    • 加快握手处理(如负载均衡、扩容)。

总结

问题原因解决方案
TIME_WAIT 过多短连接频繁关闭复用连接、调整 tcp_tw_reuse
CLOSE_WAIT 过多服务端未正确关闭 Socket检查代码、优化资源释放
SYN 被丢弃队列满、攻击、网络问题增大队列、SYN Cookie、抓包分析
3.项目深挖,包括项目实现背景(即为什么去做这个项目),项目功能如何实现,项目实现中的一些细节和设计模式,项目对应功能如何测试,如何部署。遇到问题如何发散解决(40min)

3.进程线程区别
对比项进程(Process)线程(Thread)
定义操作系统资源分配的基本单位CPU 调度的基本单位(属于进程)
内存占用独立内存空间(隔离性强)共享进程内存(高效但需同步)
创建开销大(需分配独立资源)小(共享进程资源)
通信方式进程间通信(IPC):管道、共享内存、消息队列直接读写共享变量(需加锁)
崩溃影响一个进程崩溃不影响其他进程一个线程崩溃可能导致整个进程退出
并发性多进程并行(多核)多线程并行(轻量级并发)

关键点

  • 线程是进程的子任务,共享进程的堆内存,但有自己的栈和寄存器。

  • 多线程需处理竞态条件(如 synchronizedReentrantLock)。

4OSI七层模型
层数名称功能协议/设备
7应用层用户接口(HTTP、FTP)HTTP、SMTP、DNS
6表示层数据格式转换(加密、压缩)SSL、JPEG
5会话层建立/管理会话(RPC)NetBIOS
4传输层端到端可靠传输(TCP/UDP)TCP、UDP
3网络层路由寻址(IP 地址)IP、ICMP、路由器
2数据链路层帧传输(MAC 地址)Ethernet、交换机
1物理层比特流传输(电缆、光纤)网卡、集线器

简化记忆

  • 上三层(应用、表示、会话):面向用户。

  • 下四层(传输、网络、数据链路、物理):面向数据。

5详细介绍线程
线程的生命周期(状态)
  1. NEW:刚创建,未调用 start()

  2. RUNNABLE:可运行(可能在等待 CPU)。

  3. BLOCKED:等待锁(如 synchronized)。

  4. WAITING:无限期等待(如 wait())。

  5. TIMED_WAITING:超时等待(如 sleep(1000))。

  6. TERMINATED:执行完毕。

创建线程的方式
  1. 继承 Thread 类

  2. 实现 Runnable 接口:

  3. 线程池ExecutorService):

线程同步
  • synchronized

  • ReentrantLock

1.get和post的区别

1. GET vs POST 的区别

对比项GETPOST
语义获取资源(幂等)提交数据(非幂等)
数据位置URL 查询参数(明文)请求体(可加密)
长度限制受 URL 长度限制(约 2KB)无限制(服务器可配置)
缓存可被缓存不可缓存
安全性参数暴露在 URL(不安全)数据在请求体中(相对安全)

使用场景

  • GET:搜索、分页(如 ?page=1)。

  • POST:登录、表单提交(如 JSON 数据)。

5.互联网这两年前景不好,谈一下你的看法
  • 短期挑战

    • 政策监管加强(如数据安全、反垄断)。

    • 资本趋于理性,野蛮增长时代结束。

    • 全球经济下行影响投资和消费。

  • 长期机会

    • 技术驱动:AI、云计算、物联网等仍是未来核心。

    • 数字化转型:传统行业(医疗、制造)仍需互联网技术赋能。

    • 全球化市场:中国互联网企业出海(如 TikTok、SHEIN)。

结论:行业从“高速增长”转向“高质量发展”,对技术深度和复合能力要求更高。

6.为什么觉着互联网会比其他行业就业广
  1. 技术渗透性强

    • 几乎所有行业都需要互联网技术(金融→FinTech、零售→电商)。

  2. 岗位多样性

    • 技术(开发、测试)、产品、运营、设计、数据分析等岗位覆盖全链条。

  3. 薪资竞争力

    • 平均薪资高于传统行业(如制造业)。

  4. 低准入门槛

    • 相比医生、律师等职业,互联网更依赖技能而非学历证书。

  5. 远程办公机会

    • 支持全球化协作(如程序员可远程为海外公司工作)。

7.app测试和web测试有何不同
对比项App 测试Web 测试
运行环境移动设备(iOS/Android)浏览器(Chrome、Firefox)
兼容性需测试不同机型、OS版本、分辨率主要测试浏览器兼容性
网络依赖弱网、断网测试更重要网络影响较小
安装与更新需测试安装、升级、卸载流程无需安装,即时更新
性能指标内存占用、CPU、电量、启动速度页面加载速度、服务器响应时间
工具Appium、XCUITest、EspressoSelenium、Cypress、Playwright

核心差异

  • App 测试更关注硬件交互(如摄像头、GPS)和移动端特性(如手势操作)。

  • Web 测试更注重跨浏览器一致性和前端渲染性能。

8.你是怎么区分前端和后端的
对比项前端(Frontend)后端(Backend)
职责用户界面(UI)和交互逻辑数据处理、业务逻辑、数据库交互
技术栈HTML/CSS/JavaScript、React/VueJava/Python/Go、Spring/Django
关注点用户体验、页面性能、兼容性高并发、安全性、API 设计
调试工具Chrome DevTools、LighthousePostman、Jmeter、日志分析
输出结果浏览器渲染的页面数据库记录、API 响应(JSON/XML)

简单判断

  • 前端代码运行在浏览器,后端代码运行在服务器

  • 前端请求数据(如 fetch('/api/data')),后端提供数据(如返回 JSON)。

内存分页与分段的区别及优缺点
分页(Paging)
  • 原理

    • 内存划分为固定大小的页(如 4KB),进程的地址空间分为同等大小的页框。

    • 通过页表映射虚拟地址到物理地址。

  • 优点

    • 解决外部碎片(物理内存利用率高)。

    • 支持虚拟内存(页面可换入换出磁盘)。

  • 缺点

    • 页内可能产生内部碎片(最后一页未用满)。

分段(Segmentation)
  • 原理

    • 按逻辑单元(代码段、数据段、堆栈段)划分内存,每段长度可变。

    • 通过段表记录基址和长度。

  • 优点

    • 符合程序逻辑(便于共享和保护段)。

  • 缺点

    • 产生外部碎片(需内存紧凑或动态分区)。

对比总结
特性分页分段
划分单位固定大小页可变长度段
碎片问题内部碎片外部碎片
管理复杂度简单(页表)复杂(段表+保护机制)
适用场景通用内存管理(OS 主流方案)需要逻辑隔离(如早期系统)

现代 OS(如 Linux):结合分页和分段,实际使用分页机制,段基址固定为 0。

Android方向
四大组件生命周期(Activity、Service等)
(1) Activity 生命周期
  • 核心方法

    • onCreate():初始化 UI 和数据。

    • onStart():Activity 可见但未前台交互。

    • onResume():Activity 进入前台,可交互。

    • onPause():失去焦点(如弹窗),需快速释放资源。

    • onStop():完全不可见(可能被销毁)。

    • onDestroy():释放所有资源。

  • 场景

    • 屏幕旋转:onDestroy() → onCreate()(默认重建)。

    • 按 Home 键:onPause() → onStop()

(2) Service 生命周期
  • 启动方式

    • startService()

      • onCreate() → onStartCommand() → (运行中)→ onDestroy()

    • bindService()

      • onCreate() → onBind() → (通信中)→ onUnbind() → onDestroy()

(3) BroadcastReceiver
  • 动态注册

    • onReceive() 执行后立即销毁。

  • 静态注册

    • 常驻,通过 AndroidManifest.xml 声明。

(4) ContentProvider
  • 生命周期由系统管理,主要方法:

    • onCreate():初始化数据源(如数据库)。

    • query()/insert()/update()/delete():CRUD 操作。

Handler机制原理(Looper、MessageQueue)
核心组件
  1. Handler:发送和处理消息(sendMessage() / handleMessage())。

  2. MessageQueue:消息队列(单链表,按时间排序)。

  3. Looper:循环从 MessageQueue 取消息并分发。

工作流程
  1. Looper.prepare():创建 Looper 和 MessageQueue(主线程已默认创建)。

  2. Looper.loop():无限循环调用 MessageQueue.next() 获取消息。

  3. Handler.sendMessage():将 Message 插入 MessageQueue

  4. Handler.handleMessage():在目标线程处理消息。

性能优化:内存泄漏(Cursor未关闭、Bitmap未回收)、ANR原因
自定义View流程(measure/layout/draw)
iOS方向
Runtime机制:消息转发、Category实现
消息转发

Objective-C 的消息转发机制是在对象无法响应某个方法时提供的一种补救措施。消息转发分为三个阶段:

  1. 动态方法解析+resolveInstanceMethod: 或 +resolveClassMethod:,可以在这里动态添加方法实现。

  2. 备用接收者-forwardingTargetForSelector:,可以将消息转发给其他对象处理。

  3. 完整转发-methodSignatureForSelector: 和 -forwardInvocation:,可以封装 NSInvocation 进行更灵活的转发。

Category 实现

Category 是通过运行时动态将方法添加到类中(编译时为类生成 category_t 结构体,运行时合并到类的方法列表中)。特点:

  • 可以添加方法,但不能添加实例变量(可通过关联对象间接实现)。

  • 方法会覆盖原类方法(同名方法调用优先级:Category > 原类 > 父类)。

实现原理:

  • 编译后生成 _category_t 结构体,包含方法、属性、协议列表。

  • 运行时通过 attachCategories 函数将 Category 数据合并到类中。

多线程:GCD与NSOperation对比、线程安全
特性GCD (Grand Central Dispatch)NSOperation
抽象层级C API,更底层Objective-C 对象,更高层
任务封装BlockNSOperation 子类
依赖管理需手动控制(如 barrier)直接通过 addDependency: 支持
状态控制无直接状态管理可监听 isReady/isFinished/isCancelled
优先级通过 QoS 设置可设置 queuePriority
取消任务不可取消可取消
适用场景简单异步任务复杂任务依赖关系
线程安全

保证线程安全的常见方式:

  1. 串行队列:将读写操作放到同一队列(如 dispatch_queue_serial)。

  2. @synchronizedNSLockos_unfair_lockpthread_mutex

  3. 原子操作atomic 属性(仅保证读写原子性,不保证线程安全)。

  4. 内存屏障OSMemoryBarrier 避免指令重排。

设计模式:Delegate vs Notification vs KVO的差异及应用场景
特性DelegateNotificationKVO
通信方向一对一(反向传值)一对多(广播)一对多(监听属性变化)
耦合度较高(需协议绑定)低(松散耦合)最低(无需显式调用)
实现复杂度中(需实现协议方法)低(仅注册观察)高(需处理移除观察者)
适用场景UITableView 事件处理跨模块通信(如登录状态广播)数据模型变化监听(如进度更新)
性能开销低(直接调用)中(需维护观察者列表)高(依赖 Runtime 派发)

最佳实践

  • 需要返回值时用 Delegate。

  • 跨组件通信用 Notification。

  • 监听对象属性变化用 KVO(注意移除观察者避免崩溃)。

单例模式的实现与优缺点
优点
  1. 全局唯一访问点,便于管理资源(如配置、缓存)。

  2. 减少重复实例化开销。

缺点
  1. 测试困难:全局状态可能导致测试依赖。

  2. 内存常驻:单例生命周期与应用一致。

  3. 隐藏耦合:滥用会导致代码难以维护。

替代方案:依赖注入(通过参数传递实例)。

MVC/MVVM在Android中的实践
MVC
  • Model:数据层(Room、Retrofit)。

  • View:XML 布局文件。

  • Controller:Activity/Fragment(实际中常承担过多逻辑)。

问题:Activity 臃肿,单元测试困难。

MVVM(推荐)
  • ViewModel:持有数据,暴露 LiveData/Flow。

  • View:Activity/Fragment 观察数据变化。

  • Data Binding:可选的 XML 绑定(减少样板代码)。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/web/89040.shtml
繁体地址,请注明出处:http://hk.pswp.cn/web/89040.shtml
英文地址,请注明出处:http://en.pswp.cn/web/89040.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Wiz笔记二次开发

目前wiz笔记的docker版本停留在1.0.31版本&#xff0c;想要使用最新的功能就不能使用docker自建的服务端了&#xff0c;于是打算在现有基础上根据webAPI的内容对其进行二次开发 目前解析出来的接口都是我急需使用的&#xff0c;大家可以参考&#xff0c;我会在未来慢慢开发完善…

AI-Compass RLHF人类反馈强化学习技术栈:集成TRL、OpenRLHF、veRL等框架,涵盖PPO、DPO算法实现大模型人类价值对齐

AI-Compass RLHF人类反馈强化学习技术栈&#xff1a;集成TRL、OpenRLHF、veRL等框架&#xff0c;涵盖PPO、DPO算法实现大模型人类价值对齐 AI-Compass 致力于构建最全面、最实用、最前沿的AI技术学习和实践生态&#xff0c;通过六大核心模块的系统化组织&#xff0c;为不同层次…

阿里云 Kubernetes 的 kubectl 配置

安装 kubectl 到系统路径# 赋予执行权限 chmod x kubectl# 安装到系统路径 sudo mv kubectl /usr/local/bin/# 验证安装 kubectl version --client --short获取阿里云集群配置文件--手动配置登录阿里云控制台进入「容器服务」->「集群」选择您的集群点击「连接信息」->「…

C++-linux系统编程 8.进程(二)exec函数族详解

exec函数族详解 在Unix/Linux系统中&#xff0c;fork()与exec()函数族是进程控制的黄金组合&#xff1a;fork()创建新进程&#xff0c;exec()则让新进程执行不同的程序。这种组合是实现shell命令执行、服务器进程动态加载任务等核心功能的基础。本文将详细解析exec函数族的原理…

PTL亮灯拣选系统提升仓库运营效率的方案

随着电商、零售、制造等行业的快速发展&#xff0c;仓库的作业效率成为企业竞争力的关键因素之一。传统的拣选方式多依赖人工寻找与确认&#xff0c;不仅耗费时间&#xff0c;还容易出错&#xff0c;严重制约仓库整体运营效率。为了应对日益增长的订单需求与提高拣选准确率&…

LVS三种模式实战

IPVS基本上是一种高效的Layer-4交换机&#xff0c;它提供负载平衡的功能。当一个TCP连接的初始SYN报文到达时&#xff0c;IPVS就选择一台服务器&#xff0c;将报文转发给它。此后通过查看报文的IP和TCP报文头地址&#xff0c;保证此连接的后继报文被转发到相同的服务器。这样&a…

HCIA第二次综合实验:OSPF

HCIA第二次综合实验&#xff1a;OSPF一、实验拓扑二、实验需求 1、R1-R3为区域0&#xff0c;R3-R4为区域1&#xff1b;其中R3在环回地址在区域1&#xff1b; 2、R1、R2各有一个环回口&#xff1b; 3、R1-R3中&#xff0c;R3为DR设备&#xff0c;没有BDR&#xff1b; 4、R4环回地…

深入解析环境变量:从基础概念到系统级应用

目录 一、基本概念及其核心作用 1、基本概念 2、核心作用 二、常见环境变量 三、查看环境变量方法 四、测试PATH 1、对比执行&#xff1a;./project和直接执行project的区别 2、思考&#xff1a;为何某些命令可直接执行而无需路径&#xff0c;但我们的二进制程序却需要…

Spring Boot:DTO 字段 cPlanId 无法反序列化的奇葩问题

本文记录一次在 Spring Boot 项目中&#xff0c;DTO 字段明明有值&#xff0c;反序列化后却是 null 的问题。最终发现并不是常见的 JSON 工具库 Bug&#xff0c;而是隐藏在 setter 命名大小写规则中的坑。&#x1f4bb; 背景介绍技术栈如下&#xff1a;Spring Boot&#xff1a;…

文本生成视频的主要开源模型

AI文本到视频生成技术发展迅速&#xff0c;这些模型的“快速”通常指相对于传统视频制作的效率&#xff08;生成时间从几秒到几分钟&#xff0c;取决于硬件&#xff09;&#xff0c;但实际速度取决于您的计算资源&#xff08;如GPU&#xff09;。这些模型大多依赖于深度学习框架…

vscode里面怎么配置ssh步骤

01.ubuntu里面下载几个插件还需要下载插件net-tools02.vscode里面下载插件会生成下面类似电视机的插件(room6)

【人工智能99问】激活函数有哪些,如何选择使用哪个激活函数?(5/99)

文章目录激活函数一、激活函数的分类1. 按“是否线性”分类2. 按“是否饱和”分类&#xff08;针对非线性激活函数&#xff09;3. 按“适用层”分类二、常见激活函数及特点&#xff08;一&#xff09;非线性激活函数&#xff08;主要用于隐藏层&#xff09;1. 饱和激活函数&…

代数——第4章——线性算子(算符)(Michael Artin)

第 4 章 线性算子(Linear Operators) That confusions of thought and errors of reasoning still darken the beginnings of Algebra, is the earnest and just complaint of sober and thoughtful men. (思维混乱和推理错误 仍然使代数的开端变得模糊不清&#xff0c; …

Neo4j Python 驱动库完整教程(带输入输出示例)

Neo4j Python 驱动库完整教程&#xff08;带输入输出示例&#xff09; 1. 基础连接示例 输入代码 from neo4j import GraphDatabase# 连接配置 URI "bolt://localhost:7687" USER "neo4j" PASSWORD "password123" # 替换为你的实际密码def t…

Axios 和 Promise 区别对比

Axios 和 Promise 是前端开发中两个不同的概念&#xff0c;尽管 Axios 基于 Promise 实现&#xff0c;但它们的核心定位和功能有显著区别。以下是对比分析&#xff1a; 1. 核心定位与功能Promise 定义&#xff1a;Promise 是 JavaScript 的异步编程方案&#xff0c;用于处理异步…

Git分支管理与工作流详解

前言 分支管理是Git最强大的功能之一&#xff0c;它允许开发者在不影响主代码库的情况下创建独立的工作空间。本文将详细介绍Git分支的操作和常见工作流策略&#xff0c;帮助团队更高效地协作开发。 1. Git分支的基本概念 1.1 什么是分支 在Git中&#xff0c;分支本质上是指…

【flutter】flutter网易云信令 + im + 声网rtm从0实现通话视频文字聊天的踩坑

接了一个国外的项目,项目采用网易云im 网易云信令声网rtm遇到的一些问题这个项目只对接口,给的工期是两周,延了工期,问题还是比较多的 需要全局监听rtm信息,收到监听内容,引起视频通话网易云给的文档太烂,所有的类型推策只能文档一点点推声网的rtm配置网易云的信令,坑太多,比如…

hive/spark sql中unix_timestamp 函数的坑以及时间戳相关的转换

我用的是hive版本是3.1.3&#xff0c;spark版本是3.3.1&#xff0c;它们的unix_timestamp 函数在同样的语句下转换出来的时间戳是完全不同的&#xff0c;如下试验所示1.unix_timestamp 函数的坑上图试验中我同样的计算 2025-07-11 10:00:00 时间点对应的时间戳&#xff0c;但是…

MyBatis专栏介绍

专栏导读 在当今的软件开发领域&#xff0c;持久层框架的选择对于提高开发效率和数据处理能力至关重要。MyBatis作为一个半自动化的ORM框架&#xff0c;因其灵活、高效的特点&#xff0c;在众多开发者中广受好评。本专栏《MyBatis实战》旨在通过深入浅出的方式&#xff0c;帮助…

HarmonyOS从入门到精通:自定义组件开发指南(七):自定义事件与回调

HarmonyOS从入门到精通&#xff1a;自定义组件开发指南&#xff08;七&#xff09;&#xff1a;自定义事件与回调 在HarmonyOS应用开发中&#xff0c;组件化架构是构建复杂界面的基础&#xff0c;而组件间的高效通信则是实现业务逻辑的核心。自定义事件与回调机制作为组件交互的…