Skip to content

Latest commit

 

History

History
163 lines (117 loc) · 9.42 KB

10美团饿了么面试题2018年4月.md

File metadata and controls

163 lines (117 loc) · 9.42 KB

美团饿了么面试题2018年4月

备注:原作者分享几个

自实现pow(double, double)

参考内容
```
func _pow_3(_ base: Double, _ exponent: Int) -> Double {

    var isNegative = false
    var exp = exponent
    if exp < 0 {
        isNegative = true
        exp = -exp
    }
    let result = _pow_2(base, exp)
    return isNegative ? 1 / result : result
}

```

findMedianSortedArrays (找到两个排序数组的中位数)

参考内容

func findMedianSortedArrays_3(_ array1: [Int], _ array2: [Int]) -> Double {
    
    let total = array1.count + array2.count
    let index = total / 2
    let count = array1.count < array2.count ? array2.count : array1.count
    var array = [Int]()
    
    var i = 0, j = 0;
    for _ in 0...count {
        if array.count >= index + 1 {
            break
        }
        if array1[i] < array2[j] {
            array.append(array1[i])
            i += 1
        } else {
            array.append(array2[j])
            j += 1
        }
    }
    return total % 2 == 1 ? Double(array[index]) : Double(array[index] + array[index - 1]) * 0.5
}

UIContorl -> UIButton

参考内容
  • UIButton setTitle的时候才会创建UILabel, setImage的时候才会创建UIImageView, 你为什么吧frame给写死... 不知道UIView有sizeToFit么, 你怎么不实现sizeThatFits, 你是完全不会用吧... 你知道UIButton用AutoLayout布局的时候只要设置origin坐标, 宽高就可以自适应了, 你自定义的时候怎么不实现呢? setBackgroundImage和setImageEdgeInsets

import UIKit protocol ButtonInterface { func setTitle(_ title: String); func setTitleColor(_ titleColor: UIColor); func setTitleEdgeInsets(_ edgeInsets: UIEdgeInsets); func setImage(_ image: UIImage); func setBackgroundImage(_ image: UIImage); func setImageEdgeInsets(_ edgeInsets: UIEdgeInsets);
} class Button: UIControl, ButtonInterface { lazy var titleLabel: UILabel = UILabel() lazy var imageView: UIImageView = UIImageView() lazy var backgroundImageView: UIImageView = UIImageView() var titleLabelIsCreated = false var imageViewIsCreated = false var backgroundImageViewCreated = false internal func setTitle(_ text: String) { if !titleLabelIsCreated {
            addSubview(titleLabel)
            titleLabelIsCreated = true }
        titleLabel.text = text
    } internal func setTitleColor(_ textColor: UIColor) { if !titleLabelIsCreated { return }
        titleLabel.textColor = textColor
    } internal func setTitleEdgeInsets(_ edgeInsets: UIEdgeInsets) { if !titleLabelIsCreated { return }
    } internal func setImage(_ image: UIImage) { if !imageViewIsCreated {
            addSubview(imageView)
            imageViewIsCreated = true }
        imageView.image = image
    } internal func setBackgroundImage(_ image: UIImage) { if !backgroundImageViewCreated {
            addSubview(backgroundImageView)
            insertSubview(backgroundImageView, at: 0)
            backgroundImageViewCreated = true }
        backgroundImageView.image = image
    } internal func setImageEdgeInsets(_ edgeInsets: UIEdgeInsets) { if !imageViewIsCreated { return }
    } override func sizeThatFits(_ size: CGSize) -> CGSize { if titleLabelIsCreated && !imageViewIsCreated && !backgroundImageViewCreated { let text: NSString? = titleLabel.text as NSString? let titleLabelW: CGFloat = text?.boundingRect(with: CGSize(width: CGFloat(MAXFLOAT), height: bounds.height), options: NSStringDrawingOptions.usesLineFragmentOrigin, attributes: [NSAttributedStringKey.font : titleLabel.font], context: nil).size.width ?? 0.0 let titleLabelH: CGFloat = text?.boundingRect(with: CGSize(width: titleLabelW, height: CGFloat(MAXFLOAT)), options: NSStringDrawingOptions.usesLineFragmentOrigin, attributes: [NSAttributedStringKey.font : titleLabel.font], context: nil).size.height ?? 0.0 return CGSize(width: titleLabelW, height: titleLabelH + 10)
        } else if !titleLabelIsCreated && imageViewIsCreated { return imageView.image?.size ?? CGSize.zero
        } else if titleLabelIsCreated && imageViewIsCreated { let text: NSString? = titleLabel.text as NSString? let titleLabelW: CGFloat = text?.boundingRect(with: CGSize(width: CGFloat(MAXFLOAT), height: bounds.height), options: NSStringDrawingOptions.usesLineFragmentOrigin, attributes: [NSAttributedStringKey.font : titleLabel.font], context: nil).size.width ?? 0.0 let titleLabelH: CGFloat = text?.boundingRect(with: CGSize(width: titleLabelW, height: CGFloat(MAXFLOAT)), options: NSStringDrawingOptions.usesLineFragmentOrigin, attributes: [NSAttributedStringKey.font : titleLabel.font], context: nil).size.height ?? 0.0 let imageViewW: CGFloat = imageView.image?.size.width ?? 0.0 let imageViewH: CGFloat = imageView.image?.size.height ?? 0.0 return CGSize(width: titleLabelW + imageViewW, height: imageViewH > titleLabelH ? imageViewH : titleLabelH)
        } else { return backgroundImageView.image?.size ?? CGSize.zero
        }
    } override func layoutSubviews() { super.layoutSubviews() if titleLabelIsCreated && !imageViewIsCreated {
            titleLabel.frame = bounds
            titleLabel.textAlignment = .center
        } else if !titleLabelIsCreated && imageViewIsCreated { let y: CGFloat = 0; let width: CGFloat = imageView.image?.size.width ?? 0; let x: CGFloat = (bounds.width - width) * 0.5; let height: CGFloat = bounds.height;
            imageView.frame = CGRect(x: x, y: y, width: width, height: height)
        } else if titleLabelIsCreated && imageViewIsCreated { let imageViewY: CGFloat = 0; let imageViewW: CGFloat = imageView.image?.size.width ?? 0; let imageViewH: CGFloat = bounds.height; let text: NSString? = titleLabel.text as NSString? let titleLabelW: CGFloat = text?.boundingRect(with: CGSize(width: CGFloat(MAXFLOAT), height: bounds.height), options: NSStringDrawingOptions.usesLineFragmentOrigin, attributes: [NSAttributedStringKey.font : titleLabel.font], context: nil).size.width ?? 0.0 let titleLabelH: CGFloat = text?.boundingRect(with: CGSize(width: titleLabelW, height: CGFloat(MAXFLOAT)), options: NSStringDrawingOptions.usesLineFragmentOrigin, attributes: [NSAttributedStringKey.font : titleLabel.font], context: nil).size.height ?? 0.0 let imageViewX: CGFloat = (bounds.width - imageViewW - titleLabelW) * 0.5; let titleLabelX: CGFloat = imageViewX + imageViewW let titleLabelY = (bounds.height - titleLabelH) * 0.5 titleLabel.frame = CGRect(x: titleLabelX, y: titleLabelY, width: titleLabelW, height: titleLabelH)
            imageView.frame = CGRect(x: imageViewX, y: imageViewY, width: imageViewW, height: imageViewH)
        } if backgroundImageViewCreated {
            backgroundImageView.frame = bounds
        }
    }
}

网络框架

参考内容

可以参考YTKNetworking 或者AFN

  • 设计一个网络框架, 如何进行不同数据解析的设计(header, body), 并能够进行自定义

  • 重连机制如何处理, 状态码错误转发机制的处理

  • 如何避免回调地狱, 实现Promise的自实现.

网络接口规范

  • 两层三部分数据结构

多服务器多环境设置

  • 标准的APP是有4个环境的,开发、测试、预发、正式,

网络层数据传递(请求和返回)

  • Client做两个操作,一个是生成NSURLRequest,一个是生成NSURLSessionDataTask并发起,另外还要暴露取消操作给Engine,

业务层对接方式

  • casa:集约型API调用其实就是所有API的调用只有一个类,然后这个类接收API名字,API参数,以及回调着陆点(可以是target-action,或者block,或者delegate等各种模式的着陆点)作为参数。然后执行类似startRequest这样的方法,它就会去根据这些参数起飞去调用API了,然后获得API数据之后再根据指定的着陆点去着陆。

网络请求怎么自动取消

  • casa思路:在BaseDataEngine的dealloc里面做取消网络请求操作,把BaseDataEngine绑定给ViewController,当ViewController销毁时BaseDataEngine也就跟着销毁了
  • 每个接口生成一个BaseEngine实例,持有Client返回的requestID,所以就可以做取消操作,简单的使用场景

网络层错误处理

我们将错误处理分为两个步骤,一个是错误解析,一个是错误的UI展示

  • 设计的接口返回数据是标准的id data, NSError *error,是Client就把error处理好,不管你是网络超时错误也好,或者是数据格式不正确也好,都error解析完整,把code错误码定义好,上层根据需要通过code来做具体的UI展示,因为有的界面的错误需要用户的点击确认,有的页面的错误只是一闪而过的提示框,把error交给BaseEngine或者DataEngine来处理errorUI,

  • 定义了一套errorUI的枚举,当BaseEngine拿到error的时候就去做错误的展示

觉得整理的蛮不错,可以赞赏一下旺仔(收集整理不易,且赞且珍惜)

链接