安卓面试题到处攒,一到面试就忘个干净?来看看这份超详细的整理( 六 )


@MainThreadprotected void setValue(T value) {assertMainThread("setValue");mVersion++;mData = https://www.isolves.com/it/cxkf/cxy/2020-12-22/value;dispatchingValue(null);}private void dispatchingValue(@Nullable ObserverWrapper initiator) {//...do {mDispatchInvalidated = false;if (initiator != null) {considerNotify(initiator);initiator = null;} else {for (Iterator, ObserverWrapper>> iterator =mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {considerNotify(iterator.next().getValue());if (mDispatchInvalidated) {break;}}}} while (mDispatchInvalidated);mDispatchingValue = false;}private void considerNotify(ObserverWrapper observer) {if (!observer.mactive) {return;}// Check latest state b4 dispatch. Maybe it changed state but we didn't get the event yet.//// we still first check observer.active to keep it as the entrance for events. So even if// the observer moved to an active state, if we've not received that event, we better not// notify for a more predictable notification order.if (!observer.shouldBeActive()) {observer.activeStateChanged(false);return;}if (observer.mLastVersion >= mVersion) {return;}observer.mLastVersion = mVersion;//noinspection uncheckedobserver.mObserver.onChanged((T) mData);}这一套下来逻辑还是比较简单的,遍历刚才的map——mObservers,然后找到观察者observer,如果观察者不在活跃状态(活跃状态,也就是可见状态,处于 STARTED 或 RESUMED状态),则直接返回,不去通知 。否则正常通知到观察者的onChanged方法 。
当然,如果想任何时候都能监听到,都能获取回调,调用observeForever方法即可 。
15、说说DNS,以及存在的问题DNS用来做域名解析工作的,当输入一个域名后,需要把域名转化为IP地址,这个转换过程就是DNS解析 。
但是传统的DSN解析会有一些问题,比如:

  • 域名缓存问题本地做一个缓存,直接返回缓存数据 。可能会导致全局负载均衡失败,因为上次进行的缓存,不一定是这次离客户最近的地方,可能会绕远路 。
  • 域名转发问题如果是A运营商将解析的请求转发给B运营商,B去权威DNS服务器查询的话,权威服务器会认为你是B运营商的,就返回了B运营商的网站地址,结果每次都会跨运营商 。
  • 出口NAT问题做了网络地址转化后,权威的DNS服务器,没法通过地址来判断客户到底是哪个运营商,极有可能误判运营商,导致跨运营商访问 。
  • 域名更新问题本地DNS服务器是由不同地区,不同运营商独立部署的,对域名解析缓存的处理上,有区别,有的会偷懒忽略解析结果TTL的时间限制,导致服务器没有更新新的ip而是指向旧的ip 。
  • 解析延迟DNS的查询过程需要递归遍历多个DNS服务器,才能获得最终结果 。可能会带来一定的延时 。
  • 域名劫持DNS域名解析服务器有可能会被劫持,或者被伪造,那么正常的访问就会被解析到错误的地址 。
  • 不可靠由于DNS解析是运行在UDP协议之上的,而UDP我之前也说过是一种不可靠的协议,他的优势在于实时性,但是有丢包的可能 。
这些问题不仅会让访问速度变慢,还有可能会导致访问异常,访问页面被替换等等 。
16、怎么优化DNS解析安全优化
总之DNS还是会有各种问题吧,怎么解决呢?就是用HTTPDNS 。
HTTPDNS是一个新概念,他会绕过传统的运营商DNS服务器,不走传统的DNS解析 。而是换成HTTP协议,直接通过HTTP协议进行请求某个DNS服务器集群,获取地址 。
  • 由于绕过了运营商,所以可以避免域名被劫持 。
  • 它是基于访问的来源ip,所以能获得更准确的解析结果
  • 会有预解析,解析缓存等功能,所以解析延迟也很小
所以首先的优化,针对安全方面,就是要替换成HTTPDNS解析方式,就要借用阿里云和腾讯云等服务,但是这些服务可不是免费的,有没有免费的呢?有的,七牛云的 happy-dns 。添加依赖库,然后去实现okhttp的DNS接口即可,简单写个例子:
@MainThreadprotected void setValue(T value) {assertMainThread("setValue");mVersion++;mData = https://www.isolves.com/it/cxkf/cxy/2020-12-22/value;dispatchingValue(null);}private void dispatchingValue(@Nullable ObserverWrapper initiator) {//...do {mDispatchInvalidated = false;if (initiator != null) {considerNotify(initiator);initiator = null;} else {for (Iterator, ObserverWrapper>> iterator =mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {considerNotify(iterator.next().getValue());if (mDispatchInvalidated) {break;}}}} while (mDispatchInvalidated);mDispatchingValue = false;}private void considerNotify(ObserverWrapper observer) {if (!observer.mActive) {return;}// Check latest state b4 dispatch. Maybe it changed state but we didn't get the event yet.//// we still first check observer.active to keep it as the entrance for events. So even if// the observer moved to an active state, if we've not received that event, we better not// notify for a more predictable notification order.if (!observer.shouldBeActive()) {observer.activeStateChanged(false);return;}if (observer.mLastVersion >= mVersion) {return;}observer.mLastVersion = mVersion;//noinspection uncheckedobserver.mObserver.onChanged((T) mData);}


推荐阅读