iOS技术点

Swift 基本技术点(面试)

2019-08-06  本文已影响0人  zhang_jk

1.什么是函数式编程

函数式编程其实是一种编程思想, 代码写出来只是它的表现形式

在面向对象的编程思想中, 我们将要解决的一个个问题, 抽象成一个个类, 通过给类定义属性和方法, 让类帮助我们解决需要处理的问题.(其实面向对象也叫命令式编程, 就像给对象下一个个命令)

而在函数式编程中, 我们则通过函数描述我们要解决的问题, 以及解决问题需要怎样的方案.

RxSwift

2.swif相对于OC有哪些优点

1、swift语法简单易读、代码更少,更加清晰、易于维护

2、更加安全,optional的使用更加考验程序员对代码安全的掌控

3、泛型、结构体、枚举都很强大

4、函数为一等公民,便捷的函数式编程

5、有命名空间 基于module

6、类型判断

oc的优点、运行时

什么是泛型,swift哪些地方使用了泛型?

泛型(generic)可以使我们在程序代码中定义一些可变的部分,在运行的时候指定。使用泛型可以最大限度地重用代码、保护类型的安全以及提高性能。

例如 optional 中的 map、flatMap 、?? (泛型加逃逸闭包的方式,做三目运算)

defer 、guard的作用?

defer 包含中的内容一定会在离开作用域的地方执行
guard 过滤器,拦截器

swift 语法糖 ? !的本质(实现原理)

?为optional的语法糖
optional<T> 是一个包含了nil 和普通类型的枚举,确保使用者在变量为nil的情况下处理

!为optional 强制解包的语法糖

swift中模式匹配的作用?

for case let: for case let x in array where x > 10 {} 或者 for x in array where x > 10

swift中的closure于OC中block的区别?

什么是capture list,举例说明用处?

swift中private与fileprivate的区别?

Set 独有的方法有哪些?

实现一个min 函数

func minNum(a: T, b: T) -> T { return a > b ? a : b }

map、filter、reduce 的作用

1.map 是Array类的一个方法,我们可以使用它来对数组的每个元素进行转换
let intArray = [1, 3, 5]
let stringArr = intArray.map {
            return "\($0)"
        }
// ["1", "3", "5"]


2.filter 用于选择数组元素中满足某种条件的元素
let filterArr = intArray.filter {
    return $0 > 1
}
//[3, 5]
3.reduce 把数组元素组合计算为一个值
let result = intArray.reduce(0) {
    return $0 + $1
}

map 和flatMap的区别

1、map 可以对一个集合类型的所有元素做一个映射操作
 
2、和map 不同,flatmap 在之前版本有两个定义,分别是:
func flatMap(transform: (Self.Generator.Element) throws -> T?) -> [T]
func flatMap(transform: (Self.Generator.Element) -> S) -> [S.Generator.Element]
 
swift 4.1 废弃后改为
 
func flatMap(transform: (Self.Generator.Element) throws -> Sequence) -> [Sequence.Element]
func flatMap(_ transform: (Wrapped) throws -> U?) rethrows -> U?
 
1) flatMap的第一个作用和map一样,对一个集合类型的所有元素做一个映射操作,但是可以过滤为nil的情况
 
例如:
let array = [1,2,5,6,7,nil]
let array_map = array.map { $0 }
//[Optional(1), Optional(2), Optional(5), Optional(6), Optional(7), nil]
let array_flatmap = array_map.flatMap { $0 }
//[1, 2, 5, 6, 7]
 
2) 第二种情况可以进行“降维”操作
 
let array = [["1", "2"],["3", "4"]]
let array_map = array.map { $0 }
//[["1", "2"], ["3", "4"]]
let array_flatmap = array_map.flatMap { $0 }
//["1", "2", "3", "4"] 

什么是copy on write

copy on write, 写时复制,简称COW,它通过浅拷贝(shallow copy)只复制引用而避免复制值;当的确需要进行写入操作时,首先进行值拷贝,在对拷贝后的值执行写入操作,这样减少了无谓的复制耗时。

如何获取当前代码的函数名和行号

#function
#line
#file
#column

如何声明一个只能被类conform的protocol

protocol:class

String 与NSString的关系与区别

如何截取String的某段字符串

        let str = "how to substring js func"
        let star = str.index(str.startIndex, offsetBy: 0)
        let end = str.index(str.startIndex, offsetBy: 4)
        let substr = str[star..<end]
        print(substr)

throws 和 rethrows的用法与作用

try? 和 try!是什么意思

associatedtype 的作用


protocol TableViewCell {
    associatedtype T
    func updateCell(_ data: T)
}

struct Model {
    var name:String

}
class MyTableViewCell: UITableViewCell, TableViewCell {
    typealias T = Model
    func updateCell(_ data: Model) {
        // do something
    }
}

public 和 open 的区别

public 修饰符

修饰的属性或者方法可以在其他作用域被访问
但不能在重载 override 中被访问
也不能在继承方法中的 Extension 中被访问

open 修饰符

open 其实就是过去的 public,过去 public 有两个作用:

修饰的属性或者方法可以在其他作用域被访问
修饰的属性或者方法可以在其他作用域被继承或重载 override

private、fileprivate、public、open修饰符的作用和区别

1、private 修饰符

只允许在当前类中调用,不包括 Extension
private 现在变为了真正的私有访问控制
用 private 修饰的方法不可以被代码域之外的地方访问

2、fileprivate 修饰符

fileprivate 其实就是过去的 private。
其修饰的属性或者方法只能在当前的 Swift 源文件里可以访问。
即在同一个文件中,所有的 fileprivate 方法属性都是可以访问到的。


class TKBase: NSObject {
    func showTest()  {
        testB()
    }
}

fileprivate func testA() {
    print("test")
}

fileprivate func testB() {
    print("testB")
}

class A: NSObject {
    fileprivate func testA() {
        print("test")
    }

    fileprivate func testB() {
        print("testB")
    }
}

class B: NSObject {
    func show() {
        testA()
    }


}

5、internal修饰符

从高到低排序如下:
open > public > interal > fileprivate > private

声明一个只有一个参数没有返回值闭包的别名

typealias MyBlock = (Int) -> (Void)

Self 的使用场景

dynamic 的作用

什么时候使用@objc

与OC 的交互部分
KOV 监听、动态方法查找等都需要
协议可选方法等

Optional (可选型)是用什么实现的

枚举 一个为nil,一个为属性值

如何自定义下标获取

class Demo: NSObject {

}

extension Demo {
    subscript(index: Int) -> Int {
        get {
            // 返回一个适当的 Int 类型的值
            return 9
        }
        set(newValue) {
            // 执行适当的赋值操作
        }
    }
}

inout 的作用

让输入参数可变 类似__block的作用

Error 如果要兼容NSError需要做什么操作

Error是一个协议, swift中的Error 都是enum, 可以转 NSError
如果需要Error有NSError的功能,实现 LocalizedError CustomNSError 协议

下面代码都用了哪些语法糖

[1, 2, 3].map{ $0 * 2 }

array语法糖
尾部闭包语法糖
$0

什么是高阶函数

map、flatMap、filter、reduce?

下面的代码会不会崩溃,说出原因

        var mutableArray = [1,2,3]
        for _ in mutableArray {
            mutableArray.removeLast()
        }
不会,因为是值类型

给集合中元素是字符串的类型增加一个扩展方法,应该怎么声明

extension Array where Element == String {}

定义静态方法时关键字 static 和 class 有什么区别

非class类型 一般 统一用 static  例如  枚举 结构体
protocol中 使用 static ,实现协议的 枚举 结构体 用 static
class 中使用  class static 都可以

一个 Sequence 的索引是不是一定从 0 开始?

<br>

数组都实现了哪些协议

Decodable Encodable Equatable Hashable  CustomStringConvertible, CustomDebugStringConvertible RandomAccessCollection, MutableCollection RangeReplaceableCollection CustomReflectable ExpressibleByArrayLiteral

如何自定义模式匹配

infix operator =~
 
func =~ (str: String, pattern: String) -> Bool {
 
     
}
infix、  prefix、  postfix  用于自定义表达式的声明, 分别表示 中缀、前缀、后缀

autoclosure 的作用

自动闭包,将参数自动封装为闭包参数

下面代码中 mutating 的作用是什么

struct Person {
 
    var name: String {
        mutating get {
            return store
        }
    }
}
结构体中的 属性可能发生改变

如何让自定义对象支持字面量初始化

ExpressibleByArrayLiteral
ExpressibleByStringLiteral

为什么数组索引越界会崩溃,而字典用下标取值时 key 没有对应值的话返回的是 nil 不会崩溃。

struct Array {
    subscript(index: Int) -> Element
}
 
struct Dictionary {
    subscript(key: Key) -> Value?
}

一个函数的参数类型只要是数字(Int、Float)都可以,要怎么表示

Int、Float 都有一个协议
 
func myMethod(_ value: T) where T: Numeric {
    print(value + 1)
} 
 
或者 ExpressibleByIntegerLiteral 协议也行

Swift的静态派发

很显然静态派发是一种更高效的方法,因为静态派发免去了查表操作。

不过静态派发是有条件的,方法内部的代码必须对编译器透明,并且在运行时不能被更改,这样编译器才能帮助我们。

Swift 中的值类型不能被继承,也就是说值类型的方法实现不能被修改或者被复写,因此值类型的方法满足静态派发的要求。

默认静态派发,如果需要满足动态派发,需要 dymanic修饰

swift 有哪些修饰符

open、public 、internal、fileprivate、private

实现一个函数,输入任意一整数,输入要返回输入的整数 + 2

func plusTwo(one: Int) -> (Int) -> Int {
    return { (two: Int) in return two + one }
}

plusTwo(one: 4)(2)

Swift 到底是面向对象还是函数式的编程语言?

Swift 既是面向对象的,又是函数式的编程语言。
说 Swift 是 Object-oriented,是因为 Swift 支持类的封装、继承、和多态,从这点上来看与 Java 这类纯面向对象的语言几乎毫无差别。
说 Swift 是函数式编程语言,是因为 Swift 支持 map, reduce, filter, flatmap 这类去除中间状态、数学函数式的方法,更加强调运算结果而不是中间过程。
上一篇 下一篇

猜你喜欢

热点阅读