iTeaTime(技术清谈)【007期】【代号:蝙蝠侠】
iTeaTime(技术清谈)【007期】【代号:蝙蝠侠】
出题:微博@iOS程序犭袁 和他的小伙伴们 本期代号:蝙蝠侠

下列题目可能出现以下虚拟的程序员,非实指:
- 小地
- 大风哥
- 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岁以上男性观看



/one more thing/
第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
- 第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]
-----------------
