基础面试题
swift的基础类型有哪些
Swift是一种强类型语言,支持多种基础类型,这些基础类型包括:
- 整型 (Integers):
Int、UInt
等。 - 浮点型 (Floating-Point Numbers):
Double、Float
等 - 布尔型 (Boolean):
Bool
- 字符串 (String)
- 字符 (Character)
- 符号字面量 (Literal) :
true、false、nil、0、1.23
等 - 元组 (Tuple) : 一组不同类型的数据的组合
- 可选型 (Optional) : 用于表示一个变量有值或者没有值
Swift还支持类和结构体等复杂的数据类型,这些数据类型是由基础数据类型组合而成。
除了基本类型, swift 也支持collection类型,例如 Array,Set,Dictionary。Swift中的集合类型也是基本数据类型, 并且与其他语言比较类似。
在 Swift 中问号(?)的作用是什么?
在 Swift 中,问号 “?” 用于表示可选值 (Optionals)。可选值是一种特殊的类型,表示一个变量可能有值也可能没有值。
使用可选值类型可以有效地避免 null 引用异常 (null reference exception) 。当一个变量是可选值类型时,你必须在使用它之前进行检查。如果它有值,才能使用它,而不会引起程序崩溃。
当赋值给可选值时,如果不加”?” 那么编译器会将这个值包装为可选值类型。
在使用可选值类型之前需要进行取值操作,以确保其有值并且可用.
常用的取值操作如下:
if-let
或guard-let
, 可以检查可选值是否有值并将其分配给一个临时常量或变量。- 强制解析 (force unwrap),使用感叹号 ! 可以直接访问可选值中的值,但如果这个可选值是
nil
则会发生运行时错误。 - 隐式解析可选值,使用可选值类型的变量名来访问可选值中的值,如果这个可选值是
nil
则会发生运行时错误。
所以 “?” 是可选类型的标识符,在使用可选值类型时需要根据场景来选择合适的取值操作。
在IOS开发中KVO是什么?
KVO (Key-Value Observing) 是 iOS 开发中一种机制,用于监听对象的属性值的变化。它允许开发者在不修改对象本身的情况下,监听对象的属性值的变化,并在发生变化时进行响应。KVO 是一种观察者模式,它可以让你在不破坏封装性的前提下观察对象的状态变化,而不用去手动地实现通知机制。KVO 能够让你轻松地监听和响应对象的属性变化,并且它是线程安全的,可以在多线程环境中使用。
需要注意的是,KVO在观察的属性必须是NSObject的子类且必须使用@objc dynamic修饰,才能被观察, 否则会报错。
另外,KVO常常被用来实现数据绑定,这种情况下,你需要在对象的属性变化时自动更新 UI。但是过度使用 KVO 会导致性能问题,因此在使用 KVO 时应该尽量避免不必要的监听,并在不再需要时及时移除监听。
KVO 使用方法:
- 在需要监听的对象上调用 addObserver(_:forKeyPath:options:context:) 方法,并指定要监听的属性的 keyPath。
- 实现 observeValue(forKeyPath:of:change:context:) 方法,并在其中处理属性值变化的逻辑。
- 当监听不再需要时,调用 removeObserver(_:forKeyPath:) 方法来移除监听。
在IOS开发中AppDelegate和SceneDelegate的区别?
在 iOS 13 之前的版本中, AppDelegate 是应用程序的入口点,它处理应用程序的生命周期事件,如启动、挂起、进入后台等。它还负责应用程序级别的任务,如处理远程推送、设置根视图控制器等。
在 iOS 13 及以上版本中, Apple 推出了 SceneDelegate 类来处理应用程序的场景级别事件,如屏幕上的某一场景启动、屏幕上的某一场景挂起等。
主要的差别在于 AppDelegate 主要处理整个应用的生命周期和应用级别的事件,而 SceneDelegate 则主要处理场景(window)级别的事件。
在使用场景的应用中,多场景可以同时存在,每个场景对应一个SceneDelegate,而只有一个AppDelegate,它对应着整个应用程序
因此,在iOS13 及以上系统中,SceneDelegate 是用来管理场景,AppDelegate 继续管理整个应用程序的一些生命周期事件及应用级别的任务,两者各自都起着不同的作用。
在Swift中class和struct的共同点和区别?
Class 和 Struct 是 Swift 中两种基本的数据类型,它们之间有一些共同点和区别。
共同点:
都可以定义属性 (properties) 和方法 (methods)。
都可以遵循协议 (protocols)。
都可以使用类型转换 (type casting)。
都可以使用扩展 (extensions) 添加新的功能。
区别:不同的创建方式: 结构体是由 struct 关键字创建,类是由 class 关键字创建。
值类型和引用类型: 结构体是值类型,类是引用类型。结构体在进行赋值和传递时会进行值拷贝,类会进行引用传递。
继承: 类支持继承,结构体不支持。
deinit: 类有 deinit 方法可以进行清理操作,结构体没有
通过mutating关键字来修改结构体中的属性,而类可以直接修改。
根据使用场景来决定是使用类还是结构体,如果需要继承或者在赋值或传递时需要进行引用传递,则使用类;如果需要一个简单的数据类型并且需要在赋值或传递时进行值拷贝,则使用结构体。需要注意的是,结构体和类都是可以使用协议和扩展,协议继承以及类型转换来扩展功能的,而不仅仅限于类.
选择结构体还是类取决于你的项目需求和预期行为。如果不需要继承或者在赋值和传递时需要进行值拷贝,则选择结构体;如果需要继承或者在赋值和传递时需要进行引用传递,则选择类。
ios开发中有哪些常用的设计模式?
- 责任链(Chain Of Responsibility)责任链模式在面向对象程式设计里是一种软件设计模式,它包含了一些命令对象和一系列的处理对象。每一个处理对象决定它能处理哪些命令对象,它也知道如何将它不能处理的命令对象传递给该链中的下一个处理对象。
- 命令(Command)命令模式是一种设计模式,它尝试以对象来代表实际行动。命令对象可以把行动(action) 及其参数封装起来,于是这些行动可以被:重复多次、取消(如果该对象有实现的话)、取消后又再重做
- 解释器(Interpreter)给定一种语言,定义他的文法的一种表示,并定义一个解释器,该解释器使用该表示来解释语言中句子。
- 迭代器(Iterator)迭代器模式可以让用户通过特定的接口巡访容器中的每一个元素而不用了解底层的实现。
- 中介者(Mediator)用一个中介者对象封装一系列的对象交互,中介者使各对象不需要显示地相互作用,从而使耦合松散,而且可以独立地改变它们之间的交互。
- 备忘录(Memento)在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样就可以将该对象恢复到原先保存的状态。
- 观察者(Observer)一个目标对象管理所有相依于它的观察者对象,并且在它本身的状态改变时主动发出通知
- 状态(State)在状态模式中,对象的行为是基于它的内部状态而改变的。 这个模式允许某个类对象在运行时发生改变。
- 策略(Strategy)对象有某个行为,但是在不同的场景中,该行为有不同的实现算法。策略模式:定义了一族算法(业务规则)、封装了每个算法、这族的算法可互换代替(interchangeable)。
- 模板方法(Template method) 模板方法模式是一种行为设计模式, 它通过父类/协议中定义了一个算法的框架, 允许子类/具体实现对象在不修改结构的情况下重写算法的特定步骤。
- 访问者(Visitor)封装某些作用于某种数据结构中各元素的操作,它可以在不改变数据结构的前提下定义作用于这些元素的新的操作。
- 抽象工厂(Abstract Factory)抽象工厂模式提供了一种方式,可以将一组具有同一主题的单独的工厂封装起来。在正常使用中,客户端程序需要创建抽象工厂的具体实现,然后使用抽象工厂作为接口来创建这一主题的具体对象。
- 生成器(Builder)一种对象构建模式。它可以将复杂对象的建造过程抽象出来(抽象类别),使这个抽象过程的不同实现方法可以构造出不同表现(属性)的对象。
- 工厂方法(Factory Method)定义一个创建对象的接口,但让实现这个接口的类来决定实例化哪个类。工厂方法让类的实例化推迟到子类中进行。
- 单态(Monostate)单态模式是实现单一共享的另一种方法。不同于单例模式,它通过完全不同的机制,在不限制构造方法的情况下实现单一共享特性。 因此,在这种情况下,单态会将状态保存为静态,而不是将整个实例保存为单例。
- 单例(Singleton)单例对象的类必须保证只有一个实例存在。许多时候整个系统只需要拥有一个的全局对象,这样有利于我们协调系统整体的行为。
- 适配器(Adapter)适配器模式有时候也称包装样式或者包装(wrapper)。将一个类的接口转接成用户所期待的。一个适配使得因接口不兼容而不能在一起工作的类工作在一起,做法是将类自己的接口包裹在一个已存在的类中。
- 桥接(Bridge)桥接模式将抽象部分与实现部分分离,使它们都可以独立的变化。
- 组合(Composite)将对象组合成树形结构以表示‘部分-整体’的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。
- 修饰(Decorator)修饰模式,是面向对象编程领域中,一种动态地往一个类中添加新的行为的设计模式。 就功能而言,修饰模式相比生成子类更为灵活,这样可以给某个对象而不是整个类添加一些功能。
- 外观(Facade)外观模式为子系统中的一组接口提供一个统一的高层接口,使得子系统更容易使用。
- 享元(Flyweight)使用共享物件,用来尽可能减少内存使用量以及分享资讯给尽可能多的相似物件;它适合用于当大量物件只是重复因而导致无法令人接受的使用大量内存。
- 保护代理模式(Protection Proxy)在代理模式中,创建一个类代表另一个底层类的功能。 保护代理用于限制访问。
- 虚拟代理(Virtual Proxy)在代理模式中,创建一个类代表另一个底层类的功能。 虚拟代理用于对象的需时加载。
架构面试题
什么是依赖注入,依赖注入主要解决什么问题?
依赖注入 (Dependency Injection, DI) 是一种编程范式,通过将依赖关系通过构造函数或其他方式显式地传递给对象来实现,而不是在对象内部通过 new 或者其他方式来创建依赖对象。
使用依赖注入可以有效地降低类之间的耦合度,使得类的实现更加松散,更易于测试和维护。
可以使用依赖注入框架来简化依赖注入的过程,比如Swift-DI,Cleanse,Dip,Injector,Swinject等。
对swift响应式编程的理解,并举例Swift中响应式编程框架有哪些?
响应式编程 (Reactive Programming) 是一种编程范式,它聚焦于对于数据流和变化的响应。在响应式编程中,开发者声明了数据流和转换,而不是编写控制流程来控制数据流。使用响应式编程可以让代码变得更简洁,易于维护和扩展。此外,还可以帮助减少常见的线程问题,如线程安全和高级同步问题。
Swift 中有一些响应式编程框架可供使用,如:
- RxSwift: 这是一个用于 Swift 的响应式编程框架,它基于 ReactiveX(Rx)规范实现,提供了一组用于操作数据流和异步操作的操作符。
- ReactiveSwift: 一个用于 Swift 的响应式编程框架,提供了一组用于操作数据流和异步操作的函数,并且具有较好的性能。
- Bond: 一个轻量级的响应式编程框架,它提供了简单的数据绑定和响应式操作。
Swift中常见的架构模式有哪些,他们的区别是什么
在Swift中MVC、MVVM、MVP是三种常见的软件架构模式。
- MVC (Model-View-Controller) 是一种将应用程序的逻辑分成三个部分的设计模式。 Model 代表数据和业务逻辑,View 是用户界面,Controller 则是用来控制 Model 和 View 之间的交互的部分。
- MVVM (Model-View-ViewModel) 是一种将应用程序的逻辑分成三个部分的设计模式。Model 代表数据和业务逻辑,View 是用户界面,ViewModel 则是用来控制 Model 和 View 之间的交互的部分。
- MVP (Model-View-Presenter) 是一种将应用程序的逻辑分成三个部分的设计模式。 Model 代表数据和业务逻辑,View 是用户界面,Presenter 则是用来控制 Model 和 View 之间的交互的部分。
三种模式基本上相似,但是有一些细微差别,MVC中,controller 作为了view 和 model之间的中间层。而MVP 和 MVVM中 ViewModel和 Presenter 则只是起到中间层和View绑定作用。
Controller 通常负责处理用户交互,解析用户输入并将其转换为操作。它还负责更新用户界面。通常,它会直接更新视图或者调用视图的更新方法。而 ViewModel 主要负责将数据模型转换为可供视图使用的格式,并且处理视图和数据模型之间的交互,进而维护View 状态。简单来说,Controller 主要处理业务逻辑和视图之间的关系,ViewModel 主要处理数据模型和视图之间的关系。
对组件化的理解,Swift中常见的组件化框架有哪些?
组件化框架都可以帮助开发者实现组件化开发,让应用程序的代码更好维护和管理,提高开发效率。不同框架之间可能会有一些区别,比如支持的语言、实现思想、功能特性等,需要根据项目需求和个人喜好进行选择。
除了 BeeHive,还有很多其他类似的组件化框架可供选择,如:
- Typhoon: 一个基于 Objective-C 的组件化框架,提供了依赖注入、组件生命周期管理等功能,可以帮助开发者简化应用程序的组件化开发。
- YapTaskQueue: 一个用于 Swift 的组件化框架,提供了一组工具,帮助开发者组织和管理应用程序的组件。
- JLRoutes: 一个路由框架,可以帮助开发者在组件之间传递数据和调用组件的方法。
- Pippin : 一个基于 protocol 的轻量级的组件化框架,提供了路由、组件化、服务等功能。
- Router: 一个路由框架,支持解析链接并且根据链接打开相应的组件
算法面试题
常见的排序算法有哪些,并讲解其原理
快速排序、归并排序、冒泡排序、插入排序等
快速排序是一种分治算法,是对冒泡排序的一种改进。它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。
具体的操作流程如下:
- 选取一个关键数,将数组分为两部分:比关键数小的数放到左边,大的数放到右边
- 递归地对左右两部分数组分别进行快速排序
- 整个排序过程结束,数组将变成有序序列
- 快速排序是一种非常高效的排序算法,其平均时间复杂度为 O(nlogn)。因此,在实际的开发中,快速排序是一种非常常用的排序算法
常见的搜索算法有哪些
二分查找:二分查找(Binary Search)是一种在有序数组中查找某一特定元素的查找算法。二分查找依赖于数组有序,在每次查找中,二分查找都可以将查找区间减半,直到找到要查找的元素,或者区间为空为止。
DFS(深度优先搜索):DFS 是一种图论中的搜索算法,它从一个节点开始沿着边的方向,深入图中直到所有的节点都已经被访问过为止。DFS 是一种递归算法,它沿着树或图的深度进行搜索。
BFS(广度优先搜索):BFS 是一种图论中的搜索算法,它从图的根节点开始,以层为单位进行搜索,在一层层地拓展图的节点,直到所有的节点都已经被访问过为止。BFS 是一种队列算法,它沿着树或图的宽度进行搜索。
讲一下对图算法的理解
图算法主要用于处理图形问题,是图论中的一个重要分支。下面是一些常见的图算法:
- 最短路径算法:在图中找到两点间的最短路径,例如 Dijkstra 算法和 Floyd 算法。
- 最小生成树算法:在图中找到一个生成树,并且生成树的权值和最小,例如 Prim 算法和 Kruskal 算法。
- 图的遍历算法:在图中遍历每一个结点,例如 DFS 和 BFS。
- 关键路径算法:在图中找到关键路径,例如 AOE 网络。
这些算法在解决图形问题时都有各自的优势,在面试中可以做一些简单的题目来评估对这些算法的理解程度。
讲一下对动态规划算法的理解
动态规划算法常见以下几种:
背包问题:背包问题是一种经典的动态规划问题,它涉及到一个背包容积有限的问题,你需要在容积有限的情况下,选择最优的物品,使得总价值最大。
最长公共子序列:最长公共子序列是一种动态规划问题,它涉及到两个序列,你需要求出这两个序列的最长公共子序列。
编辑距离:编辑距离是一种动态规划问题,它涉及到两个字符串,你需要通过插入、删除、替换操作将一个字符串变换成另一个字符串,计算出所需要的最少操作数。
逻辑面试题
Swift的if else guard语句的使用和区别
if语句是Swift中的条件语句,它按照一个特定的逻辑判断条件,如果该条件为真,则执行相关语句块。
guard语句也是一种条件语句,主要用于在方法或函数开始时对参数进行验证。如果参数不符合要求,则直接从该方法或函数返回,而不需要继续执行方法体。
else语句是if语句的附属语句,当if语句的条件不成立时,会执行else语句。
项目业务能力
开发中50人左右研发团队一般是怎么管理项目需求进度的,产品研发流程?
如何尽量准确的评估研发时长和交付时间节点
效率工具能力
xcode的scheme是干嘛用的?把scheme删除项目还能编译打包吗?
Xcode的scheme是用来管理和配置工程的编译、运行和调试环境的。每个工程都有一个或多个scheme,用来指定编译和运行时使用哪个target。Scheme可以帮助你配置调试环境,例如设置断点、设置环境变量、设置启动参数等。
删除scheme并不会对项目造成影响,但如果你删除了默认的scheme,在编译打包时就不会指定使用哪个target了,所以会导致编译或运行出错。
如果你使用Xcode的图形界面来编译和运行你的项目,那么删除scheme后是无法编译和运行的,因为Xcode需要一个scheme来确定编译和运行的目标。
但是,如果你使用Xcode的命令行工具来编译和运行你的项目,那么删除scheme后仍然可以编译和运行。
比如 使用 xcodebuild 命令可以在没有scheme的情况下编译和打包项目
1 | xcodebuild -target <targetName> -configuration <configuration> -sdk <sdk> |
同样的, 使用xcodebuild 命令也可以直接运行项目
1 | xcodebuild -target <targetName> -configuration <configuration> -sdk <sdk> run |
xcode中常用的快捷键有哪些?
Xcode是IOS开发的主要集成开发环境(IDE),它提供了许多常用的快捷键来帮助开发人员提高开发效率。
以下是一些常用的Xcode快捷键:
- Command + Shift + O: 快速打开文件
- Command + Shift + J: 快速打开跳转条
- Command + Shift + L: 快速打开查找对话框
- Command + R: 运行应用程序
- Command + .: 停止运行
- Command + B: 编译工程
- Command + Shift + K: 清除并编译工程
- Command + /: 注释/取消注释代码
- Command + Control + ↑/↓: 切换代码块
- Command + Option + ↑/↓: 向上/向下移动代码块
- Command + Option + Left/Right arrow : 在编辑器之间跳转
- Command + Shift + [ : 折叠代码
- Command + Shift + ] : 展开代码
- Command + Control + Click : 跳转到定义处
- Command + Option + Click : 在导航器中显示文件
- Command + Control + E : 显示/隐藏导航器
- Command + Control + Y : 显示/隐藏调试区
- Command + Control + Shift + Y : 显示/隐藏控制台
- Command + Shift + C : 显示代码覆盖率
总之,在Xcode中熟练使用快捷键可以帮助开发人员提高开发效率和降低维护成本。建议您每天使用这些快捷键来练习,直到它们变得熟练自然。
- 本文标题:2023年IOS面试题整理
- 本文作者:Madman
- 创建时间:2023-01-11 15:27:59
- 本文链接:https://www.patpat.site/开发/前端/2023年IOS面试题整理.html
- 版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!