iOSInterviewQuestions icon indicating copy to clipboard operation
iOSInterviewQuestions copied to clipboard

iTeaTime(技术清谈)【007期】【代号:蝙蝠侠】

Open ChenYilong opened this issue 6 years ago • 2 comments

iTeaTime(技术清谈)【007期】【代号:蝙蝠侠】

出题:微博@iOS程序犭袁 和他的小伙伴们 本期代号:蝙蝠侠

enter image description here

下列题目可能出现以下虚拟的程序员,非实指:

  • 小地
  • 大风哥
  • kengny 老师

【今日话题】如何看到小程序的跨平台方案,比如:美团App内置Flutter引擎容器可以跑微信小程序,DCloud出了跨平台uni-app方案,一次编写,导出多个小程序版本发布。还没京东也出了自己的跨平台方案。你是否看好这些平台?


1 【iOS】kengny 是一名产品经理,他平时有两大爱好:第一,到处在各类群里求买企业证书,第二,运营着一款小成本的视频 app,迫于成本压力,一般只会有两个人参演。他向大风哥提出需求,说希望能够在用户退到后台后,上传日志记录用户什么时候进入的后台,便于记录用户使用时长。并要求退到后台后依然能够下载小视频,这样用户上班点击下载按钮,回到家躺床上打开 APP 就能看了。并且要求把后台下载成功率定为大风哥的KPI。

如果你是大风哥,你将如何应对。必要时贴出示例代码。

【 难度🌟🌟🌟】【出题人 微博@iOS程序犭袁】


2【iOS】kengny 是一名产品经理,他们的 app 是一款类似美团的产品,最近他和一些店家进行了PY交易,要求用户到他们家店附近的时候,立即收到通知。 小地和大风哥,会上听到需求后,小地立即说:这个需求做不了。大风哥会上没说话,产品经理说,明天上线,怎么实现我不管,散会。

会后,大风哥悄悄说对小地说要做也可以,可以这样做:_______。

请补充填空,要求给出详细理由,包括技术实现细节,如有必要贴出示例代码。

【 难度🌟】【出题人 微博@iOS程序犭袁】


3【iOS】大风哥负责企业内部员工 APP 的iOS开发工作,产品经理 kengny 老师通知说,老板要求,发布2.0,对员工数据进行更新,在 iOS 原有数据库基础上,增加一个字段,用于记录用户 “是否是兄弟”。该字段只有老板有操作权限,如果打开APP后,发现不是兄弟,就弹出离职申请页面。服务端得知填写完成后,会发送指令要求手机原地爆炸。如果不能爆炸的话,远程删除APP,或将手机初始化也可以。

如果你是大风哥你将如何应对。要求数据库操作贴出示例代码,数据库类型不限。

【 难度🌟🌟🌟】【出题人 微博@iOS程序犭袁】


6【算法】请通过编程实现大数(亿位)的相加减乘除。(不限语言) 【 难度🌟🌟🌟】【出题人 消摇-金融-深圳iOSqp】


8 【iOS】CoreData中几个核心概念及关系阐述下,第三方库 MagicRecord 的读写操作是在什么线程中执行的?【 难度🌟🌟🌟】【出题人 微博@iOS程序犭袁】


9 【iOS】在一个字典中含有,字符串,字典,数组。层层嵌套,可能十几层。现在想知道任意节点Value中是否含有某个字符串。【 难度🌟🌟】【出题人 BM-成都iOS】


11 【iOS】多线程操作中,读写操作一定要在同一线程中执行吗?给出原因,并至少给出两种场景佐证你的观点,以及实现方法。【难度🌟🌟】【出题人 微博@iOS程序犭袁】


12 【iOS】一个app中可能会产生几个 Autorelease Pool , Autorelease Pool 中的临时对象,何时会被dealloc 。给出原因。【难度🌟🌟】【出题人 微博@iOS程序犭袁】


13 【iOS】For in 循环中频繁创建临时变量的场景下,如何使用 Autorelease Pool 优化, 着重讲下你放置pool的位置,以及这些临时变量的生命周期改变。并给出原因。【难度🌟🌟🌟】【出题人 微博@iOS程序犭袁】

14题 Autorelease Pool 方法走完了,才会对里面的临时对象做一次release操作,当临时对象引用计数为0时,才会dealloc 从后往前release


Posted by 微博@iOS程序犭袁
原创文章,版权声明:自由转载-非商用-非衍生-保持署名 | Creative Commons BY-NC-ND 3.0


One more thing...

【非礼勿视】以下为彩蛋部分,建议28岁以上男性观看


enter image description here

enter image description here

enter image description here

/one more thing/

ChenYilong avatar May 11 '19 09:05 ChenYilong

第7题

//
//  LRUCache.m
//  LRUCache
//
//  Created by JNC on 2019/5/11.
//  Copyright © 2019 JNC. All rights reserved.
//

#import "LRUCache.h"

@interface ItemNode : NSObject

@property(nonatomic, strong) id value;
@property(nonatomic, strong) ItemNode *next;
@property(nonatomic, weak)   ItemNode *prev;

- (instancetype)initWithValue:(id)value;

@end

@implementation ItemNode

- (instancetype)initWithValue:(id)value {
   if (self = [super init]) {
       _value = value;
       _next = nil;
       _prev = nil;
   }
   return self;
}

@end

@interface LRUCache ()

@property(nonatomic, assign) NSUInteger size;
@property(nonatomic, assign) NSUInteger capacity;
@property(nonatomic, strong) ItemNode *head;
@property(nonatomic, strong) ItemNode *tail;
@property(nonatomic, strong) NSMutableDictionary *dict;

@end

@implementation LRUCache

- (instancetype)initWithCapacity:(NSUInteger)capacity {
   if (self = [super init]) {
       _size = 0;
       _capacity = capacity;
       _head = [[ItemNode alloc] initWithValue:@"HEAD"];
       _tail = [[ItemNode alloc] initWithValue:@"TAIL"];
       _head.next = _tail;
       _tail.prev = _head;
       _dict = [[NSMutableDictionary alloc] init];
   }
   return self;
}

- (id)getItemForKey:(NSString *)key {
   ItemNode *item = [self.dict objectForKey:key];
   if (item) {
       item.prev.next = item.next;
       item.next.prev = item.prev;
       [self putToHead:item];
       return item.value;
   }
   return nil;
}

- (void)setItem:(id)item forKey:(NSString *)key {
   ItemNode *curItem = [self.dict objectForKey:key];
   if (item) {
       curItem.prev.next = curItem.next;
       curItem.next.prev = curItem.prev;
       curItem.value = item;
       [self putToHead:curItem];
       return;
   }
   
   ItemNode *anotherItem = [[ItemNode alloc] initWithValue:item];
   [self.dict setObject:anotherItem forKey:key];
   [self putToHead:anotherItem];
   if (++self.size > self.capacity) {
       ItemNode *deleteItem = self.tail.prev;
       deleteItem.prev.next = self.tail;
       self.tail.prev = deleteItem.prev;
       deleteItem = nil;
       --self.size;
   }
}

#pragma mark - Private

- (void)putToHead:(ItemNode *)item {
   item.next = self.head.next;
   self.head.next.prev = item;
   self.head.next = item;
   item.prev = self.head;
}

@end

jinnaichen avatar May 11 '19 11:05 jinnaichen

  • 第7题
struct FixedSizeArray<T> {
    
    /// FixedSizeArray begin https://github.com/raywenderlich/swift-algorithm-club/tree/master/Fixed%20Size%20Array
    private var maxSize: Int
    private var defaultValue: T
    private var array: [T]
    private (set) var count = 0
    
    init(maxSize: Int, defaultValue: T) {
        self.maxSize = maxSize
        self.defaultValue = defaultValue
        self.array = [T](repeating: defaultValue, count: maxSize)
    }
    
    subscript(index: Int) -> T {
        assert(index >= 0)
        assert(index < count)
        return array[index]
    }
    
    mutating func append(_ newElement: T) {
        assert(count < maxSize)
        array[count] = newElement
        count += 1
    }
    
    mutating func removeAt(index: Int) -> T {
        assert(index >= 0)
        assert(index < count)
        count -= 1
        let result = array[index]
        array[index] = array[count]
        array[count] = defaultValue
        return result
    }
    
    mutating func removeAll() {
        for i in 0..<count {
            array[i] = defaultValue
        }
        count = 0
    }
    
    /// FixedSizeArray end https://github.com/raywenderlich/swift-algorithm-club/tree/master/Fixed%20Size%20Array
    
    mutating func insert(_ value: T) -> Bool {
        var isRemove: Bool = false
        var dic: [Int: T] = [:]
        for i in 0..<count {
            dic[i] = array[i]
        }
        
        for i in 0..<count {
            if let t = dic[i] {
                if i+1 >= maxSize {
                    count -= 1
                    isRemove = true
                } else {
                    array[i+1] = t
                }
            }
        }
        array[0] = value
        count += 1
        return isRemove
    }
    
    mutating func putIndexToFirst(_ index: Int) {
        if (index > count || index >= maxSize) {
            print("index > count || index >= maxSize")
            return
        }
        let item = array[index]
        var dic: [Int: T] = [:]
        for i in 0...index {
            dic[i] = array[i]
        }
        for i in 0..<index {
            if let t = dic[i] {
                array[i+1] = t
            }
        }
        array[0] = item
    }
}

class LRUCache {
    
    var capacity: Int = 0
    var cache: [String: Int]? = nil
    var list: FixedSizeArray<Any>? = nil
    
    private var count: Int = 0
    
    func initWith(capacity: Int) {
        self.capacity = capacity
        self.list = FixedSizeArray(maxSize: capacity, defaultValue: "")
        self.cache = [:]
    }
    
    func set(item: Any, forKey: String) {
        if cache == nil || list == nil {
            print("cache or list is nil")
            return
        }
        
        if cache![forKey] != nil {
            if let index = cache![forKey] {
                list!.removeAt(index: index)
                cache!.removeValue(forKey: forKey)
            }
        }
        
        let isRemove = list!.insert(item)
        
        for (k, v) in cache! {
            cache![k] = v+1
        }
        
        if isRemove {
            var c = cache!
            for (k, index) in cache! {
                if index == capacity, let _ = c.removeValue(forKey: k) {
                    break
                }
            }
            cache = c
        }
        
        cache![forKey] = 0
    }
    
    func getItemFor(key: String) -> Any? {
        if let index = cache?[key], list != nil, index < capacity {
            list!.putIndexToFirst(index)
            
            var c = cache!
            var keys: [String] = []
            for _ in 0..<capacity {
                keys.append("")
            }
            for (k, v) in c {
                keys[v] = k
            }
            for i in 0..<index {
                if let v = cache![keys[i]] {
                    c[keys[i]] = v + 1
                }
            }
            c[keys[index]] = 0
            cache! = c
            
            return list![0]
        }
        return nil
    }
    
    func desc() {
        if list != nil {
            print("\(String(describing: list!))")
            print("\(cache ?? [:])")
            print("-----------------")
        }
    }
}

let c = LRUCache()
c.initWith(capacity: 3)

c.set(item: "A", forKey: "0A")
c.desc()
c.set(item: "C", forKey: "1C")
c.desc()
c.set(item: "B", forKey: "0B")
c.desc()
c.set(item: "D", forKey: "2D")
c.desc()
c.set(item: "E", forKey: "3E")
c.desc()

print("=============== 我是分割线 ===============")

let key2 = c.getItemFor(key: "2D")
print(key2 ?? "nil2")
c.desc()
let key1 = c.getItemFor(key: "1C")
print(key1 ?? "nil1")
c.desc()
let key0 = c.getItemFor(key: "0B")
print(key0 ?? "nil0")
c.desc()
let key4 = c.getItemFor(key: "3E")
print(key4 ?? "nil3")
c.desc()

输出:

FixedSizeArray<Any>(maxSize: 3, defaultValue: "", array: ["A", "", ""], count: 1)
["0A": 0]
-----------------
FixedSizeArray<Any>(maxSize: 3, defaultValue: "", array: ["C", "A", ""], count: 2)
["1C": 0, "0A": 1]
-----------------
FixedSizeArray<Any>(maxSize: 3, defaultValue: "", array: ["B", "C", "A"], count: 3)
["0B": 0, "1C": 1, "0A": 2]
-----------------
FixedSizeArray<Any>(maxSize: 3, defaultValue: "", array: ["D", "B", "C"], count: 3)
["0B": 1, "1C": 2, "2D": 0]
-----------------
FixedSizeArray<Any>(maxSize: 3, defaultValue: "", array: ["E", "D", "B"], count: 3)
["0B": 2, "3E": 0, "2D": 1]
-----------------
=============== 我是分割线 ===============
D
FixedSizeArray<Any>(maxSize: 3, defaultValue: "", array: ["D", "E", "B"], count: 3)
["0B": 2, "3E": 1, "2D": 0]
-----------------
nil1
FixedSizeArray<Any>(maxSize: 3, defaultValue: "", array: ["D", "E", "B"], count: 3)
["0B": 2, "3E": 1, "2D": 0]
-----------------
B
FixedSizeArray<Any>(maxSize: 3, defaultValue: "", array: ["B", "D", "E"], count: 3)
["0B": 0, "3E": 2, "2D": 1]
-----------------
E
FixedSizeArray<Any>(maxSize: 3, defaultValue: "", array: ["E", "B", "D"], count: 3)
["0B": 1, "3E": 0, "2D": 2]
-----------------

Jonhory avatar May 13 '19 16:05 Jonhory