iOS跳动,京东,小米,腾讯面经
百度面试
不用临时变量怎么实现 swap(a, b)?(实现两个值的交换)
解:用加法或者异或都可以
a = a + b
b = a - b # 此时 b = (a + b) - b = a
a = a - b # 此时 a = (a + b) - a = b
二维有序数组查找数字?
剑指 offer 第 3题,解题思路:
-
方法一:
暴力遍历,可以做剪枝操作,如果遍历的数字大于target,就直接break。 -
方法二:
二分查找,对每一行做二分查找,python有内置函数bisect,非常方便。 -
方法三:
从右上角往左下方向查找,如果大于target,就向左移一位,如果小于target,就向下移一位
这种查找方法适用于有序数组,在本题中既可以从右上角出发,也可以从左下角出发,像流水一样,缓缓朝刚好大于target的方向流动。
在亿级日志中查找登录次数最多的十个用户?
剑指 offer 第 30题,解题思路:
先用哈希表保存登陆次数和ID,然后用红黑树保存最大的十个数。(这是我的思路,不确定对不对)
问题:当用户量极大时(比如上亿用户),哈希表可能无法全部放入内存。
-
方法一:哈希统计 + 最小堆(单机处理)
哈希统计:遍历日志文件,用哈希表统计每个用户的登录次数
维护Top 10:使用大小为10的最小堆来维护当前找到的登录次数最多的用户 -
方法二:分治 + 归并(适用于大数据)
哈希分片:根据用户ID的哈希值将日志分割到多个文件中
分别统计:对每个文件统计用户登录次数
归并结果:汇总所有文件的统计结果,找出全局Top 10 -
方法三:使用MapReduce框架
对于真正的亿级数据,使用分布式计算框架更合适:
Map阶段:提取每条日志中的用户ID,输出<user_id, 1>
Shuffle阶段:框架自动将相同user_id的数据发送到同一个Reducer
Reduce阶段:统计每个user_id的总登录次数
二次MapReduce:找出全局Top 10
优化建议
预处理:如果日志是按时间排序的,可以只处理最近的数据
布隆过滤器:快速过滤掉低频用户
多级统计:先按天统计,再汇总多天结果
简述排序算法?
引用:
1、冒泡排序:与后面的依次比较大小,往后排
2、选择排序:选择最小的交换,最后交换到前面的位置
3、插入排序:与前面排好序的对比,插入到前面
4、希尔排序:分治算法,二分增量排序
5、归并排序:分治算法,递归左右两边的排序,最后合并
6、快速排序:选择基准元素,递归左右两边的排序(partion函数的原理)
7、堆排序:二叉树排序(不稳定)
8、计数排序:每个桶只存储单一键值(适合整数)
9、桶排序:每个桶存储一定范围的数值
10、基数排序:根据键值的每位数字来分配桶,从个位开始,然后十位,百位...
iOS中:类的load和initialize 方法,哪个先调用?调用时机再什么时间?
1. +load 方法
调用时机:+load 方法在类或分类被加载到运行时(Runtime)时调用,通常是在程序启动时。
调用顺序:
1.父类的 +load 方法先于子类调用。
2.类的 +load 方法先于分类的 +load 方法调用。
3.不同类之间的 +load 方法调用顺序取决于编译顺序。
2. +initialize 方法
调用时机:+initialize 方法在类第一次接收到消息(如调用类方法或实例方法)时调用,且只会调用一次(类被使用的时候)。
调用顺序:
父类的 +initialize 方法先于子类调用。
如果子类没有实现 +initialize 方法,父类的 +initialize 方法会被调用。
总结
+load 先于 +initialize 调用:+load 在程序启动时调用,而 +initialize 在类首次使用时调用。
调用顺序:+load 的调用顺序由编译顺序决定,而 +initialize 的调用顺序由类的继承关系决定。
说说你对 block 的理解?
三种 block:堆、栈、全局
捕获变量,__block捕获指针(forwarding)
栈上的自动复制到堆上,block 的属性修饰符是 copy,循环引用的原理和解决方案。
解决循环引用:__weak
说说你对 runtime 的理解?
主要是方法调用时如何查找缓存,如何找到方法,找不到方法时怎么转发,对象的内存布局。
-
isa 指针:
指向对象的类(Class),用于动态派发方法。
在 ARM64 架构中,isa 可能经过优化(Non-pointer isa),利用多余的位存储引用计数、析构状态等信息。(变量列表、缓存列表、方法列表、变量列表) -
实例变量(ivars):
紧随 isa 之后,按声明顺序排列。
内存对齐(通常按指针大小或变量类型对齐)。
说说 UITableView 的调优?
- 通过 instruments 检查影响性能的地方
- 使用预估算设置 cell高度
- 计算cell高度并在 runloop 空闲时缓存
- 使用重用机制
谈谈你对 ARC 的理解。ARC 是编译器完成的,依靠引用计数,谈谈几个属性修饰符的内存管理策略,什么情况下会内存泄露?
isKindOfClass、isMemberOfClass区别是什么
isKindOfClass:检查对象是否是:指定类或其子类的实例
isMemberOfClass:某个对象确切属于某个类型。
NSArray *array = [NSArray array];
if ([array isKindOfClass:[NSArray class]]) {
NSLog(@"array 是 NSArray 或其子类的实例");
}
if ([array isKindOfClass:[NSObject class]]) {
NSLog(@"array 是 NSObject 或其子类的实例");
}
//输出
array 是 NSArray 或其子类的实例
array 是 NSObject 或其子类的实例
NSArray *array = [NSArray array];
if ([array isMemberOfClass:[NSArray class]]) {
NSLog(@"array 是 NSArray 的实例");
}
if ([array isMemberOfClass:[NSObject class]]) {
NSLog(@"array 是 NSObject 的实例");
}
//输出
array 是 NSArray 的实例
数组和链表的区别?
根据具体需求选择数据结构:
优先数组(快速访问、内存紧凑)
优先链表(频繁增删、动态大小)
image.png
SDWebImage 下载了图片后为什么要解码?
默认情况:从网络或磁盘加载的图片数据是压缩格式的二进制数据,必须解码成未压缩的位图(如 RGBA 像素数据)才能被 GPU 渲染。
SDWebImage 的解决方案:在后台线程提前解码图片,确保主线程渲染时直接使用解码后的位图,避免实时解码带来的性能问题。
解码前后内存对比:
- 压缩图片:文件可能只有 100KB,但解码后的一张 1000x1000 的 PNG(32 位色深)会占用 1000 × 1000 × 4 ≈ 4MB 内存。
- 未提前解码:若在渲染时(如 UIImageView 显示时)才解码,系统会临时分配解码后的内存,可能导致峰值内存暴涨(尤其在多图同时渲染时)。
SDWebImage 的策略:提前在后台解码并缓存位图,虽然占用内存,但避免了重复解码和内存波动。(建立一个内存映射)
了解NSURLConnection和Session吗?
1. NSURLConnection (已废弃)
NSURLConnection 是苹果早期提供的网络请求 API,在 iOS 2.0 引入,但在 iOS 9.0 被标记为废弃。
同步请求:会阻塞当前线程
异步请求:通过委托回调返回数据
-
缺点
没有后台下载
不能暂停、恢复或取消请求
复杂的委托模式
不能多部分上传
2. NSURLSession (推荐)
NSURLSession 是苹果在 iOS 7 引入的现代网络 API,取代了 NSURLConnection。
-
三种会话类型:
Default: 类似 NSURLConnection 的标准请求
Ephemeral: 不存储缓存、cookie 等的临时会话
Background: 应用在后台时也能执行上传下载 -
任务类型:
Data Task: 用于普通的 HTTP 请求
Download Task: 用于文件下载,支持断点续传
Upload Task: 专门用于文件上传 -
改进的功能:
后台传输支持
暂停、恢复、取消操作
更灵活的委托模型
支持现代网络特性
说一下NSURLSession具体的实现原理
底层创建 __NSURLSessionLocal 或 __NSCFURLSession
每个 Session 持有一个唯一的标识符(创建 Task 时生成唯一标识符)
维护一个操作队列 (NSOperationQueue) 用于任务调度
-
进程间通信:
应用通过 XPC 与 nsurlsessiond 守护进程通信
即使应用被挂起,传输仍可持续 -
唤醒机制:
使用 Darwin 通知中心传递事件
传输完成时通过推送唤醒应用
iOS TCP流量控制方法总结
具体取决于你的需求(如优化性能、节省电量、限制带宽等)。以下是常见的方法和技术:
iOS 提供了高级网络框架(如 URLSession),它们已经内置了 TCP 流量优化机制(如拥塞控制、慢启动等)。你可以通过配置 URLSession 来控制部分行为:
-
设置 QoS(后台流量):
let config = URLSessionConfiguration.default
config.networkServiceType = .background // 后台流量,低优先级
let session = URLSession(configuration: config) -
限制并发连接数:
config.httpMaximumConnectionsPerHost = 2 -
自定义 TCP 参数(低级控制)
let tcpOptions = NWProtocolTCP.Options()
tcpOptions.noDelay = true // 禁用 Nagle 算法(减少小数据包延迟)
tcpOptions.connectionTimeout = 3 // 设置连接超时
页面间的传值方式有哪些?
公有属性,公有方法和协议,block传值,通知,extern全局变量传值,NSUserDefault简单数据存储传值
哈希表如何处理冲突?
具体策略:
- 线性探测(Linear Probing)
- 二次探测(Quadratic Probing)
- 双重哈希(Double Hashing)
Autoreleasepool什么时候释放?
AutoreleasePool(自动释放池)会在以下情况下释放其管理的对象:
- 在当前 RunLoop 迭代结束时:主线程的 RunLoop 在每个迭代周期中会自动创建和销毁 AutoreleasePool
- 显式调用 drain 方法时:手动创建的 AutoreleasePool 会在调用 drain 时释放
- Pool 对象本身被释放时:当 AutoreleasePool 的引用计数为0被销毁时
swift使用的基础库
pod 'HandyJSON' , '5.0.2' # JSON转Model,阿里出品,使用很方便
pod 'MJRefresh' , '3.7.6' # 刷新:上拉下拉
pod 'SnapKit' , '5.6.0' # 布局
pod 'SnapKitExtend' , '~> 1.1.0' # 针对约束的扩展
pod 'Kingfisher' , '7.6.2' # 网络图片加载
pod 'SDWebImage' , '5.18.10'
pod 'IQKeyboardManagerSwift' , '= 6.5.11'
pod 'Alamofire' , '5.8.1' # 网络请求(swfit)
pod 'SwifterSwift' , '5.2.0'
pod 'lottie-ios' , '3.4.1' # Installing lottie-ios 3.4.1 (was 4.3.4)
pod 'Toast-Swift' , '5.1.0' # 弹窗提示
pod 'RxSwift' , '~> 6.2.0'
pod 'RxCocoa' , '~> 6.2.0'
pod 'RxDataSources' , '~> 5.0'
pod 'SwiftyRSA' , '1.7.0' # 加密
pod 'KeychainAccess' , '4.2.2' # 钥匙链访问
pod 'SSZipArchive' , '= 2.4.3' # web缓存压缩
pod 'AMapSearch' , '9.7.0' # 高德地图 地图SDK搜索功能
pod 'AMapLocation' , '2.10.0' # 高德地图 定位SDK
pod 'AMapFoundation' , '~> 1.8.0' # 高德地图
pod 'AMapNavi' , '9.8.1' # 已包含3D地图,无需单独引入3D地图 (9.8.1)
pod 'AMapTrack' , '1.4.2' # 图片选择器
pod 'HXPHPicker' , '2.0.0'
pod 'JPush' , '5.2.0' # 必选项 极光推送 #pod 'JCore' # 可选项,也可由pod 'JPush'自动获取
pod 'Starscream' , '~> 4.0.6'
pod 'JXSegmentedView' , '1.3.0' # 分类切换滚动视图
pod 'ActiveLabel' , '1.1.0' # 协议展示Label
pod 'FSPagerView' , '0.8.3' # 轮播图
#移动开发:分享、支付
pod 'WechatOpenSDK-XCFramework' , '2.0.2'
pod 'AlipaySDK-iOS' , '~> 15.6.8'
pod 'AliyunOSSiOS' , '2.10.18'
引用
新iOS面试题全集合(目前不断更新)
新iOS开发京东零售的面试题
iOS开发,跳槽面试应该注意的Swift面试题
iOS某些大厂以及小公司的面试题!
iOS面试--字节跳动最新iOS开发面试题