This is my thrid blog web site.

0%

About Android 2 进入Application

上一篇总结(抄)了Android从开机到启动桌面的过程,接下来从Launcher展开。

  • 启动application过程
  • 启动Activity
  • activity启动模式

启动Application

在ActivityThread的main方法中创建了一个主线程Looper并开启循环。
在Looper.loop()之前,会创建一个ActivityThread对象并attach(false)

在attach内部,会获取mgr.attachApplication(mAppThread).
mgr是一个IBinder引用,其实也是ActivityManagerService的引用

在attachApplication内会调用attachApplicationLocked(thread, callingPid)
然后thread.bindApplication(…)
后续会在ActivityStackSupervisor.attachApplicaiontLocked(app)
=> realStartActiviityLocked()

bindApplication最终会sendMessage到一个handler

该handler内对bindapplication做出响应

  • 创建Application
    • ContextImpl.createAppContext(activityThread, this)
    • app = ..newApplicaiton(cl,appClass,appContext)
      • app.attach(context)
    • setOutterContext(app)
  • mInstrumenttation.callApplicationOnCreate(app)

启动Activity

startActivity通过Instrumentation来启动activity

  • startActivity
  • startActivityForResult
  • instrumentation.executeStartActivity
    • ActivityManager.getService().startActivity

ActivityManagerService中

  • getService()
  • startActivity()
  • startActivityAsUser()
  • ActivityStartController.obtainStarter.xxxx.execute()

ActivityStarter中

  • 拿到ActivityRecord
  • 判断启动模式
  • Application

activity启动模式

  • Android启动模式和场景
    • singleInstance 全局唯一
      • oncreate
      • onnewintent onrestart onstart
    • singleStack 已处于栈内 复用并弹出上层
    • singleTop 已处于栈内时复用
    • standard
1
2
3
4
5
一般会问一些简单的题,例如

栈[A,B,C]

用不同的模式启动A会发生什么变化

参考
1
2

about Android 1 启动到桌面

  • 启动系统
    • 开机键
      • 引导芯片加载BootLoader到内存,拉起Linux OS, 寻找init.rc启动init进程
      • init进程
        • 启动Zygote进程
          • 启动java虚拟机
          • jni
          • 找到ZygoteInit类调用main
      • Zygote
        • 通过fork复制进程来创建应用进程和SystemServer进程
        • 启动时会创建DVM获ART
        • main
          • 创建socket
          • 预加载
          • 启动SystemServer
          • 等待AMS请求
      • SystemServer
        • 用于创建系统服务
          • AMS
          • WMS
          • PMS
        • PathClassLoader
        • 启动binder线程池

AMS

  • SystemServer
    • 获取Context
      • 构造ActivityThread
        • thead.attach(true)
          • if (true)
            • setAppName system_process
            • 从systemContext的packageInfo获取对象然后makeApplication
            • application.onCreate
      • 取得ActivityThread实例的context
  • 启动各种Service
    • 启动AMS
      • newInstance ActivityManagerService
      • add service对象到mServices
      • service.onStart()
  • AMS onStart()
    • start()
    • systemReady()
      • startHomeActivityLocked
        • getHomeIntent
        • ActivityStartController.startHomeActivity
          • ActivityStarter
            • execute
      • 进行操作
      • mStackSupervisor.resumeTopActivitiesLocked()

HomeActivity

在 systemReady 后启动HomeActivity

  • 怎么启动HomeActivity
    • 通过flag 常量 XXXX_HOME

启动Activity

  • 启动组件的方式
    • 显式启动
    • 隐式启动
  • Activity 启动模式

启动方式

显式启动

1
2
3
4
5
6
7
Intent intent = new Intent(AActivity.this,BActivity.class);
startActivity(intent);

Intent intent2 = new Intent();
intent2.setClassName("","");
startActivity(intent2);
//需要在对应AndroidManifest.xml内设置exported = true

隐式启动
即通过IntentFilter寻找

  • action
  • category

AMS收到StartActivity请求,匹配组件action,检查category,检查数据,启动组件并传入数据

HomeActivity做了什么

也就是Launcher做了什么

  • 获取已安装的apk信息
  • 显式已安装的apk信息并响应点击事件

参考:
1
2
3

CSS相关

CSS其实用得不深, 常规布局就已经满足了我接触到的需求了

  • 盒模型
    • content border padding margin
  • box-sizing

  • 选择器
    • id
    • 标签
    • 相邻选择器
      • xxx
    • 子选择器
    • 后代选择器
    • 通配符
    • 属性选择器
      • xxx
    • 伪类选择器
  • 可继承属性
    • font-szie
    • font-family
    • color
  • css3新增伪类
  • 居中div
    • margin auto
    • 浮动元素
      • xxx
    • 绝对定位
      • xxx

        flex-direction: column;
        justify-content: center;
        align-items: center;

Java 多态的实现原理

java方法调用依赖于方法表。
没有太细节。后续可以考虑补充

类引用调用和接口引用调用

类引用调用

jvm class文件调用方法的符号引用,然后在静态类型的方法表中找到偏移量,找不到就在父类中找

  • 方法区
    • 类型信息
      • 方法表

设计模式

设计模式的相关复习。 先把我用过的设计模式梳理一下

单例模式

很常见

Java 实现单例的方法有很多

JavaScript呢?

工厂模式

没怎么用,有用到过。
在Android中生成部分对象时. 主要是interface, 然后根据不同的条件Factory类返回Interface的不同实现Class

抽象工厂

工厂是一个抽象类,用Producer类生成工厂类实现类

建造者模式

Builder

原型模式

实现clone ,存入数据库, 从数据库取出时使用clone()

Adapter

观察者模式

Subject

Observer

Java String

  • String
  • StringBuffer
  • StringBuilder

String

  • 修改会创建新变量

StringBuffer

  • 线程安全
  • 执行速度慢

StringBuilder

  • 线程不安全
  • 执行速度快

HTTP

HTTP 超文本传输协议

HTTP

HTTPS

  • 客户端请求https
  • 服务端返回证书
  • 客服端生成秘钥,并用证书公钥进行加密
  • 服务端解密,获取秘钥

HTTP 状态码

  • 1 通知
    • 100
    • 101
    • 102
  • 2xx 成功
    • 200 成功 OK
    • 201
    • 202
    • 203
    • 204 响应头没有body数据
    • 205
    • 206 断点续传
  • 3xx 重定向
    • 300
    • 301
      • Moved Permanently
    • 302
    • 303
    • 304
      • Not Modified
      • 相应实体主体为空
      • 客户端已有数据,没必要重复发生
    • 305
  • 4 客户端错误
    • 400 Bad Request
    • 401 Unauthorized
    • 403 Forbidden
    • 404 Not found
    • 409 COnflict
    • 410 Gone
  • 5 服务端错误
    • 500
      • Internal Server Error
    • 502 bad gateway

Java 与JavaScript 的内存泄漏和内存溢出

内存泄漏 memory leak

申请内存后无法释放已申请的内存空间

内存溢出 out of memory

申请内存时,没有足够的内存空间可以使用

java中

  • java内存回收机制

  • java内存泄漏原因

  • 引用

    • 强引用
    • 软引用
      • 内存不足时回收
    • 弱引用
      • 扫描时回收
    • 虚引用
      • 形同虚设

java内存回收机制

java中的内存主要指jvm虚拟机中的内存。通常一个java对象是被new或者通过放射的方式创建的。如果创建的是基础类型对象,则先在常量池中寻找,如果常量池中没有相对应得变量,则创建,然后栈中创建引用指向常量池

java内存泄漏原因

  • 静态类集合类引起内存泄漏
  • 结合内对象hash不同后remove不起作用
  • 监听器没有remove
  • 各种连接
  • 单例模式

    JavaScript中

  • 垃圾回收机制
  • 内存泄漏的识别方法
  • 命令行查看
  • WeakMap

垃圾回收机制

引用计数

内存泄漏识别

  • 经验法则
    • 连续5次gc, 内存占用一次比一次大
  • 浏览器
  • 命令行 process.memoryUsage

WeakMap

ES^ 新数据结构

  • WeakSet
  • WeakMap
1
2
3
4
5
6
const wm = new WeakMap();

const element = document.getElementById('example');

wm.set(element, 'some information');
wm.get(element) // "some information"

##异同

参考
1

TCP

  • 滑动窗口 (流量控制)
  • 拥塞控制
    • 拥塞避免算法
  • 网络模型
  • 3次握手
  • 4次挥手
    • timeout

滑动窗口

  • Client
    • send ack
    • send not ACK
    • not send, ready to receive
    • not send, not ready to receive
  • Server
    • rec, ack, not send to process
    • rec not ACK
    • not rec

拥塞控制

防止过多数据注入到网络,可以使网络中的路由器或链路不过载

常用方法

  • 慢开始, 拥塞控制
  • 快重传,快恢复

慢开始 慢启动

  • 发送方维持一个 拥塞窗口, 拥塞窗口和接收方共同决定发送窗口
  • 先发送1字节的试探报文
  • 当收到第一个字节的确认后,发送2字节报文
  • 2 ack, send 4 bit data. 2^n
  • 达到慢开始门限
    • cwnd < ssthresh 慢开始算法
    • cwnd > ssthresh ,停止慢开始算法,改用拥塞避免算法
    • cwnd = ssthresh 都可以

拥塞避免算法

  • 每经过一个往返时间rtt则把发送方拥塞窗口+1
  • 网络拥塞时(李儒丢包),
    • 慢开始门限设为原先一半
    • cwnd = 1
    • 执行慢开始算法

快重传 快回复

  • 快重传
    • 接收方 丢失包
      • 后续包继续发送针对该包的重传请求
    • 发送方
      • 接收到3个一样的确认 就知道该包出现错误,立刻重传该包
  • 快恢复
    • 慢开始门限减半
    • cwnd设为门限减半后的数值
    • 拥塞避免算法(高起点,线性增长)

网络模型

OSI模型

  • 应用层
  • 表示层
  • 会话层
  • 网络层
  • 传输层
  • 链路层
  • 物理层

TCP/IP模型

  • 应用层 报文 message
  • 传输层 报文段 segment
  • 网络层 分组 packet
  • 链路层 帧 frame
  • 物理层 PDU bit

3次握手

Three way handshake , 建立tcp连接

  • 客户端发送 SYN包,进入SYN-SEND状态,等待服务器确认
  • 服务器 收到SYN包,确认客户的sYN,自己也发送一个SYN-ACK包,进入SYN-RECV状态
  • 客户端收到 SYN-ACK包,发生ACK包,发送完毕,客服端和服务器进入ESTABLISHED状态,完成3次握手,

SYN攻击

Server发送SYN-ACK后,收到client的ACK之前的TCP连接称为TCP半连接 half-open connect

  • server
    • SYN-RECV

等待client确认, 需要不断重发超时,导致正常的SYN因为队列满而被丢弃

4次挥手

Four-way wavehand。

  • Client send FIN ,Client => FIN_WAIT_1
  • Server get FIN ,send ACK, Server => CLOSE_WAIT
  • Server send FIN, Server => LAST_ACK
  • Client get FIN, Client => TIME_WAIT, send ACK , Server => CLOSED

##为什么建立连接是三次握手,而关闭连接却是四次挥手呢?

为什么TIME_WAIT状态需要经过2MSL(最大报文段生存时间)才能返回到CLOSE状态

一、保证TCP协议的全双工连接能够可靠关闭
二、保证这次连接的重复数据段从网络中消失

参考:
1
2