iOS大厂面试题总结

作者: CoderLocus | 来源:发表于2019-03-19 18:09 被阅读47次

    1. OC语法

    1. OC中对象的结构(腾讯一面)

    1. Instance对象

      1. 如果是NSObject对象,对象中只有一个isa指针,在64位中占16个字节(可以通过malloc_size函数获得),但实际只用到了8个字节(可以通过class_getInstanceSize函数获得)。
      2. 这个isa指针指向了class类对象,通过isa指针&isa_mask可以获得NSObject类的地址。
      3. 如果自定义的类,如果增加了属性或成员变量,对象中会有成员变量值得存储地址。
      4. 对象方法、属性、成员变量、协议信息存放在类对象中,类方法存放在元类对象(可以通过get_class获得)中
    2. class对象


      class对象
    3. mate-class对象

      1. isa指针指向了基类的mate-class对象,superClass指针指向了父类的mate-class对象。基类的mate-class对象的superClass指针指向了基类的class对象
        2.结构与class对象一致,只是之存储了类方法信息
    4. isa指针

      1. 在arm64架构之前isa指针直接存储了class、mate-class对象的地址
      2. 在arm64之后isa指针经过优化,使用了公用体(union)结构
        isa指针位域

    2. assign、strong、weak、copy、unsafe_unretained

    1. strong:一般用于id类型和对象的修饰符,是使用__strong修饰符,instance对象会持有该对象,setter方法中会调用retain,并且retainCount+1
    2. assign:一般用于基本数据类型,是使用__unsafe_unretained修饰符,setter时会直接赋值
    3. weak:是使用__weak修饰符,如果retainCount为0,对象会被自动释放,并设置成nil
    4. copy:是使用__strong修饰符,但是赋值的是被赋值的对象
    5. unsafe_unretained:是使用__unsafe_unretained修饰符,

    3. assing可以使用在对象中吗(头条一面)

    可以,但会造成坏内存访问的错误

    4. weak如何实现自动赋nil(头条一面)

    runtime 对注册的类, 会进行布局,对于 weak 对象会放入一个 hash 表中。 用 weak 指向的对象内存地址作为 key,当此对象的引用计数为0的时候会 dealloc, 在这个 weak 表中搜索,找到所有以key为键的 weak 对象,从而设置为 nil。

    5. 可变数组的实现原理(头条二面)

    6. KVO的实现原理(美团一面、阿里一面)

    1. 通过runtime API动态生成一个子类,让instance对象的isa指针只想这个子类,
    2. 当修改instance对象属性的时候,会调用Fondation框架里的NSSetXXXValueAndNotify方函数
      -willChangeValueForKey
      调用父类原有的set方法
      -didChangeValueForKey
      内部触发器会调用监听方法-observeValueForKeyPath:ofObject:change:context:

    7. Block的循环引用、如何解决、原理(阿里一面)

    block的本质是封装了函数调用和环境的代码块,但我感觉可以把它看成是一个对象,因为block内部也有isa指针

    1. 三种block:globalBlock、stackBlock、mallocBlock
    2. block在修饰auto变量是值传递,在修饰静态变量是指针传递,在修饰全局变量不需要传递参数
    3. 如果block被拷贝到堆上,内部会调用_block_object_assign,如果auto对象是被__strong或__copy修饰会形成强引用
    4. 可以用__weak或__unsafe_unretained

    8. Block和delegate的比较

    1. 从源头上理解和区别block和delegate
      delegate运行成本低,block的运行成本高。
      block出栈需要将使用的数据从栈内存拷贝到堆内存,当然对象的话就是加计数,使用完或者block置nil后才消除。delegate只是保存了一个对象指针,直接回调,没有额外消耗。就像C的函数指针,只多做了一个查表动作。

    2. 从使用场景区别block和delegate
      有多个相关方法。假如每个方法都设置一个 block, 这样会更麻烦。而 delegate 让多个方法分成一组,只需要设置一次,就可以多次回调。当多于 3 个方法时就应该优先采用 delegate。当1,2个回调时,则使用block。

    3. delegate更安全些,比如: 避免循环引用。使用 block 时稍微不注意就形成循环引用,导致对象释放不了。这种循环引用,一旦出现就比较难检查出来。而 delegate 的方法是分离开的,并不会引用上下文,因此会更安全些。

    4. delegate回调返回的参数被限制在了 NS 类的范围内,数量也很有限(当然可以用直接调用方法的形式在绕过,并不推荐;也可以用 Array 套着传, 不过这样需要有文档支持,不然不够清晰,回调方法也需要独立的验证,故也不推荐)。

    如果这个回调是一个不定期触发,或者会多次触发的,那么 Delegation 应该更适合;如果这个回调是一个一次性的,并且和调用方法是单线性关系的,那么 Block 应该更适合。在不同的执行线(不是线程),不同的执行次数、执行数量上的区别,是鉴别使用哪一种回调的最好判断方法。

    9. 讲一讲响应链(美团二面)

    1. 事件的每个类型,UIKit指定一个第一响应者,然后最先发送事件到这个对象。
    2. App中包含一个UILable,UITextField,UIButton,以及2个backgroundView,如果UITextField不能响应事件,UIKit发送事件到UITextField的父视图(UIView)对象,随后是UIWindow的根视图(UIView)。从根视图,响应者链在事件传递到UIWindow之前,先转移到所拥有的UIViewController。如果UIWindow不能处理事件,UIKit传递事件到UIApplication对象,也可能到app delegate如果对象是UIResponder的实例并且不是响应链的一部分。


      响应链

    10. 如何通过一个view查找它所在的viewController(美团二面)

    UIResponser *responser = self.nextResponser;
    do  {
        if ([responser isKindOfClass:[UIVC class]])
            return (UIVC *)responser;
        responser = response.nextResponser;
    } while (responser);
    

    11. 持久化(阿里一面)

    1. NSUserDefaults:用于存放小数据,只能存储系统自带的数据类型,自定义的对象无法存储
      1. 不需要关心文件名(不需要设置路径)
      2. 键值对存储(账号相关信息) 对象存储
    NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
        //放到缓存里,并不会马上放到文件里面
    [userDefaults setObject:@"123" forKey:@"account"]; //对象
    [userDefaults setObject:@"123456" forKey:@"pwd"];
    //BOOL类型
    [userDefaults setBool:YES forKey:@"status"];
    //在ios7 默认不会马上跟硬盘同步  同步操作 起到立即存储的作用
    [userDefaults synchronize];
    
    1. 属性列表property list:只能存储系统自带的数据类型,一般实际开发中存储字典、数组,自定义的模型无法进行存储
    NSString *kUserPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).firstObject stringByAppendingPathComponent:@"latestQuery.plist"];
    NSArray  *array = @[];
    [arr writeToFile:kUserPath atomically:YES]; 
    
    1. 归档NSKeyedArchiver:可以存储自定义对象,自定义对象想要归档,则自定义对象必须遵守NSCoding协议,实现协议方法
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    NSData *memberData = [NSKeyedArchiver archivedDataWithRootObject:[cache.member mj_keyValues]];
    [defaults setObject:memberData forKey:KEY_MEMBER];
    [defaults synchronize];
    
    1. 数据库:用于存放一条条的数据
    2. 文件:用于存放图片、文件、音视频等数据

    12. 多态(腾讯一面)

    iOS的多态基于了runtime,可以动态绑定数据类型,添加方法,属性等

    13. layoutIfNeeded和setNeedsLayout的区别(头条二面)

    更新布局会调用layoutIfNeeded

    • setNeedsLayout
      会标记为需要重新布局,异步调用layoutIfNeeded刷新布局,但不是立刻执行,是在RunLoop下一轮循环结束前刷新。对于这一轮runloop之内的所有布局和UI上的更新只会刷新一次,layoutSubviews一定会被调用。
    • layoutIfNeeded
      如果有需要刷新标记,会立刻调用layoutSubviews进行刷新操作,如果没有则不调用

    14. isEquel和hash的关系(头条二面)

    15. 有哪些编码方式(头条一面)

    NSASCIIStringEncoding = 1,      /* 0..127 only */
    NSNEXTSTEPStringEncoding = 2,
    NSJapaneseEUCStringEncoding = 3,
    NSUTF8StringEncoding = 4,
    NSSymbolStringEncoding = 6,
    

    2. Runtime

    1. 消息调用的过程(美团一面、阿里一面)

    1. 首先会在reveiceClasscache中查找方法
    2. 如果没有找到,会到reveiceClassclass_rw_t的方法列表中查找
    3. 如果找不到,会到superClasscache中查找
    4. 如果找不到,会到superClassclass_rw_t的方法列表中查找
    5. 如果找不到,会递归3操作,直到superClassnil
    6. 如果superClassnil,会进入消息动态解析
    7. 如果有动态解析,进入消息转发
    8. 如果没有动态解析,会调用+resolveInstanceMethod:+resolveClassMethod:
    9. 动态解析过后,会重新走消息发送机制
    10. 如果没有动态解析,会调用forwardingTargetForSeletor
    11. 如果返回不为nil,调用objc_msgSend(返回值,SEL)
    12. 如果返回nil,会调用methodSignatureForSeletor
    13. 如果返回值不为nil,调用forwardingInvocation
    14. 返回为nil,报错doesNotRecognizeSelector

    2. 如何hook一个对象的方法,而不影响其它对象(头条二面)

    1. 可以在分类的load方法里,或是initialaze里使用dispatch_once,
    2. 调用class_addMethod判断是否可以添加方法,可以的话调用class_replaceMethod函数
    3. 或者调用method_exchangeImplementations函数

    3. runtime如何通过selector找到对应的IMP地址(阿里一面)

    1. IMP class_getMethodImplementation(Class cls, SEL name); 参考2.1 消息调用的过程
    2. IMP method_getImplementation(Method m) 直接取method_t中的imp指针

    3. RunLoop

    1. runloop内部实现逻辑?(阿里一面)

    1. source0:触摸事件处理、performSelector:onThread
    2. source1:基于port之间的线程通信、系统时间捕捉
    3. Timers:NSTimer、performSelector:withObject:afterDelay:
    4. Observers:用于监听RunLoop的状态、刷新UI(BeforeWaiting)、AutoreleasePool(BeforeWaiting)
    runloop内部实现逻辑

    4. 多线程

    1. 队列、进程和线程的区别(阿里一面、头条一面、百度一面)

    1. 进程:进程是操作系统资源分配的基本单位。
    2. 线程:线程是任务调度和执行的基本单位。一个进程可以由很多个线程组成,线程间共享进程的所有资源,每个线程有自己的堆栈和局部变量。线程由CPU独立调度执行,在多CPU环境下就允许多个线程同时运行。同样多线程也可以实现并发操作,每个请求分配一个线程来处理。

    地址空间:同一进程的线程共享本进程的地址空间,而进程之间则是独立的地址空间。
    资源拥有:同一进程内的线程共享本进程的资源如内存、I/O、cpu等,但是进程之间的资源是独立的。

    1. 队列:队列是一种特殊的线性表

    2. 进程间通信的方式(百度一面)

    1. 管道pipe:管道是一种半双工的通信方式,数据只能单向流动,而且只能在具有亲缘关系的进程间使用。进程的亲缘关系通常是指父子进程关系。
    2. 命名管道FIFO:有名管道也是半双工的通信方式,但是它允许无亲缘关系进程间的通信。
    3. 消息队列MessageQueue:消息队列是由消息的链表,存放在内核中并由消息队列标识符标识。消息队列克服了信号传递信息少、管道只能承载无格式字节流以及缓冲区大小受限等缺点。
    4. 共享存储SharedMemory:共享内存就是映射一段能被其他进程所访问的内存,这段共享内存由一个进程创建,但多个进程都可以访问。共享内存是最快的 IPC 方式,它是针对其他进程间通信方式运行效率低而专门设计的。它往往与其他通信机制,如信号两,配合使用,来实现进程间的同步和通信。
    5. 信号量Semaphore:信号量是一个计数器,可以用来控制多个进程对共享资源的访问。它常作为一种锁机制,防止某进程正在访问共享资源时,其他进程也访问该资源。因此,主要作为进程间以及同一进程内不同线程之间的同步手段。
    6. 套接字Socket:套解口也是一种进程间通信机制,与其他通信机制不同的是,它可用于不同及其间的进程通信。
    7. 信号 ( sinal ) : 信号是一种比较复杂的通信方式,用于通知接收进程某个事件已经发生。

    3. 一个进程有哪些区(百度一面)

    参考5.1

    4. 多线程的方式和它们的区别(头条一面、阿里一面)

    多线程

    5. 线程死锁的四个条件(阿里一面)

    1. 互斥条件:进程对所分配到的资源不允许其他进程进行访问,若其他进程访问该资源,只能等待,直至占有该资源的进程使用完成后释放该资源
    2. 请求和保持条件:进程获得一定的资源之后,又对其他资源发出请求,但是该资源可能被其他进程占有,此事请求阻塞,但又对自己获得的资源保持不放
    3. 不可剥夺条件:是指进程已获得的资源,在未完成使用之前,不可被剥夺,只能在使用完后自己释放
    4. 环路等待条件:是指进程发生死锁后,必然存在一个进程--资源之间的环形链

    6. 线程安全的题(头条一面)

    1. 资源共享:一块资源可能被多个线程共享,比如多个线程同时访问同一个对象、同一个变量、同一个文件
    2. 当多个线程同时访问一块资源时,可能发生数据错乱或线程安全问题

    7. iOS中有哪些锁(头条一面、腾讯一面)

    1. OSSpinLock
    2. os_unfiar_lock
    3. ptheard_metux_lock
    4. dispatch_semaphore
    5. NSLock
    6. NSRecursiveLock
    7. NSCondition
    8. NSConditionLock

    8. 自旋锁和互斥锁的区别(头条二面)

    1. 自旋锁适用于:
    2. 预计线程等待锁的时间很短
    3. 临界区经常被调用,但竞争较少
    4. 多核处理
    5. CPU不紧张
    6. 互斥锁适用于:
    7. 预计线程等待锁的时间较长
    8. 单核处理器
    9. 临界区有IO操作
    10. 临界区代码复杂或循环量大
    11. 临界区竞争激烈

    9. 线程同步的方式(腾讯一面)

    1. 可以利用加锁的方式来保证线程同步
    2. 可以利用dispat_queue串行队列
    3. 可以用dispatch_semaphore信号量
    4. atomic,对象的原子性,默认在setter方法内部加锁
    5. 针对读写操作可以使用多读单写的操作来保证线程同步,例如dispatch_barrier_async和ptheard_rolock

    10. GCD执行原理?(阿里一面)

    11. 事务的特征(阿里一面)

    事务是并发控制的基本单位。所谓的事务,它是一个操作序列,这些操作要么都执行,要么都不执行,它是一个不可分割的工作单位。例如,银行转账工作:从一个账号扣款并使另一个账号增款,这两个操作要么都执行,要么都不执行。所以,应该把它们看成一个事务。事务是数据库维护数据一致性的单位,在每个事务结束时,都能保持数据一致性。 针对上面的描述可以看出,事务的提出主要是为了解决并发情况下保持数据一致性的问题。

    事务具有以下4个基本特征。

    1. Atomic(原子性):事务中包含的操作被看做一个逻辑单元,这个逻单元中的操作要么全部成功,要么全部失败。
    2. Consistency(一致性):只有合法的数据可以被写入数据库,否则事务应该将其回滚到最初状态。
    3. Isolation(隔离性):事务允许多个用户对同一个数据进行并发访问,而不破坏数据的正确性和完整性。同时,并行事务的修改必须与其他并行事务的修改相互独立。
    4. Durability(持久性):事务结束后,事务处理的结果必须能够得到固化。

    5. 内存管理

    1. 介绍下内存的几大区域?(阿里一面)

    1. 代码段:用于存放编译之后的代码
    2. 数据段:
    3. 堆段:通过malloc、calloc、alloc动态分配的空间,分配的内存地址越来越大,需要程序员手动管理内存
    4. 栈段:用于函数调用开销,例如局部变量,分配的内存空间地址越来越小,系统自动分配内存
    5. 内核区:

    2. 浅拷贝和深拷贝的区别(阿里一面、头条三面)

    浅拷贝拷贝地址,深拷贝拷贝内存
    一般不可变量调用copy,为浅拷贝;
    可变变量调用copy,或调用MutableCopy为深拷贝

    3. 数组cop后里面的元素会复制一份新的吗(头条三面)

    4. 对于字符串使用strong会有什么问题?对于可变数组使用copy这样会有什么问题?

    1. 如果赋值的是不可变字符串,没有问题,如果赋值的和被赋值是可变字符串,则如果修改赋值对象,用strong修饰的被赋值对象也会被修改
    2. 会新创建一个新的数组

    5. Autorelease pool的实现原理(阿里一面)

    1. 内部结构主要有__atAutoreleasePool、autoreleasePoolPage
    2. 调用了autorelease的对象都由autoreleasePoolPage来管理,
    3. 调用了push操作后会有一个POOL_BOUNDARY入栈,
    4. 然后调用了autorelease的对象都会加到autoreleasePoolPage,
    5. 如果autoreleasePoolPage内存不够他会创建一个新的autoreleasePoolPage,原先的child指向新的autoreleasePoolPage,新的perent指向原先的,
    6. 在调用pop以后,会从最后一个入栈的对象开始往前release,知道遇到POOL_BOUNDARY为止

    6. 性能优化

    1. 性能优化(阿里二面)

    1. CPU
      1. 尽量使用轻量级对象,比如用不到事件处理的地方,可以考虑使用CALayer取代UIView
      2. 不要频繁调用UIView的相关属性,比如frame、bounds、transform等属性,尽量减少不必要的修改
      3. 尽量提前计算好布局,在有需要时一次调整,不要多次修改属性
      4. autolayout比直接设置frame小号更多CPU资源
      5. 图片的size最好刚好跟UIImageView的size一样
      6. 控制一下线程最大并发数
      7. 尽量把耗时操作放到子线程
        1. 文本处理(尺寸计算、绘制)
        2. 图片处理(解码、绘制)
    2. GPU
      1. 尽量减少短时间内的图片大量显示,尽可能的合成一张图片显示
      2. GPU最大能处理的纹理是4096 x 4096,一但超过这个尺寸,就需要占用CPU资源处理,所以纹理最好不要超过这个尺寸
      3. 尽量减少视图的数量和层次
      4. 尽量不要使用透明度
      5. 尽量不要出现离屏渲染(在当前屏幕缓冲区以外,开出一片新的缓冲区进行渲染操作)
        1. 需要创建新的缓冲区
        2. 离屏渲染需要多次切换上下文,先从当前屏幕,切换到离屏屏幕,等到离屏渲染完成之后,有需要将缓冲区渲染到当前屏幕,有需要将上下文环境从离屏屏幕切换到当前屏幕
      6. 那些操作会造成离屏渲染
        1. 光栅化,layer.shouldRasterize = YES;
        2. 遮罩,layer.mask
        3. 圆角,同时设置layer.masksToBounds = YES 和 layer.corner > 0,可以考虑通过CoreGraphics绘制剪裁圆角,或直接使用圆角图片
        4. 阴影,layer.shadowXXX,如果设置了layer.shadowPath就不会产生离屏渲染

    2. 你是如何组件化解耦的?(阿里一面)

    项目前期一般不需要组件化解耦,而且前期开发人员少,业务发展的不是特别快,不使用组件化可以保证开发进度。但如果项目发展起来会出现很多弊端,如耦合度比较严重、容易出现冲突、业务方的开发效率不够高(因为他只关心自己的组件,却需要编译整个项目)

    1. 优点:
      1. 加快编译速度
      2. 提高开发效率
      3. 自由选择开发设计模式
      4. 方便OA有针对性测试
    2. 缺点:
      1. 资源的重复性:以前放在一起,知道哪些资源是公共资源,而组件化之后,因为各个组件都相对独立了,所以一些资源需要重复加载,导致包变大了
      2. 页面样式:因为独立开来,可能导致页面样式有差异。可以使用公共组件化解决。

    3. 优化你是从哪几方面着手?(阿里一面)

    1. 耗电优化
      1. CPU处理:尽可能的降低CPU和GPU的功耗
        1. 少用NSTimer
        2. 优化IO操作
          1. 尽量不要频繁的写入小数据,最好批量一次性写入
          2. 读写大量数据时,考虑用dispatch_io,其提供了基于GCD的异步操作IO文件的API。用dispatch_io系统会优化磁盘访问
          3. 数据量比较大的,建议使用数据库(SQLite、CoreData)
      2. 网络:
        1. 减少、压缩网络数据
        2. 如果多次请求数据相同,尽量使用缓存
        3. 如果大文件下载,使用断点续传
        4. 网络不可用时,不要尝试执行网络请求
        5. 让用户可以手动取消长时间运行、速度很慢的网络请求,设置合适的超时时间
        6. 批量传输,比如下载视频流时,不要传输很小的数据包,直接下载整个文件或一大块一大块的下载。如果下载广告,一次性下载多一些,然后慢慢展示,如果下载电子邮件,一次下载多封,不要一封一封下载
      3. 定位:
        1. 如果需要快速定位使用CLLocationManagerrequestLocation方法,定位完成后,会自动让定位硬件断电。
        2. 如果不是导航应用,不要实时刷新位置,定位完毕就关掉定位服务
        3. 尽量降低定位精度,比如尽量不要使用精度最高的kCLLocationAccuracyBest
        4. 需要后台定位时,尽量设置pauseLocationUpdatesAutomatically = YES,如果用户不大可能移动的时候会自动暂停位置更新
        5. 尽量不要使用startMonitoringSignificantLocationChanges,优先考虑startMonitoringForRegion
      4. 硬件检测优化:用户移动、摇晃、倾斜设备时,可能触发动作事件,这些事件由加速器、陀螺仪、磁力计等硬件检测,在不使用的时候,应关闭这些设备
    2. 启动优化:主要优化冷启动
      1. dyld
        1. 减少动态库,合并一些动态库,清理一些不用的动态库
        2. 减少Objc类、分类、Seletor的数量,清理一些不用的类、分类
        3. 减少c++虚函数数量
        4. Swift尽量使用struct
      2. runtime
        initialize+dispatch_once取代load、c++静态构造器等
      3. main
        在不影响用户体验的前提下,尽量延迟加载,尽量不放到finishLaunching方法中
    3. 安装包优化
      1. 资源(图片、音视频等)
        1. 采用无损压缩
        2. 删除没有用到的资源
      2. 编辑器
        1. Strip Linked Product、Make Strings Read-Only、Symbols Hidden by Default设置为YES
        2. 去掉异常支持,Enable C++ Exceptions、Enable Objective-C Exceptions设置为NO, Other C Flags添加-fno-exceptions
        3. 利用APPCode检测未使用的代码
        4. 利用LLVM插件检测出重复代码、为被调用代码
    4. 卡顿优化:参考6.1

    7. 第三方库

    1. Masonry的约束应该写在哪里(阿里一面)

    1. 在addSubView之后添加约束
    2. 相关约束对象添加之后添加约束

    2. YYModel和AF源码(阿里二面)

    3. Pod update和pod install的区别(头条二面)

    在pod多少版本之前,pod update只是更新需要更新的代码,而Pod install是更新全部代码
    不想升级specs库,可以增加忽略参数--no-repo-update

    4. SD的源码(头条二面)

    5. 看过哪些源码,讲讲思路(腾讯一面)

    6. YYAsyncLayer如何异步绘制?(阿里一面)

    8. 设计模式及架构

    1. MVC的一些缺点(头条一面)

    2. 介绍一下MVVM(阿里三面)

    3. MVC和MVVM的区别(腾讯一面)

    4. 架构(阿里二面)

    5. 如何自己设计json转model(阿里二面)

    6. 知道哪些设计模式(阿里三面、腾讯一面)

    7. 存一个通讯录,包括增删改查,用什么数据结构(腾讯一面)

    8. 讲一下我最满意的一个项目(百度二面)

    9. 介绍项目,主要介绍自己强项一点的地方(阿里二面、头条三面)

    10. 自我介绍 介绍一些项目难点(阿里三面)

    11. 怎么防止别人反编译你的app?(阿里一面)

    9. 网络

    1. 七层模型(美团一面、百度一面)

    应用层、表示层、会话层、网络层、传输层、数据链路层、物理层

    2.传输层和网络层分别是做什么的(百度一面)

    3. http有哪些部分(美团一面、腾讯一面、头条一面)

    4. Http2.0如1.x的区别(百度一面)

    5.发送一个HTTP请求的过程(百度二面)

    6. tcp和udp的区别(美团一面、百度一面)

    1. TCP:是面向链接的协议,经过三次握手建立链接,链接成功传输协议、四次放手,
    2. UDP:是非链接协议,所以TCP比UDP安全,但因为需要建立链接,所以传输速度慢

    7. get和post的区别(美团一面)

    1. get一般用于从服务器上获取数据,post一般用于向服务器传输数据
    2. get采用的地址传参,post采用报文传参
    3. get传输的数据量小,一般2K,post可传输的数据量很大,一般默认无限传输,但实际有上限(4G)
    4. get安全性非常低,post安全性较高
    5. get不能上传文件,post可以上传文件

    8. TCP头部多长,IP呢(腾讯一面)

    9. UDP可以实现一对多??(百度一面)

    10. TCP是如何保证可靠的(百度二面)

    11. TCP为什么是三次握手和四次挥手(头条三面)

    12. 知道MTU吗(腾讯一面)

    最大输出单元,如果在IP层要传输一个数据报比链路层的MTU还大,那么IP层就会对这个数据报进行分片。一个数据报会被分为若干片,每个分片的大小都小于或者等于链路层的MTU值。当同一网络上的主机互相进行通信时,该网络的MTU对通信双方非常重要。

    10. 算法

    1. 算法字符串翻转(头条二面、腾讯一面)

    2. 两个链表找第一个相同结点(腾讯一面)

    3. 找链表的倒数第k个结点(腾讯一面)

    4. 把一个链表比某个值大的放在左边,比它小的放在右边(腾讯一面)

    5. 二叉树的中序遍历,非递归(腾讯一面)

    6. 求数组的最长子数组(百度一面)

    7. 在一个10G的数据里面找出最大的100个数(百度二面)

    相关文章

      网友评论

        本文标题:iOS大厂面试题总结

        本文链接:https://www.haomeiwen.com/subject/shjmxqtx.html