├── Android ├── ActivityManagerService.md ├── Activity启动过程.md ├── Android 中的 ClassLoader.md ├── Android9.0非SDK接口限制.md ├── Android匿名共享内存-Ashmem.md ├── Android基础.md ├── Android基础temp.md ├── Android新特性.md ├── Android系统启动.md ├── Android系统架构.md ├── Apk打包流程.md ├── Binder机制.md ├── Bitmap.md ├── ContentProvider启动过程.md ├── Context.md ├── Dalvik和ART.md ├── DataBinding原理.md ├── Framework │ ├── 001.Android系统架构.md │ ├── 001.Android系统架构 │ │ └── 001.Android系统架构.md │ ├── ActivityManagerService.md │ ├── Context.md │ ├── WindowManagerService.md │ ├── 包管理机制和PMS │ │ ├── 000.目录.md │ │ └── 001.PackageManager简介.md │ └── 应用程序进程启动.md ├── Handler.md ├── HandlerThread.md ├── Hook技术.md ├── IntentService.md ├── JNI基础.md ├── Jetpack.md ├── LayoutInflater.md ├── MMKV.md ├── MVC、MVP、MVVM.md ├── RecyclerView.md ├── Service启动过程.md ├── ViewPager2.md ├── View体系.md ├── View绘制流程.md ├── WindowManagerService.md ├── kotlin.md ├── v1、v2、v3签名区别.md ├── 事件分发.md ├── 代办.md ├── 保活.md ├── 函数式编程.md ├── 协程.md ├── 广播启动过程.md ├── 应用程序进程启动过程.md ├── 性能优化 │ ├── 01.应用崩溃优化.md │ ├── 02.内存优化.md │ ├── 03.绘制优化.md │ ├── 04.App启动速度优化.md │ ├── 05.IO优化.md │ ├── 06.数据存储优化.md │ ├── 07.SQLite优化.md │ ├── 08.网络优化.md │ ├── 09.电量优化.md │ ├── 10.Apk包优化.md │ ├── 11.高效的测试.md │ ├── 12.发布版本优化.md │ ├── 启动优化.md │ ├── 电量优化.md │ └── 绘制优化.md ├── 换肤方案.md ├── 插件化.md ├── 热修复.md ├── 第三方源码 │ ├── ARouter.md │ ├── ButterKnife.md │ ├── Dagger2.md │ ├── EventBus.md │ ├── Glide.md │ ├── GreenDao.md │ ├── Leakcanary.md │ ├── Okhttp.md │ ├── Retrofit.md │ └── RxJava.md └── 组件化.md ├── C++ └── C++基础.md ├── C ├── C基础.md └── Linux基础.md ├── Flutter ├── Dart │ └── Dart语言.md ├── Dart语言.md └── Flutter实战 │ ├── 01.第一个Flutter应用.md │ ├── 02.基础Widget.md │ ├── 03.布局类组件.md │ ├── 04.容器类组件.md │ └── Flutter实战.md ├── Git ├── 001.reset和checkout区别.md ├── part01 │ ├── 000.目录.md │ ├── 001.Git理论基础.md │ ├── 002.查看工作状态和历史提交.md │ ├── 003.回到过去.md │ ├── 004.版本对比.md │ ├── 005.修改最后一次提交、删除文件和重命名.md │ ├── 006.创建和切换分支.md │ ├── 007.合并分支和删除分支.md │ └── 008.匿名分支和checkout命令.md └── part02 │ ├── 000.目录.md │ ├── 001.基本操作.md │ ├── 002.分支管理.md │ └── 003.标签.md ├── Gradle ├── 000.目录.md ├── 001.Groovy基础.md ├── 002.Gradle基础.md └── part01 │ ├── 000.目录.md │ ├── 001.Gradle 版 Hello World.md │ ├── 001.Gradle基础.md │ ├── 002.Gradle Wrapper.md │ ├── 003.Gradle 日志.md │ ├── 004.Gradle 命令行.md │ ├── 004.Gradle构建脚本基础.md │ ├── 005.Groovy基础_字符串.md │ ├── 006.Groovy基础_集合.md │ ├── 007.Groovy基础_方法.md │ ├── 008.Groovy基础_JavaBean.md │ ├── 009.Groovy基础_闭包.md │ ├── 010.DSL.md │ └── 011.Settings文件.md ├── Java ├── ArrayList源码分析.md ├── ConcurrentHashMap.md ├── CopyOnWriteArrayList.md ├── HashMap.md ├── JavaIO.md ├── Java基础.md ├── Java容器.md ├── Java并发.md ├── Java线程池.md ├── Java虚拟机.md ├── LinkedHashMap源码分析.md ├── LinkedList源码分析.md ├── PriorityQueue源码分析.md ├── synchronized锁升级优化.md ├── 反射与动态代理.md ├── 异常体系.md └── 泛型.md ├── NDK └── JNI.md ├── Python ├── Python基础.md ├── bili视频爬虫.md └── 一个图片爬虫例子.md ├── README.md ├── asset ├── 1.6内存区域.png ├── 1.7hash链表.png ├── 1.8hash.png ├── 1.8hash1.png ├── 1.8内存区域.png ├── 17CM.png ├── 5.0-8.0.png ├── 5.0电量优化.png ├── ABA.png ├── Actiovity构成.png ├── Activity启动过程.png ├── Activity栈.png ├── Activity组成.png ├── Android系统启动流程.png ├── Atomic类.png ├── CachedThreadPool.png ├── DNS层次结构.jpg ├── Hook.png ├── IO体系.png ├── IO控制方式.png ├── Instantrun.png ├── JVMGC.png ├── JVM内存1.png ├── JVM内存2.png ├── UDP数据报格式.png ├── View体系.png ├── WindowManager.png ├── android-stack_2x.png ├── apk签名过程.jpg ├── binder机制.jpg ├── c.jpg ├── c_数据类型.png ├── ca.png ├── channel.png ├── check.jpg ├── context.jpg ├── context继承.png ├── c数据类型.png ├── c编译过程.png ├── dart线程模型.jpg ├── dump.png ├── event.jpg ├── executor.png ├── final-architecture.png ├── gc root.png ├── git_diff.png ├── git_reset.png ├── git_reset_checkout.png ├── git基本操作.png ├── gradle.png ├── handler.png ├── http.png ├── http2.0.jpg ├── https.png ├── https原理.png ├── http报文结构.jpg ├── http请求.jpg ├── iostream2xx.png ├── ip互联.png ├── javacrash.jfif ├── java线程的状态.png ├── java编译.png ├── jetpack.jpg ├── linux目录结构.jpg ├── mvc.png ├── mvp.png ├── mvvm.png ├── newFixedThreadPool.png ├── newSingleThreadExecutor.png ├── next.png ├── okhttp.png ├── oopxxx.png ├── osi模式.png ├── p2p和cs.jpg ├── pcb内容.png ├── sche2.png ├── scrr.png ├── service.png ├── service启动过程.png ├── servie生命周期.png ├── tcpip.png ├── tcpip和osi.png ├── tcp报文.png ├── tcp报文段.png ├── topbanner.png ├── udp.png ├── v1签名.png ├── v2签名.jpg ├── v3.png ├── view坐标.png ├── wrapper.png ├── wrappertest.png ├── www.jpg ├── 三次握手.png ├── 三种常用的数据编码方式.png ├── 三种数据交换的方式.png ├── 两级目录结构.jpg ├── 中断.png ├── 中断处理过程.png ├── 二叉查找树.png ├── 二叉查找树问题.png ├── 五层协议.png ├── 代理模式.png ├── 以存储器为中心的计算机结构.png ├── 使用示意.png ├── 依赖关系.png ├── 保活.png ├── 典型冯诺依曼机.png ├── 内存模型.png ├── 加密方式.png ├── 协议接口服务.png ├── 单向关联.png ├── 单模光纤.png ├── 单级目录结构.jpg ├── 双向关联.png ├── 双绞线.png ├── 受检异常.webp.jpg ├── 右旋.gif ├── 同轴电缆.png ├── 四次挥手.png ├── 域名解析过程.jpg ├── 复制.png ├── 多模光纤.png ├── 实现关系.png ├── 对象的创建.png ├── 对象的访问.png ├── 小顶堆.jpg ├── 小顶堆.png ├── 左旋.gif ├── 左旋右旋规则.png ├── 常用的系统服务1.png ├── 常用的系统服务2.png ├── 应用层协议.jpg ├── 循环队列.png ├── 快恢复.png ├── 慢开始.png ├── 手机淘宝.png ├── 拓扑.png ├── 指令执行.png ├── 控制连接.jpg ├── 操作系统历史.png ├── 数字签名.png ├── 数字调制.png ├── 数据编码.png ├── 无环图目录结构.jpg ├── 时隙ALOHA.png ├── 普通Activity创建.png ├── 标记整理.png ├── 标记清除.png ├── 树形目录结构.jpg ├── 校验.png ├── 根Activity启动过程.png ├── 模型.png ├── 死锁.png ├── 消息机制.png ├── 电子邮件.jpg ├── 电子邮件发送接收过程.jpg ├── 磁盘结构.jpg ├── 程序装入过程.jpg ├── 类加载修复.png ├── 类加载器.png ├── 类图.png ├── 类生命周期.png ├── 系统结构.png ├── 纯ALOHA.png ├── 线程.png ├── 线程模型.png ├── 线程池执行的过程.png ├── 线程状态转换.png ├── 线程调度.png ├── 组件化.png ├── 组件化架构.png ├── 组合关系.png ├── 继承关系.png ├── 编译过程.png ├── 聚合关系.png ├── 自关联.png ├── 计算机功能.png ├── 计算机系统多层次结构.png ├── 边缘部分.png ├── 运行时数据区.png ├── 进程状态转换.png ├── 逻辑结构.png ├── 链式存储结构.png ├── 集合框架.png ├── 集合框架2.png ├── 非受检异常.webp.jpg └── 高速缓存区.jpg ├── js └── JavaScript基础.md ├── 其他 ├── 001.HTTP1.0、HTTP2.0、HTTP3.0.md ├── HTTP和HTTPS.md ├── 博客.md ├── 滑动窗口.md ├── 知识点总结.md ├── 笔记.md ├── 红黑树.md └── 面经整理.md ├── 密码学 ├── 001.密码学概述.md ├── 002.凯撒密码.md ├── 003.对称加密.md ├── 004.消息摘要.md ├── 005.非对称加密.md └── 006.数字签名.md ├── 操作系统 ├── 001.计算机系统概述.md ├── 002.进程管理.md ├── 003.内存管理.md ├── 004.文件管理.md └── 005.输入输出(IO)管理.md ├── 数据结构 ├── 001.绪论.md ├── 002.线性表.md ├── 003.栈和队列.md ├── 004.串.md ├── 005.树与二叉树.md ├── 006.图.md ├── 007.查找.md ├── 008.排序.md ├── 01.数据结构和算法概述.md ├── 02.排序.md ├── 03.线性表.md └── part01 │ ├── 000.目录.md │ ├── 001.数据结构与算法的关系.md │ ├── 002.线性结构和非线性结构.md │ ├── 003.稀疏数组.md │ ├── 004.队列.md │ ├── 005.单链表.md │ └── 006.单链表面试题.md ├── 正则 └── 正则表达式.md ├── 算法 ├── labuladong的算法小抄.md ├── 剑指Offer │ ├── 03.数组中重复的数字.md │ ├── 04.二维数组中的查找.md │ ├── 05.替换空格.md │ ├── 06.从尾到头打印链表.md │ ├── 07.重建二叉树.md │ ├── 10-1.斐波那契数列.md │ ├── 10-2.青蛙跳台阶.md │ ├── 22.链表倒数第k个节点.md │ ├── 40.最小的k个数.md │ ├── 57-2.和为s的连续正数序列.md │ ├── 67.把字符串转换成整数.md │ ├── 68-1.二叉搜索树中的最近公共祖先.md │ └── 68-2.二叉树的最近公共祖先.md ├── 排序.md ├── 算法训练 │ └── 字符串 │ │ ├── 387.字符串中的第一个唯一字符.md │ │ ├── 58.最后一个单词的长度.md │ │ ├── 709.转换成小写字母.md │ │ └── 8.字符串转换整数 (atoi).md └── 算法训练营.md ├── 计算机组成原理 ├── 001.计算机系统概述.md ├── 002.数据的表示和运算.md ├── 003.存储系统.md ├── 004.指令系统.md ├── 005.中央处理器.md ├── 006.总线.md └── 007.IO系统.md ├── 计算机网络 ├── 001.计算机网络概述.md ├── 002.物理层.md ├── 003.数据链路层.md ├── 004.网络层.md ├── 005.传输层.md ├── 006.应用层.md ├── other │ └── 001.HTTP1.0、HTTP2.0、HTTP3.0.md └── 计算机网络.md ├── 设计模式 ├── 001.设计模式七大原则.md ├── 002.设计模式简介.md ├── 003.UML.md ├── 004.创建者模式_单例模式.md ├── 005.创建者模式_工厂模式.md ├── 006.创建者模式_原型模式.md ├── 007.创建者模式_建造者模式.md ├── 008.结构型模式_适配器模式.md ├── 009.结构型模式_代理模式.md ├── 010.结构型模式_装饰者模式.md ├── 011.结构型模式_桥接模式.md ├── 012.结构型模式_外观模式.md ├── 013.结构型模式_享元模式.md ├── 014.结构型模式_组合模式.md ├── 015.结构型模式_桥接模式.md ├── 016.行为型模式_模板模式.md ├── 017.行为型模式_策略模式.md ├── 018.行为型模式_命令模式.md ├── 019.行为型模式_职责链模式.md ├── 020.行为型模式_状态模式.md ├── 021.行为型模式_观察者模式.md ├── 022.行为型模式_中介者模式.md ├── 023.行为型模式_迭代器模式.md ├── 024.行为型模式_访问者模式.md ├── 025.行为型模式_备忘录模式.md ├── 026.行为型模式_解释器模式.md └── 027.模式对比.md └── 音视频 └── 001.音视频基本知识.md /Android/Android9.0非SDK接口限制.md: -------------------------------------------------------------------------------- 1 | ## 1 简介 2 | 3 | 在 Android 9.0 中,通过反射或 JNI 访问非公开接口时会触发警告/异常等。当我们调用反射 java.lang.Class.getDeclaredMethod(String) 最终调用到 getDeclaredMethodInternal 这个 native 方法。 4 | 5 | ```java 6 | static jobject Class_getDeclaredMethodInternal(JNIEnv* env, jobject javaThis, 7 | jstring name, jobjectArray args) { 8 | ... 9 | if (result == nullptr || ShouldBlockAccessToMember(result->GetArtMethod(), soa.Self())) { 10 | //ShouldBlockAccessToMember 触发系统的限制,如果不满足相关条件,直接抛异常。 11 | return nullptr; 12 | } 13 | return soa.AddLocalReference(result.Get()); 14 | } 15 | 16 | //ShouldBlockAccessToMember 17 | ALWAYS_INLINE static bool ShouldBlockAccessToMember(T* member, Thread* self) 18 | REQUIRES_SHARED(Locks::mutator_lock_) { 19 | //hiddenapi::GetMemberAction 20 | hiddenapi::Action action = hiddenapi::GetMemberAction( 21 | member, self, IsCallerTrusted, hiddenapi::kReflection); 22 | if (action != hiddenapi::kAllow) { 23 | hiddenapi::NotifyHiddenApiListener(member); 24 | } 25 | return action == hiddenapi::kDeny; 26 | } 27 | 28 | //hidden_api.cc 29 | template 30 | inline Action GetMemberAction(T* member, 31 | Thread* self, 32 | std::function fn_caller_is_trusted, 33 | AccessMethod access_method) 34 | REQUIRES_SHARED(Locks::mutator_lock_) { 35 | DCHECK(member != nullptr); 36 | //获取 HiddenApiAccessFlags 列表 37 | HiddenApiAccessFlags::ApiList api_list = member->GetHiddenApiAccessFlags(); 38 | Action action = GetActionFromAccessFlags(member->GetHiddenApiAccessFlags()); 39 | //很明显,如果能干涉这3个语句的返回值,就能影响到系统对隐藏 API 的判断 欺骗系统 绕过限制。 40 | if (action == kAllow) { 41 | return action; 42 | } 43 | if (fn_caller_is_trusted(self)) { 44 | return kAllow; 45 | } 46 | return detail::GetMemberActionImpl(member, api_list, action, access_method); 47 | } 48 | ``` 49 | 50 | * 针对 action == kAllow :动态搜索到 hidden_api_policy_,直接修改内存 51 | * 针对 fn_caller_is_trusted(self):修改偏移的方式直接修改 ClassLoader 52 | * 针对 GetMemberActionImpl:修改 runtime 的内存,或修改signature 53 | 54 | **绕过 API 限制** 55 | 56 | * **通过某种方式修改函数的执行流程** (**inline hook**) 57 | * **以系统类的身份去反射** 58 | * 直接把我们自己变成系统类 59 | * 借助系统类去调用反射(通过 「元反射」来反射调用 `VMRuntime.setHiddenApiExemptions` 将要使用的隐藏 API 全部都豁免掉了) 60 | 61 | ## 2 参考阅读 62 | 63 | * [一种绕过Android P对非SDK接口限制的简单方法](http://weishu.me/2018/06/07/free-reflection-above-android-p/) 64 | 65 | * [另一种绕过 Android P以上非公开API限制的办法](http://weishu.me/2019/03/16/another-free-reflection-above-android-p/) 66 | 67 | -------------------------------------------------------------------------------- /Android/Android匿名共享内存-Ashmem.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/Android/Android匿名共享内存-Ashmem.md -------------------------------------------------------------------------------- /Android/Android新特性.md: -------------------------------------------------------------------------------- 1 | ## 5.0 2 | 3 | * Meterial Desigin 4 | * 支持多种设备 5 | * 全新的通知设计 6 | * 64 位的 ART 虚拟机 7 | * Overview (多任务视窗) 8 | * 设备识别锁(附近有智能手表等,解锁) 9 | * 面部解锁 10 | * RecyclerView、CardView 11 | * 三种 Notification(普通、折叠、悬挂) 12 | * Toolbar、Palette 13 | 14 | ## 6.0 15 | 16 | * 应用权限管理 17 | * Android Pay 18 | * 指纹支持 19 | * Doze 电量管理 20 | * App Links 21 | 22 | ## 7.0 23 | 24 | * 多窗口模式 25 | * Data Saver (流量保护机制) 26 | * 改进 Java 8 语言支持 27 | * 自定义壁纸 28 | * 快速回复 29 | * 后台省电 30 | * 快速设置通知栏快捷界面 31 | 32 | ## 8.0 33 | 34 | * 全新的通知中心 35 | * 画中画支持 36 | * 自适应启动器图标 37 | * 多显示器支持 38 | * 后台执行限制(后台Service限制、广播限制) 39 | * 后台位置信息限制 40 | 41 | ## 9.0 42 | 43 | * 全面屏 44 | * 机制学习 45 | * 室内定位 46 | * 对使用非 SDK 接口的限制 47 | 48 | ## 10.0 49 | 50 | * 5G 网络支持 51 | * 可折叠设备 52 | * 暗黑主题 53 | * 手势导航 54 | * ART 优化(分代垃圾回收功能) 55 | * 用户隐私 56 | 57 | 58 | 59 | -------------------------------------------------------------------------------- /Android/Android系统启动.md: -------------------------------------------------------------------------------- 1 | ## 1 Android 系统启动流程 2 | 3 | ![](../asset/Android系统启动流程.png) 4 | 5 | ### 1.1 启动电源以及系统启动 6 | 7 | 当电源按下时引导芯片代码开始从预定义的地方(固化在ROM)开始执行。加载引导程序 **BootLoader 到 RAM**,然后执行。 8 | 9 | ### 1.2 引导程序 BootLoader 10 | 11 | 引导程序 BootLoader 是在 Android 操作系统开始运行前的一个小程序,主要作用是把系统 OS 拉起来并运行。 12 | 13 | ### 1.3 Linux 内核启动 14 | 15 | 内核启动时,设置缓存、被保护存储器、计划列表、加载驱动。当内核完成系统设置,它首先在系统文件中寻找init.rc 文件,并启动 init 进程。 16 | 17 | * init.rc 是由 Android 初始化语言编写的脚本,包含 5 种类型:Action、Command、Service、Option、Import。 18 | 19 | ### 1.4 init 进程启动 20 | 21 | **初始化和启动属性服务,并且启动 Zygote 进程。** 22 | 23 | * 创建和挂载启动所需的文件目录 24 | * 初始化和启动属性服务 25 | * 解析 init.rc 配置文件并启动 Zygote 进程 26 | 27 | ### 1.5 Zygote 进程启动 28 | 29 | 创建 Java 虚拟机并为 Java 虚拟机注册 JNI,创建服务端 Socket,启动 SystemServer 进程。 30 | 31 | * Zygote:孵化器,通过 fork 的形式创建应用进程和 SystemServer 进程。 32 | * Zygote 启动脚本(init.zygote32.rc、init.zygote32_64.rc、init.zygote64.rc、init.zygote64_32.rc) 33 | 34 | ### 1.6 SystemServer 进程启动 35 | 36 | 启动 Binder 线程池和 SystemServiceManager,并且启动各种系统服务。 37 | 38 | ```java 39 | ZygoteInit.nativeZygoteInit() //启动 Binder 线程池 是 Native 方法 40 | ``` 41 | 42 | ### 1.7 Launcher 启动 43 | 44 | 被 SystemServer 进程启动的 ActivityManagerService 会启动 Launcher,Launcher 启动后会将已安装应用的快捷图标显示到界面上。 -------------------------------------------------------------------------------- /Android/Android系统架构.md: -------------------------------------------------------------------------------- 1 | ## 1 平台架构 2 | 3 | ![](../asset/android-stack_2x.png) 4 | 5 | ## 2 Linux 内核层 6 | 7 | Android 平台的基础是 Linux 内核。例如,[Android Runtime (ART)](https://developer.android.google.cn/guide/platform/#art) 依靠 Linux 内核来执行底层功能,例如线程和低层内存管理。 8 | 9 | 使用 Linux 内核可让 Android 利用[主要安全功能](https://source.android.google.cn/security/overview/kernel-security.html),并且允许设备制造商为著名的内核开发硬件驱动程序。 10 | 11 | ## 3 硬件抽象层(HAL) 12 | 13 | [硬件抽象层 (HAL)](https://source.android.google.cn/devices/architecture/hal-types) 提供标准界面,向更高级别的 [Java API 框架](https://developer.android.google.cn/guide/platform/#api-framework)显示设备硬件功能。HAL 包含多个库模块,其中每个模块都为特定类型的硬件组件实现一个界面,例如[相机](https://source.android.google.cn/devices/camera/index.html)或[蓝牙](https://source.android.google.cn/devices/bluetooth.html)模块。当框架 API 要求访问设备硬件时,Android 系统将为该硬件组件加载库模块。 14 | 15 | ## 4 系统运行库层 16 | 17 | ### 4.1 Android Runtime 18 | 19 | 对于运行 Android 5.0(API 级别 21)或更高版本的设备,每个应用都在其自己的进程中运行,并且有其自己的 [Android Runtime (ART)](https://source.android.google.cn/devices/tech/dalvik/index.html) 实例。ART 编写为通过执行 DEX 文件在低内存设备上运行多个虚拟机,DEX 文件是一种专为 Android 设计的字节码格式,经过优化,使用的内存很少。编译工具链(例如 [Jack](https://source.android.google.cn/source/jack.html))将 Java 源代码编译为 DEX 字节码,使其可在 Android 平台上运行。 20 | 21 | ART 的部分主要功能包括: 22 | 23 | - 预先 (AOT) 和即时 (JIT) 编译 24 | - 优化的垃圾回收 (GC) 25 | - 在 Android 9(API 级别 28)及更高版本的系统中,支持将应用软件包中的 [Dalvik Executable 格式 (DEX) 文件转换为更紧凑的机器代码](https://developer.android.google.cn/about/versions/pie/android-9.0#art-aot-dex)。 26 | - 更好的调试支持,包括专用采样分析器、详细的诊断异常和崩溃报告,并且能够设置观察点以监控特定字段 27 | 28 | 在 Android 版本 5.0(API 级别 21)之前,Dalvik 是 Android Runtime。如果您的应用在 ART 上运行效果很好,那么它应该也可在 Dalvik 上运行,但[反过来不一定](https://developer.android.google.cn/guide/practices/verifying-apps-art)。 29 | 30 | Android 还包含一套核心运行时库,可提供 Java API 框架所使用的 Java 编程语言中的大部分功能,包括一些 [Java 8 语言功能](https://developer.android.google.cn/guide/platform/j8-jack)。 31 | 32 | ### 4.2 原生 C/C++ 库 33 | 34 | 许多核心 Android 系统组件和服务(例如 ART 和 HAL)构建自原生代码,需要以 C 和 C++ 编写的原生库。Android 平台提供 Java 框架 API 以向应用显示其中部分原生库的功能。例如,您可以通过 Android 框架的 [Java OpenGL API](https://developer.android.google.cn/reference/android/opengl/package-summary) 访问 [OpenGL ES](https://developer.android.google.cn/guide/topics/graphics/opengl),以支持在应用中绘制和操作 2D 和 3D 图形。 35 | 36 | 如果开发的是需要 C 或 C++ 代码的应用,可以使用 [Android NDK](https://developer.android.google.cn/ndk) 直接从原生代码访问某些[原生平台库](https://developer.android.google.cn/ndk/guides/stable_apis)。 37 | 38 | ## 5 应用框架层 39 | 40 | 您可通过以 Java 语言编写的 API 使用 Android OS 的整个功能集。这些 API 形成创建 Android 应用所需的构建块,它们可简化核心模块化系统组件和服务的重复使用,包括以下组件和服务: 41 | 42 | - 丰富、可扩展的[视图系统](https://developer.android.google.cn/guide/topics/ui/overview),可用以构建应用的 UI,包括列表、网格、文本框、按钮甚至可嵌入的网络浏览器 43 | - [资源管理器](https://developer.android.google.cn/guide/topics/resources/overview),用于访问非代码资源,例如本地化的字符串、图形和布局文件 44 | - [通知管理器](https://developer.android.google.cn/guide/topics/ui/notifiers/notifications),可让所有应用在状态栏中显示自定义提醒 45 | - [Activity 管理器](https://developer.android.google.cn/guide/components/activities),用于管理应用的生命周期,提供常见的[导航返回栈](https://developer.android.google.cn/guide/components/tasks-and-back-stack) 46 | - [内容提供程序](https://developer.android.google.cn/guide/topics/providers/content-providers),可让应用访问其他应用(例如“联系人”应用)中的数据或者共享其自己的数据 47 | 48 | 开发者可以完全访问 Android 系统应用使用的[框架 API](https://developer.android.google.cn/reference/packages)。 49 | 50 | ## 6 应用层 51 | 52 | Android 随附一套用于电子邮件、短信、日历、互联网浏览和联系人等的核心应用。平台随附的应用与用户可以选择安装的应用一样,没有特殊状态。因此第三方应用可成为用户的默认网络浏览器、短信 Messenger 甚至默认键盘(有一些例外,例如系统的“设置”应用)。 53 | 54 | 系统应用可用作用户的应用,以及提供开发者可从其自己的应用访问的主要功能。例如,如果您的应用要发短信,您无需自己构建该功能,可以改为调用已安装的短信应用向您指定的接收者发送消息。 -------------------------------------------------------------------------------- /Android/Apk打包流程.md: -------------------------------------------------------------------------------- 1 | ## 1 APK 打包过程 2 | 3 | ![](../asset/apk签名过程.jpg) 4 | 5 | * 打包资源文件,生成 R.java 文件 6 | - aapt 工具(aapt.exe) -> AndroidManifest.xml 和 布局文件 XMl 都会编译 -> R.java -> AndroidManifest.xml 会被 aapt 编译成二进制 7 | - res 目录下资源 -> 编译,变成二进制文件,生成 resource id -> 最后生成 resouce.arsc(文件索引表) 8 | 9 | * 处理 aidl 文件,生成相应的 Java 文件 10 | 11 | * aidl 工具(aidl.exe) 12 | 13 | * 编译项目源代码,生成 class 文件 14 | 15 | * 转换所有 class 文件,生成 classes.dex 文件 16 | 17 | * dx.bat 18 | 19 | * 打包生成 APK 文件 20 | 21 | ​ 22 | 23 | * apkbuilder 工具打包到最终的 .apk 文件中 24 | 25 | * 对APK文件进行签名 26 | 27 | * 对签名后的 APK 文件进行对齐处理(正式包) 28 | 29 | * 对 APK 进行对齐处理,用到的工具是 zipalign -------------------------------------------------------------------------------- /Android/Binder机制.md: -------------------------------------------------------------------------------- 1 | ## 1 简介 2 | 3 | Binder 中文译为粘合剂,它把系统中各个组件粘合到了一起,是各个组件的桥梁。Binder 是Android 系统中进程间通讯(IPC)的一种非常重要的方式,区别于传统的 Linux IPC 机制。 4 | 5 | ## 2 Linux 的 IPC 机制 6 | 7 | ### 2.1 管道(PIPE) 8 | 9 | 用于进程间通信的一段共享内存,创建管道的进程称为管道服务器,连接到一个管道的进程为管道客户机。一个进程在向管道写入数据后,另一进程就可以从管道的另一端将其读取出来。用于父子进程或者兄弟进程之间,具有亲缘关系的进程之间的通信。 10 | 11 | ### 2.2 命名管道(FIFO) 12 | 13 | 是一种特殊类型的文件,它在系统中以文件形式存在。克服了管道的弊端允许没有亲缘关系的进程间通信。 14 | 15 | ### 2.3 信号(signal) 16 | 17 | 信号机制是unix系统中最为古老的进程之间的通信机制,用于一个或几个进程之间传递异步信号。信号可以有各种异步事件产生,比如键盘中断等。shell 也可以使用信号将作业控制命令传递给它的子进程。 18 | 19 | ### 2.4 消息队列(Message queues) 20 | 21 | 是内核地址空间中的内部链表,通过 linux 内核在各个进程直接传递内容,消息顺序地发送到消息队列中,并以几种不同的方式从队列中获得,每个消息队列可以用 IPC 标识 唯一地进行识别。内核中的消息队列是通过 IPC 的标识符来区别,不同的消息队列直接是相互独立的,每个消息队列中的消息,又构成一个 独立的链表。 22 | 消息队列克服了信号承载信息量少,管道只能承载无格式字符流。 23 | 24 | ### 2.5 信号量(Semaphore) 25 | 26 | 是一种计数器,用于控制对多个进程共享的资源进行的访问。常常被用作一个锁机制,在某个进程正在对特定的资源进行操作时,信号量可以防止另一个进程去访问它。 27 | 信号量是特殊的变量,它只取正整数值并且只允许对这个值进行两种操作:等待(wait)和信号(signal),简单来说就是PV操作,P用于等待,V用于信号 ,P 相当于申请资源,V 相当于释放资源 。 28 | 29 | * P(sv):sv > 0,就减 1;sv == 0,就挂起该进程的执行 30 | * V(sv):如果有其他进程因等待 sv 而被挂起,就让它恢复运行;如果没有其他进程因等待 sv而挂起,则给它加1 。 31 | 32 | ### 2.6 共享内存(Share Memory) 33 | 34 | 多个进程之间共享内存区域的一种进程间的通信方式,由 IPC 为进程创建的一个特殊地址范围,它将出现在该进程的地址空间中。其他进程可以将同一段共享内存连接到自己的地址空间中。所有进程都可以访问共享内存中的地址,就好像它们是 malloc 分配的一样。如果一个进程向共享内存中写入了数据,所做的改动将立刻被其他进程看到。 35 | 36 | ### 2.7 内存映射(Memory Map) 37 | 38 | **内存映射文件**,是由一个文件到一块内存的映射。内存映射文件与 虚拟内存有些类似,通过内存映射文件可以保留一个地址的区域, 39 | 同时将物理存储器提交给此区域,内存文件映射的物理存储器来自一个已经存在于磁盘上的文件,而且在对该文件进行操作之前必须首先对文件进行映射。使用内存映射文件处理存储于磁盘上的文件时,将不必再对文件执行I/O操作。 每一个使用该机制的进程通过把同一个共享的文件映射到自己的进程地址空间来实现多个进程间的通信(这里类似于共享内存,只要有一个进程对这块映射文件的内存进行操作,其他进程也能够马上看到)。 40 | 使用内存映射文件不仅可以实现多个进程间的通信,还可以用于处理大文件提高效率。因为我们普通的做法是把磁盘上的文件先拷贝到内核空间的一个缓冲区再拷贝到用户空间(内存),用户修改后再将这些数据拷贝到缓冲区再拷贝到磁盘文件,一共四次拷贝。如果文件数据量很大,拷贝的开销是非常大的。那么问题来了,系统在在进行内存映射文件就不需要数据拷贝?mmap()确实没有进行数据拷贝,真正的拷贝是在在缺页中断处理时进行的,由于mmap()将文件直接映射到用户空间,所以中断处理函数根据这个映射关系,直接将文件从硬盘拷贝到用户空间,所以只进行一次数据拷贝。效率高于read/write。 41 | 42 | ### 2.8 套接字(socket) 43 | 44 | 套接字机制不但可以单机的不同进程通信,而且使得跨网机器间进程可以通信。它明确地将客户端与服务器 区分开来,可以实现多个客户端连到同一服务器。 45 | 46 | 47 | 48 | ## 参考阅读 49 | 50 | * [linux基础——linux进程间通信(IPC)机制总结](https://blog.csdn.net/a987073381/article/details/52006729) 51 | * [一篇文章了解相见恨晚的 Android Binder 进程间通讯机制](https://jeanboy.blog.csdn.net/article/details/70082302?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-3.control&dist_request_id=&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-3.control) 52 | * [Binder学习指南](http://weishu.me/2016/01/12/binder-index-for-newer/) 53 | 54 | -------------------------------------------------------------------------------- /Android/Context.md: -------------------------------------------------------------------------------- 1 | ## 1 简介 2 | 3 | Context 上下文对象,Android 中很多业务流程都涉及到 Context。 4 | 5 | ![](../asset/context.jpg) 6 | 7 | Context 数量 = Activity 数量 + Service 数量 + Application 数量(1) 8 | 9 | ## 2 Application Context 的创建过程 10 | 11 | 在 Activity 启动流程源码分析的启动过程中, 最后一个重要的方法是performLaunchActivity, 源码如下: 12 | 13 | ```java 14 | private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) { 15 | 16 | ... 17 | //创建 Application 18 | Application app = r.packageInfo.makeApplication(false, mInstrumentation); 19 | ... 20 | return activity; 21 | } 22 | 23 | ``` 24 | 25 | 主要看 r.packageInfo.makeApplication -> LpadedApk 26 | 27 | ```java 28 | @UnsupportedAppUsage 29 | public Application makeApplication(boolean forceDefaultAppClass, 30 | Instrumentation instrumentation) { 31 | //不为 null 就直接返回 Application 32 | if (mApplication != null) { 33 | return mApplication; 34 | } 35 | ... 36 | try { 37 | java.lang.ClassLoader cl = getClassLoader(); 38 | if (!mPackageName.equals("android")) { 39 | ... 40 | } 41 | //创建 ContextImpl类型的 appContext 42 | ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this); 43 | //创建了一个 app 实例 反射 44 | app = mActivityThread.mInstrumentation.newApplication( 45 | cl, appClass, appContext); 46 | appContext.setOuterContext(app); 47 | } catch (Exception e) { 48 | ... 49 | } 50 | mActivityThread.mAllApplications.add(app); 51 | mApplication = app; 52 | if (instrumentation != null) { 53 | try { 54 | //最终就调用了application.onCreate()方法 55 | instrumentation.callApplicationOnCreate(app); 56 | } catch (Exception e) { 57 | ... 58 | } 59 | } 60 | return app; 61 | } 62 | ``` 63 | 64 | -------------------------------------------------------------------------------- /Android/DataBinding原理.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/Android/DataBinding原理.md -------------------------------------------------------------------------------- /Android/Framework/001.Android系统架构.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/Android/Framework/001.Android系统架构.md -------------------------------------------------------------------------------- /Android/Framework/001.Android系统架构/001.Android系统架构.md: -------------------------------------------------------------------------------- 1 | ## 1 Android 系统架构 2 | 3 | ![](../../../asset/系统结构.png) 4 | 5 | -------------------------------------------------------------------------------- /Android/Framework/ActivityManagerService.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/Android/Framework/ActivityManagerService.md -------------------------------------------------------------------------------- /Android/Framework/Context.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/Android/Framework/Context.md -------------------------------------------------------------------------------- /Android/Framework/包管理机制和PMS/000.目录.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/Android/Framework/包管理机制和PMS/000.目录.md -------------------------------------------------------------------------------- /Android/Framework/包管理机制和PMS/001.PackageManager简介.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/Android/Framework/包管理机制和PMS/001.PackageManager简介.md -------------------------------------------------------------------------------- /Android/Framework/应用程序进程启动.md: -------------------------------------------------------------------------------- 1 | ## 1 应用程序进程启动 2 | 3 | * AMS 通过 startProcessLocked 方法向 Zygote 进程发送创建应用程序进程的请求 4 | * 获取要创建的应用进程的用户 ID 5 | 6 | * Zygote 接收请求并创建应用程序进程 7 | * Binder 线程池 8 | * 创建消息循环(ActivityThread -> main() -> 创建主线程 Looper -> 创建主线程 H (Handler)类) 9 | 10 | -------------------------------------------------------------------------------- /Android/HandlerThread.md: -------------------------------------------------------------------------------- 1 | ## 1 简介 2 | 3 | * 继承自 Thread 的类,本质是一个线程; 4 | * 持有一个可用来构建 Handler 的子线程 Looper; 5 | 6 | ## 2 原理 7 | 8 | 通常使用如下: 9 | 10 | ```java 11 | handlerThread = new HandlerThread("HandlerThread-1"); 12 | handlerThread.start(); 13 | //handlerThread.getLooper() 获取子线程的 Looper 14 | taskHandler = new TaskHandler(handlerThread.getLooper()); 15 | ``` 16 | 17 | ### HandlerThread#getLooper() 18 | 19 | ```java 20 | public Looper getLooper() { 21 | //判断当前线程是否已经开启 22 | if (!isAlive()) { 23 | return null; 24 | } 25 | // 如果线程已开启但Looper未被创建,会进入同步代码块,阻塞-->直到Looper被创建 26 | synchronized (this) { 27 | while (isAlive() && mLooper == null) { 28 | try { 29 | //mLooper==null-->线程进入阻塞状态 30 | wait(); 31 | } catch (InterruptedException e) { 32 | } 33 | } 34 | } 35 | //确保 返回的mLooper不为null 36 | return mLooper; 37 | } 38 | ``` 39 | 40 | 那么 mLooper 在那里赋值,接着往下看。 41 | 42 | ### HandlerThread#run() 43 | 44 | ```java 45 | @Override 46 | public void run() { 47 | mTid = Process.myTid(); 48 | //创建此线程的 Looper 和 MessageQueue 49 | Looper.prepare(); 50 | synchronized (this) { 51 | //给 mLooper 赋值 52 | mLooper = Looper.myLooper(); 53 | //此时 mLooper!=null--> 取消线程阻塞 54 | notifyAll(); 55 | } 56 | //为线程设置mPriority优先级 57 | Process.setThreadPriority(mPriority); 58 | onLooperPrepared(); 59 | //开始 loop 60 | Looper.loop(); 61 | mTid = -1; 62 | } 63 | ``` 64 | 65 | 开启 HandlerThread 线程后,会创建此线程的 Looper 和 MessageQueue,设置线程优先级,并且开始 Looper 循环。 66 | 67 | 那么,还有一个问题 Handler 在那里。 68 | 69 | HandlerThread#getThreadHandler() 70 | 71 | ```java 72 | private @Nullable Handler mHandler; 73 | 74 | /** 75 | * 返回与此线程相关联的一个Handler实例 76 | * @hide 目前此方法是被隐藏的,无法正常直接调用 77 | */ 78 | @NonNull 79 | public Handler getThreadHandler() { 80 | if (mHandler == null) { 81 | mHandler = new Handler(getLooper()); 82 | } 83 | return mHandler; 84 | } 85 | ``` 86 | 87 | 当外界调用 getThreadHandler() 的时候,才会对 mHandler 实例化。 88 | 89 | HandlerThread 这个类与 Looper 的关系是密不可分,所以也会有退出Looper的办法。 90 | 91 | ```java 92 | public boolean quit() { 93 | Looper looper = getLooper(); 94 | if (looper != null) { 95 | looper.quit(); 96 | return true; 97 | } 98 | return false; 99 | } 100 | 101 | public boolean quitSafely() { 102 | Looper looper = getLooper(); 103 | if (looper != null) { 104 | //允许消息队列中还在排队的消息都被取出后再关闭,避免所有挂起的任务无法有序的被完成。 105 | looper.quitSafely(); 106 | return true; 107 | } 108 | return false; 109 | } 110 | ``` 111 | 112 | HandlerThread 本质是一个 Thread,在 run 中不是执行耗时任务,而是创建了该线程的 **Looper 和 消息队列**,外界 Handler 可以很方便获取到这个 Looper,搭配执行耗时任务,适合串行执行耗时任务等场景。源码当中典型场景就是 IntentService 。 113 | 114 | -------------------------------------------------------------------------------- /Android/IntentService.md: -------------------------------------------------------------------------------- 1 | ## 1 简介 2 | 3 | * 本质是一种特殊的Service,继承自Service,本身就是一个抽象类。 4 | * 可以用于在后台执行耗时的异步任务,当任务完成后会自动停止。 5 | * 拥有较高的优先级,不易被系统杀死(继承自Service的缘故),因此比较适合执行一些高优先级的异步任务。 6 | * 内部通过 HandlerThread 和 Handler 实现异步操作。 7 | * 创建 IntentService 时,只需实现 onHandleIntent 和 构造方法,onHandleIntent 为异步方法,可以执行耗时操作。 8 | 9 | ## 2 原理 10 | 11 | 先从构造函数入手。 12 | 13 | ### IntentService 14 | 15 | ```java 16 | private String mName; 17 | 18 | public IntentService(String name) { 19 | //IntentService 继承 Service,调用 Service。 20 | super(); 21 | mName = name; 22 | } 23 | ``` 24 | 25 | 接下来看看 onCreate() 方法。 26 | 27 | ### IntentService#onCreate() 28 | 29 | ```java 30 | @Override 31 | public void onCreate() { 32 | super.onCreate(); 33 | //创建 HandlerThread 的变量,结合mName 进行命名,为了获取它的 Looper 和消息队列 34 | HandlerThread thread = new HandlerThread("IntentService[" + mName + "]"); 35 | thread.start(); 36 | //获取到 HandlerThread 的 Looper 37 | mServiceLooper = thread.getLooper(); 38 | //创建 ServiceHandler 39 | mServiceHandler = new ServiceHandler(mServiceLooper); 40 | } 41 | ``` 42 | 43 | ### ServiceHandler 44 | 45 | ```java 46 | private final class ServiceHandler extends Handler { 47 | public ServiceHandler(Looper looper) { 48 | super(looper); 49 | } 50 | 51 | @Override 52 | public void handleMessage(Message msg) { 53 | //将消息转换为 Inetnt 54 | onHandleIntent((Intent)msg.obj); 55 | //msg.arg1:Message 的startId 56 | stopSelf(msg.arg1); 57 | } 58 | } 59 | //全部任务都调用 stopSelf 过后才会回调 onDestroy(),退出工作线程的Looper循环 60 | public void onDestroy() { 61 | mServiceLooper.quit(); 62 | } 63 | ``` 64 | 65 | ### IntentService#onStart() 66 | 67 | 从上面可以看出有一个 Message,创建在 onStart() 68 | 69 | ```java 70 | @Override 71 | public int onStartCommand(@Nullable Intent intent, int flags, int startId) { 72 | onStart(intent, startId); 73 | return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY; 74 | } 75 | 76 | @Override 77 | public void onStart(@Nullable Intent intent, int startId) { 78 | Message msg = mServiceHandler.obtainMessage(); 79 | msg.arg1 = startId; 80 | msg.obj = intent; 81 | //mServiceHandler 发送消息 82 | mServiceHandler.sendMessage(msg); 83 | } 84 | 85 | ``` 86 | 87 | IntentService的机制核心是 **Handler 和 消息队列**,每次调用 startService(new Intent),给 IntentService 添加一个任务。在 IntentService 的内部,第一次启动时,会构建 IntentService 对象,开始初始化工作:通过 HandlerThread 获取到一个工作线程的 Looper,用来构建它的核心Handler。然后每当有一个任务被添加进来,内部就会创建一个附带着 Intent 的 Message 对象,使用 IntentService 内部的 Handler 发送 Message。Looper 从消息队列中循环地取出 Message 传递给这个 Handler,Handler 就会在工作线程上依次处理这些消息任务的Intent。 88 | -------------------------------------------------------------------------------- /Android/JNI基础.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/Android/JNI基础.md -------------------------------------------------------------------------------- /Android/RecyclerView.md: -------------------------------------------------------------------------------- 1 | ## RecyclerView 性能优化 2 | 3 | -------------------------------------------------------------------------------- /Android/View体系.md: -------------------------------------------------------------------------------- 1 | ## 1 View 和 ViewGroup 2 | 3 | * View 是 Android 控件的基类 4 | * ViewGroup 继承 View 5 | 6 | ![](../asset/View体系.png) 7 | 8 | ## 2 View 的坐标 9 | 10 | ![](../asset/view坐标.png) 11 | 12 | ### View 获取自身宽高 13 | 14 | 由上图可知 `View` 自身的高度计算公式: 15 | 16 | - width = getRigth() - getLeft() 17 | - height = getBottom() - getTop() 18 | 19 | `View` 源码中提供的 `getWidth()` 和 `getHeight()` 获取 `View` 的宽高,内部处理是相同的。 20 | 21 | ### View 自身坐标 22 | 23 | 下面方法获取 `View` 到父控件的距离: 24 | 25 | - getTop():View 自身顶部到父控件顶部距离 26 | - getBottom():View 自身底部到父控件顶部距离 27 | - getLeft():View 自身左边到父控件左边距离 28 | - getRight():View 自身右边到父控件左边距离 29 | 30 | ### MotionEvent 提供方法 31 | 32 | 当我们点击手机屏幕时候,点击事件会封装成 `MotionEvent`,然后由 `onTouchEvent(MotionEvent ev)` 方法进行处理,`MotionEvent` 提供获取焦点左边的方法: 33 | 34 | - getX():视图坐标,点击位置距离控件左边距离 35 | - getY():视图坐标,点击位置距离控件顶部距离 36 | - getRawX():绝对坐标,点击位置距离整个屏幕左边距离 37 | - getRawY():绝对坐标,点击位置距离整个屏幕顶部距离 38 | 39 | ## 3 View 滑动 40 | 41 | * layout() 42 | * offsetLeftAndRight() 和 offsetTopAndBottom() 43 | * LayoutParmas 44 | * 动画 45 | * scrollTo 和 scrollBy 46 | * scrollTo 移动到具体点 47 | * scrollBy 移动增量,最终调用 scrollTo 48 | * Scroller 配合 View.computeScroll() -------------------------------------------------------------------------------- /Android/kotlin.md: -------------------------------------------------------------------------------- 1 | #### 1 什么是内联函数? 2 | 3 | 内联函数 使用 inline 修饰,空间换时间,比正常函数少了压栈和出栈的操作,当函数体少,以及被频繁调用的函数才适合被定义为内联函数。简单来说,就是把调用函数替换成函数里面的内容。 4 | 5 | #### 2 apply、run、let、also、with 之间的区别? 6 | 7 | with、T.run、T.apply 接收者是 this,T.let、T.also 接收者是 it。 8 | 9 | with、T.run、T.let 返回值是作用域的最后一个对象(this),T.apply、T.also 返回值是调用者本身(itself)。 10 | 11 | #### 3 数据类的使用,data class 会继承什么? 12 | 13 | 默认生成下面: 14 | 15 | * equals() / hashCode() 16 | * toString() 17 | * componentN() 18 | * copy() 19 | 20 | #### 4 "==" 和 "===" 区别? 21 | 22 | == 比较的是数值是否相等, 而 === 比较的是两个对象的地址是否相等。 23 | 24 | 25 | 26 | #### 5 kotlin 中 var、val、const val 区别? 27 | 28 | var 定义变量 private,带有 public 的 set 和 get 属性。 29 | 30 | val 定义常量 private,带有 public 的 get 方法,可见性为 private final static,并且 val 会生成方法getNormalObject(),通过方法调用访问。 31 | 32 | const val 定义的常量,可见性为 public final static,可以直接访问。 33 | 34 | #### 6 介绍一下伴生对象和静态成员? 35 | 36 | ```kotlin 37 | class NewFragment { 38 | companion object { 39 | val instance = NewFragment() 40 | } 41 | } 42 | //类似于 Java 中使用类访问静态成员的语法 43 | ``` 44 | 45 | 46 | 47 | #### 7 @JvmField 和 @JvmStatic 的使用 48 | 49 | ```kotlin 50 | class NumberTest { 51 | companion object { 52 | @JvmField //修饰属性 53 | var flag = false 54 | 55 | @JvmStatic //修饰方法 56 | fun plus(num1: Int, num2: Int): Int { 57 | return num1 + num2 58 | } 59 | } 60 | } 61 | 62 | public static void main(String[] args) { 63 | System.out.println(NumberTest.plus(2, 3)); 64 | NumberTest.flag = true; 65 | System.out.println(NumberTest.flag); 66 | } 67 | ``` 68 | 69 | #### 8 @JvmOverloads 的作用? 70 | 71 | 为了暴露多个重载方法。 72 | 73 | ```java 74 | fun f(a: String, b: Int = 0, c: String="abc"){} 75 | //相当于 java 中 76 | void f(String a, int b, String c){} 77 | 78 | @JvmOverloads 79 | fun f(a: String, b: Int=0, c:String="abc"){} 80 | //相当于 java 中 81 | void f(String a) 82 | void f(String a, int b) 83 | void f(String a, int b, String c) 84 | ``` 85 | 86 | #### 9 List 与 MutableList 区别? 87 | 88 | List :只能读,不能更改元素; 89 | 90 | MutableList :可读写,返回的是一个 ArrayList; 91 | 92 | #### 10 Kotlin 中的数据类型有隐式转换吗? 93 | 94 | 没有,需要显式的转换。 95 | 96 | #### 11 Kotlin中 Unit 类型的作用以及与Java中 Void 的区别? 97 | 98 | * Java中必须指定返回类型,void 不能省略,但是在 kotlin 中,如果返回为 unit,可以省略。 99 | * Java中 void 为一个关键字,但是在 kotlin 中 Void 是一个类。 -------------------------------------------------------------------------------- /Android/v1、v2、v3签名区别.md: -------------------------------------------------------------------------------- 1 | ## 1 APK 打包过程 2 | 3 | ![](../asset/apk签名过程.jpg) 4 | 5 | * 打包资源文件,生成 R.java 文件 6 | - aapt 工具(aapt.exe) -> AndroidManifest.xml 和 布局文件 XMl 都会编译 -> R.java -> AndroidManifest.xml 会被 aapt 编译成二进制 7 | - res 目录下资源 -> 编译,变成二进制文件,生成 resource id -> 最后生成 resouce.arsc(文件索引表) 8 | * 处理 aidl 文件,生成相应的 Java 文件 9 | * aidl 工具(aidl.exe) 10 | * 编译项目源代码,生成 class 文件 11 | * 转换所有 class 文件,生成 classes.dex 文件 12 | * dx.bat 13 | * 打包生成 APK 文件 14 | * apkbuilder 工具打包到最终的 .apk 文件中 15 | * 对APK文件进行签名 16 | * 对签名后的 APK 文件进行对齐处理(正式包) 17 | * 对 APK 进行对齐处理,用到的工具是 zipalign 18 | 19 | ## 2 签名方案 20 | 21 | - v1 方案:基于 JAR 签名。 22 | - v2 方案:解决 JAR 签名方案的安全性问题和渠道包,在 Android 7.0 引入。 23 | - v3 方案:v2 升级版,在 Android 9.0 引入。 24 | 25 | ### 2.1 签名工具 26 | 27 | * **jarsigner**:jdk 自带的签名工具,对 jar 进行签名。使用 keystore 文件进行签名,生成的签名文件默认使用 keystore 的别名命名。 28 | * **apksigner**:Android sdk 提供的专门用于 Android 应用的签名工具。使用 pk8、x509.pem 文件进行签名。 pk8 是私钥文件,x509.pem 是含有公钥的文件。生成的签名文件统一使用“CERT”命名。 29 | 30 | ### 2.2 V1 签名 31 | 32 | #### 2.2.1 签名 33 | 34 | ![](../asset/v1签名.png) 35 | 36 | #### 2.2.2 校验 37 | 38 | ![](../asset/校验.png) 39 | 40 | - 检查 APK 中包含的所有文件,对应的摘要值与 MANIFEST.MF 文件中记录的值一致。 41 | - 使用证书文件(RSA 文件)检验签名文件(SF 文件)没有被修改过。 42 | - 使用签名文件(SF 文件)检验 MF 文件没有被修改过。 43 | 44 | #### 2.2.3 v1 弊端 45 | 46 | * 签名检验速度慢:对所有文件进行摘要绩,如果 Android 机器差,安装速度慢。 47 | * 完整性保障不够:META-INF 目录用来存放签名,但可以随意添加文件。 48 | 49 | ### 2.3 v2 签名 50 | 51 | v2 是一种**全文件签名方案**,能够发现对 APK 的受保护部分进行的所有更改,从而有助于加快验证速度并增强完整性保证。 52 | 53 | v2 将**验证归档中的所有字节**,而不是单个 ZIP 条目,因此,在签署后无法再运行 ZIPalign(必须在签名之前执行)。正因如此,现在,在编译过程中,Google 将**压缩、调整和签署合并成一步完成**。 54 | 55 | v2 会在原先 APK 块中增加了一个**新的块(签名块)**,新的块存储了签名、摘要、签名算法、证书链和额外属性等信息,这个块有特定的格式。最终的签名APK其实就有四块:头文件区、V2签名块、中央目录、尾部。下图是V1签名和V2签名的组成。 56 | 57 | ![](../asset/v2签名.jpg) 58 | 59 | 相对与 v1 签名方案,v2 签名方案不再以文件为单位计算摘要了,而是以 **1 MB 为单位**将文件拆分为多个连续的块(chunk),**每个分区**的最后一个块可能会小于 1 MB。 60 | 61 | ### 2.4 v3 签名 62 | 63 | v3 签名在v2的基础上,仍然采用检查整个压缩包的校验方式。不同的是在签名部分增可以添加新的证书,即可以不用修改 ApplicationID 来完成证书的更新迭代。 64 | 65 | 其实 v3 就是加入了证书的**旋转校验**,即可以在一次的升级安装中使用新的证书,新的私钥来签名APK。当然这个新的证书是需要老证书来保证的,类似一个证书链。 66 | 67 | ![](../asset/v3.png) 68 | 69 | 签名机制主要有两种用途: 70 | 71 | - 使用特殊的 key 签名可以获取到一些不同的权限 72 | - 验证数据保证不被篡改,防止应用被恶意的第三方覆盖 73 | 74 | ## 3 总结 75 | 76 | | 版本 | 简介 | 77 | | ---- | ------------------------------------------------------------ | 78 | | v1 | 签名以文件的形式存在于apk包中,这个版本的apk包就是一个标准的zip包 | 79 | | v2 | 签名信息被塞到了apk文件本身中,这时apk已经不符合一个标准的zip压缩包的文件结构 | 80 | | v3 | 添加了一种更新证书的方式,这部分更新证书的数据同样被放在了签名信息中 | 81 | 82 | ## 4 参考 83 | 84 | [详解Android v1、v2、v3签名(小结)](https://www.jb51.net/article/174939.htm) 85 | 86 | [Android P v3签名新特性](https://blog.csdn.net/bobby_fu/article/details/103843038) -------------------------------------------------------------------------------- /Android/代办.md: -------------------------------------------------------------------------------- 1 | - [ ] 内存优化 2 | - [ ] 绘制优化 3 | - [ ] 启动优化 4 | - [ ] 数据存储优化 5 | - [ ] SQLite优化 6 | - [ ] 网络优化 7 | - [ ] 电量优化 8 | - [ ] Apk包优化 9 | - [ ] 高效测试 10 | - [ ] 发布版本优化 11 | 12 | -------------------------------------------------------------------------------- /Android/协程.md: -------------------------------------------------------------------------------- 1 | ## 1 简介 2 | 3 | 协程通过将复杂性放入库来简化异步编程。程序的逻辑可以在协程中顺序地表达,而底层库会为我们解决其异步性。该库可以将用户代码的相关部分包装为回调、订阅相关事件、在不同线程(甚至不同机器)上调度执行,而代码则保持如同顺序执行一样简单。 4 | 5 | 简单来说,协程是一种并发的设计模式,是一个轻量级的线程。 6 | 7 | ### 2 基础 8 | 9 | ```kotlin 10 | class MainActivity : AppCompatActivity() { 11 | private var TAG = "Test_Main" 12 | 13 | override fun onCreate(savedInstanceState: Bundle?) { 14 | super.onCreate(savedInstanceState) 15 | setContentView(R.layout.activity_main) 16 | test1() 17 | } 18 | private fun test1() { 19 | GlobalScope.launch { 20 | delay(1000L) 21 | println("World") 22 | } 23 | println("Hello") 24 | Thread.sleep(2000L) 25 | } 26 | } 27 | 28 | ``` 29 | 30 | -------------------------------------------------------------------------------- /Android/性能优化/02.内存优化.md: -------------------------------------------------------------------------------- 1 | ## 1 内存泄漏 2 | 3 | 内存泄漏是内存优化的重点,内存泄漏,简单来说,就是使用的对象没用释放掉。Android 中的内存泄漏主要包含以下三类: 4 | 5 | * 程序员自己的编码造成的泄漏(可控) 6 | * 第三方框架造成的泄漏(不可控) 7 | * Android 系统或第三方 ROM 造成的泄漏(不可控) 8 | 9 | ## 2 内存泄漏的场景 10 | 11 | ### 2.1 非静态内部类的静态实例 12 | 13 | 非静态内部类会持有外部类实例的引用,如果非静态内部类的实例是静态的,就会长期持有外部类的引用。 14 | 15 | ### 2.2 多线程相关的匿名类/非静态内部类 16 | 17 | 匿名内部类会持有外部类实例的引用。 18 | 19 | ### 2.3 Handler 内存泄漏 20 | 21 | Handler 的 Message 被存储在 MessageQueue 中,当 Message 没有及时处理,或者延迟处理,会导致 MEssageQueue 存在的时间长,Handler 无法被回收,如果 Handler 是非静态,Handler 会持有外部 Activity 或 Service 不能被回收。 22 | 23 | 解决: 24 | 25 | * 使用静态的 Handler 26 | 27 | * 弱引用,或者 onDestory -> 移除 MessageQueue 28 | 29 | ```java 30 | private static class MyHandler extends Handler { 31 | private final WeakReference mActivity; 32 | public MyHandler() { 33 | mActivity = new WeakReference<>(xxxActivity); 34 | } 35 | public void handleMessage(Message msg) { 36 | if(mActivity !=null && mActivity.get() == null) { 37 | mActivity.get().show(); 38 | } 39 | } 40 | } 41 | ``` 42 | 43 | ### 2.4 未正确使用 Context 44 | 45 | 对于不是必须使用 Activity 的 Context 的情况,可以使用 Application Context 来代替。 46 | 47 | ### 2.5 静态 View 48 | 49 | 使用静态的 View,会持有 Activity 的引用,导致 Activity 无法被回收。 50 | 51 | ### 2.6 WebView 52 | 53 | 在 Android 中使用一次 WebView ,内存不会被释放,可以开一个新进程,使用 AIDL 与应用的主进程进行通信。 54 | 55 | ### 2.7 资源对象未关闭 56 | 57 | Cursor、File 等对象,往往使用缓冲,会造成内存泄漏,在资源对象未使用时,可以把引用置为 null。 58 | 59 | ### 2.8 集合中的对象没有清理 60 | 61 | 集合中的对象不使用,没有清理集合中的对象,不断往里面增加对象,导致集合会越来越大。 62 | 63 | ### 2.9 Bitmap 对象 64 | 65 | 加入创建了一个大的 Bitmap 对象,经过变换之后,等到一个新的 Bitmap,假如旧的 Bitmap 没有被回收,可能造成泄漏。 66 | 67 | ### 2.10 监听器未关闭 68 | 69 | 很多系统服务、广播、EventBud 等 注册之后没有反注册,可能会造成内存泄漏。 70 | 71 | ## 3 利用 Android Profiler 测量应用性能 72 | 73 | Android Studio 3.0 及更高版本中的 Android Profiler 取代了 Android Monitor 工具。Android Profiler 工具可提供实时数据,帮助您了解应用的 CPU、内存、网络和电池资源使用情况,我们可以在 google 开发平台查看使用。 74 | 75 | [Android Profiler](https://developer.android.google.cn/studio/profile/android-profiler) 76 | 77 | [Android Profiler内存检测](https://www.cnblogs.com/zhaozhengwu/p/10578562.html) 78 | 79 | ## 4 使用 MAT 进行内存分析 80 | 81 | 准备测试代码 82 | 83 | ```java 84 | public class MainActivity extends AppCompatActivity { 85 | 86 | @Override 87 | protected void onCreate(Bundle savedInstanceState) { 88 | super.onCreate(savedInstanceState); 89 | setContentView(R.layout.activity_main); 90 | TestThread testThread = new TestThread(); 91 | testThread.start(); 92 | } 93 | 94 | class TestThread extends Thread{ 95 | @Override 96 | public void run() { 97 | try { 98 | Thread.sleep(60*60*1000); 99 | } catch (InterruptedException e) { 100 | e.printStackTrace(); 101 | } 102 | } 103 | } 104 | } 105 | ``` 106 | 107 | 具体使用重看这篇文章 [Android Profiler mat](https://blog.csdn.net/kongbaidepao/article/details/108011943) 108 | -------------------------------------------------------------------------------- /Android/性能优化/03.绘制优化.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/Android/性能优化/03.绘制优化.md -------------------------------------------------------------------------------- /Android/性能优化/04.App启动速度优化.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/Android/性能优化/04.App启动速度优化.md -------------------------------------------------------------------------------- /Android/性能优化/05.IO优化.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/Android/性能优化/05.IO优化.md -------------------------------------------------------------------------------- /Android/性能优化/06.数据存储优化.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/Android/性能优化/06.数据存储优化.md -------------------------------------------------------------------------------- /Android/性能优化/07.SQLite优化.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/Android/性能优化/07.SQLite优化.md -------------------------------------------------------------------------------- /Android/性能优化/08.网络优化.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/Android/性能优化/08.网络优化.md -------------------------------------------------------------------------------- /Android/性能优化/09.电量优化.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/Android/性能优化/09.电量优化.md -------------------------------------------------------------------------------- /Android/性能优化/11.高效的测试.md: -------------------------------------------------------------------------------- 1 | ## 1 测试的演变 2 | 3 | ### 1.1 测试的田园时代 4 | 5 | -------------------------------------------------------------------------------- /Android/性能优化/12.发布版本优化.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/Android/性能优化/12.发布版本优化.md -------------------------------------------------------------------------------- /Android/性能优化/启动优化.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/Android/性能优化/启动优化.md -------------------------------------------------------------------------------- /Android/性能优化/电量优化.md: -------------------------------------------------------------------------------- 1 | ## 1 耗电演进历程 2 | 3 | ### 1.1 野蛮生长:Pre Android 5.0 4 | 5 | 在Android 5.0之前,系统并不是那么完善,对于电量优化还是比较少的。特别没有对应用的后台做严格的限制,多进程、fork native 进程以及广播拉起等各种保活技术。 6 | 7 | 常常有以下问题: 8 | 9 | - 耗电与安装应用程序的数量有关:用户安装越多的应用程序,无论是否打开它们,手机耗电都会更快。 10 | - App耗电量与App使用时间无关:用户希望App的耗电量应该与它的使用时间相关,但是有些应用即使常年不打开,依然非常耗电。 11 | - 电量问题排查复杂:无论是电量的测量,还是耗电问题的排查都异常艰难。 12 | 13 | 在Android 5.0之前,系统也做一些省电相关的优化。 14 | 15 | ![](../../asset/5.0电量优化.png) 16 | 17 | ### 1.2 逐步收紧:Android 5.0~Android 8.0 18 | 19 | Android 5.0 开启了一个[Volta项目](https://developer.android.com/about/versions/android-5.0?hl=zh-cn),目标是改善电池的续航。在优化电量的同时,还增加了的dumpsys batteryst等工具生成设备电池使用情况统计数据。 20 | 21 | ![](../../asset/5.0-8.0.png) 22 | 23 | 但是还存在以下问题: 24 | 25 | - 省电模式不够省电:Doze低功耗模式限制得不够严格,例如屏幕关闭还可以获取位置、后台应用的网络权限等。 26 | - 用户对应用控制力度不够:用户不能简单的对某些应用做更加细致的电量和后台行为的控制,但是其实国内很多的厂商已经提前实现了这个功能。 27 | - Target API开发者响应不积极:为了不受新版本的某些限制,大部分国内的应用坚持不把Target API升级到Oreo以上,所以很多省电的功能事实上并没有生效。 28 | 29 | ### 1.3 严格限制 9.0 30 | 31 | Android 9.0开始,Google对[电源管理](https://developer.android.com/about/versions/pie/power?hl=zh-cn)引入了几个更加严格的限制。 32 | 33 | ## 2 工具 34 | 35 | 使用 [Battery Historian](https://github.com/google/battery-historian) 进行电量分析。 36 | 37 | ```java 38 | //7.0和7.0以后 39 | $ adb bugreport bugreport.zip 40 | //6.0和6.0之前: 41 | $ adb bugreport > bugreport.txt 42 | //通过historian图形化展示结果 43 | python historian.py -a bugreport.txt > battery.html 44 | ``` 45 | 46 | - Google 推出的一款 Android 电量分析工具,它支持 Android 5.0 及以上系统的电量分析。 47 | - 它获取到的各个耗电模块的耗电信息要相对精确、丰富地多。例如 GPS、WaleLock、蓝牙 等的工作时间以及耗电量。 48 | - 此外,它不仅可以针对单个 App 进行选择,也可以比对不同的电量场景的信息,比如 优化前、优化后 的信息。 49 | - Battery Historian 的缺点在于它只能在线下使用。因此除了使用其在线下测试之外,我们还需要在线上增加一些电量的辅助监控,统计例如:耗电组件的使用次数、调用堆栈以及访问时间。这些都是与用户相关的基础电量消耗数据,如果有用户反馈,我们就可以通过这些信息来判断用户是不是有耗电的操作。 50 | 51 | ## 3 优化 52 | 53 | 我们很难在线上统计出 App 的电量消耗,而且各个手机厂商也硬件也各不相同,可以从下面四个方向考虑优化。 54 | 55 | ### 3.1 网络 56 | 57 | - 减少网络请求的时机以及次数,对网络资源进行本地缓存,减少网络的请求。 58 | - 对网络传输数据进行压缩,降低传输的时间与流量。 59 | - 禁止使用轮询的方式来做业务操作。 60 | 61 | ### 3.2 传感器 62 | 63 | 根据场景选择传感器使用的模式,比如说在使用 GPS 的时候一般要避免使用高精度的模式,或者是尽量复用上一次的定位结果。不要进行频繁的 WIFI 扫描等 64 | 65 | ### 3.3 WakeLock 66 | 67 | 使用 WakeLock 注意事项: 68 | 69 | * acquire、release 配对使用 70 | * 尽量使用 acquire 的超时方法来设置超时时间,避免因为异常情况从而导致 WakeLock 而无法释放的情况 71 | * 关于 WakeLock 的释放一定要写在 try-catch-finally 的 finally 当中,保证 WakeLock 在异常情况下的释放。 72 | 73 | ### 3.4. JobScheduler 74 | 75 | JobScheduler 可以允许开发者在符合某些条件下创造执行在后台的任务,我们可以设置执行一些耗电操作的场景,比如说 处于 WIFI 状态下同时连接电源 的情况下。同时,要注意用户在离开界面后,要避免耗电的操作,比如说停止播放动画。通过这些操作,我们的 App 就不会比之前耗电了。类似的 Alerm 76 | 77 | ## 4 耗电监控 78 | 79 | 耗电监控可以使用 Facebook 开源库 [Battery-Metrics](https://github.com/facebookincubator/Battery-Metrics)s,可以监控包括 Alarm、WakeLock、Camera、CPU、Network 等信息,而且也有收集电量充电状态、电量水平等信息。 80 | 81 | ## 参考阅读 82 | 83 | * [Android性能优化之电量篇](http://hukai.me/android-performance-battery/) 84 | * Android应用性能优化最佳实践 85 | * Android 开发高手课 86 | * [Android 优化——电量优化](https://www.jianshu.com/p/627554db9f60) 87 | 88 | -------------------------------------------------------------------------------- /Android/性能优化/绘制优化.md: -------------------------------------------------------------------------------- 1 | ## 1 简介 2 | 3 | 绘制优化主要是**界面流畅度**的优化。 4 | 5 | ## 2 绘制原理 6 | 7 | View 绘制流程:measure、layout、draw,运行在系统应用框架层,真正将数据渲染到屏幕上的是系统 Native 层 **SurfaceFlinger** 服务来完成。 8 | 9 | FPS:帧数, 1 秒时间内传输数据的图片的量,View 的最佳绘制频率为 **60fps**,要求每帧绘制时间 <= 16ms。 10 | 11 | ## 3 产生卡顿原因 12 | 13 | * 布局 Layout 过于复杂,无法在 16ms 完成渲染。 14 | * 同一个**时间动画执行的次数**过多,导致 CPU 或 GPU 负载过重。 15 | * View 过度绘制,导致某些像素在同一帧时间内被绘制多次。 16 | * 在 UI 线程中做了耗时操作。 17 | * GC 回收时暂停时间过长或者频繁的 GC 产生大量的暂停时间。 18 | 19 | ## 4 布局调优工具 20 | 21 | ### 4.1 Profile GPU Rendering 22 | 23 | Android手机上自带的一个辅助图形监测工具,用于渲染、绘制性能追踪。 24 | 25 | ### 4.2 TraceView 26 | 27 | 28 | 29 | ### 4.3 Systrace 30 | 31 | 32 | 33 | ## 5 布局优化方式 34 | 35 | ### 5.1 合理运用布局 36 | 37 | RelativeLayout 存在性能低的问题,原因是 RelativeLayout 会对子 View 做两次测量。但如果在 LinearLayout 中有 weight 属性,也需要进行两次测量,但是因为没有更多的依赖关系,所以仍然会比RelativeLayout的效率高。 38 | 39 | ### 5.2 使用 Merge 标签去除多余层级 40 | 41 | ### 5.3 使用 ViewStub 提高加载速度 42 | 43 | ### 5.4 避免 GPU 过度绘制 44 | 45 | 46 | 47 | ### 48 | 49 | 参考阅读 50 | 51 | * [Android绘制优化(一)绘制性能分析](http://liuwangshu.cn/application/performance/draw-1-performance.html) 52 | * [Android绘制优化(二)布局优化](http://liuwangshu.cn/application/performance/draw-2-layout.html) 53 | * [Android性能优化之绘制优化](https://juejin.cn/post/6844904080989487118) 54 | * [必知必会 | Android 性能优化的方面方面都在这儿](https://mp.weixin.qq.com/s/QVOYF2nfoWMCbM5YsxQgRQ?) -------------------------------------------------------------------------------- /Android/插件化.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## 1 简介 4 | 5 | 插件化技术主要用于解决应用越来越庞大以及**功能模块的解耦**,解决以下的问题: 6 | 7 | - 业务复杂,模块耦合 8 | - 应用的接入 9 | - 65536 限制,内存占用大 10 | 11 | ## 2 插件化的思想 12 | 13 | ![](../asset/手机淘宝.png) 14 | 15 | 如上图所示,手机淘宝APP 包含了主业务,以及外接的一些业务,如天猫商城,飞猪旅行等,这些外接业务可以以插件的形式存在。 16 | 17 | 插件化客户端又两部分组成: 18 | 19 | * **宿主**:先被安装到手机中的 APK,也就是普通的 APP。 20 | * **插件**:经过处理的 APK、so、和 dex 等文件。插件可以被宿主加载,也可以作为 APK 独立运行。 21 | 22 | ## 3 插件化框架对比 23 | 24 | | 特性 | VirtualApk | DroidPlugin | Small | RePlugin | 25 | | -------------------------------- | ---------- | ----------- | ---------- | ---------- | 26 | | 支持四大组件 | 全支持 | 全支持 | Activity | 全支持 | 27 | | 组件无须在宿主 manifest 中预注册 | Y | Y | Y | Y | 28 | | 插件可以依赖宿主 | Y | N | Y | Y | 29 | | 支持 PendingIntent | Y | Y | N | Y | 30 | | Android 特性支持 | 几乎全部 | 几乎全部 | 大部分 | 几乎全部 | 31 | | 兼容性适配 | 高 | 高 | 中等 | 高 | 32 | | 插件构建 | Gradle构建 | 无 | Gradle构建 | Gradle构建 | 33 | 34 | 加载插件不需要和宿主有耦合、也无须通信:Replugin。 35 | 36 | 其他情况推荐使用 VirtualApk。 37 | 38 | ## 4 Activity 插件化 39 | 40 | 三种方式: 41 | 42 | * 反射:性能问题 43 | * 接口实现 44 | * **Hook(Hook IActivityManger、Hook Instrumentation)** 45 | 46 | **根 Activity 启动过程:** 47 | 48 | ![](../asset/根Activity启动过程.png) 49 | 50 | **普通 Activity 启动过程:** 51 | 52 | ![](../asset/普通Activity创建.png) 53 | 54 | ### 4.1 Hook IActivityManager 方案实现 55 | 56 | 步骤: 57 | 58 | * 在 AndroidManifest.xml 注册 Activity 来进行占坑,用来通过 AMS 检验。 59 | * 用插件 Activity 替换占坑的 Activity。 60 | * 还原插件 Activity(hook Handler -> HCallback) 61 | 62 | ### 4.2 Hook Instrumentation 方案实现 63 | 64 | 65 | 66 | ## 5 Service 插件化 67 | 68 | 69 | 70 | ## 6 ContentProvider 插件化 71 | 72 | 73 | 74 | ## 7 BroadcastReceiver 插件化 75 | 76 | 77 | 78 | ## 8 资源插件化 79 | 80 | 81 | 82 | ## 9 so 的插件化 83 | 84 | -------------------------------------------------------------------------------- /Android/热修复.md: -------------------------------------------------------------------------------- 1 | ## 1 热修复核心 2 | 3 | * 资源修复 4 | * 代码修复 5 | * 动态链接库修复 6 | 7 | ## 2 资源修复 8 | 9 | 资源修复参考 **Instant Run** 的资源修复原理。 10 | 11 | * 创建 AssetManager,通过反射调用 addAssetPath 方法加载外部的的资源。 12 | * 将 AssetManager 类型的 mAssets 字段的引用全部替换成新创建的 AssetManager。 13 | 14 | ### 2.1 Instant Run 15 | 16 | Instant Run 是 AS 2.0 新增的运行机制,其运行如下: 17 | 18 | ![](../asset/Instantrun.png) 19 | 20 | 21 | 22 | ## 3 代码修复 23 | 24 | 代码修复主要有三个方案: 25 | 26 | * 类加载方案 27 | * 底层替换方案 28 | * Instant Run 方案 29 | 30 | ### 3.1 类加载方案 31 | 32 | **基于 Dex 分包方案** 33 | 34 | 原理: 35 | 36 | ![](../asset/类加载修复.png) 37 | 38 | ClassLoad 加载类时候,调用 DexPatchList#findClass 39 | 40 | ```java 41 | public Class findClass(String name, List suppressed) { 42 | for (Element element : dexElements) { 43 | Class clazz = element.findClass(name, definingContext, suppressed);//查找类 44 | if (clazz != null) { 45 | return clazz; 46 | } 47 | } 48 | 49 | if (dexElementsSuppressedExceptions != null) { 50 | suppressed.addAll(Arrays.asList(dexElementsSuppressedExceptions)); 51 | } 52 | return null; 53 | } 54 | ``` 55 | 56 | * Element 内部封装 DexFile,DexFile 用于加载 dex 文件,每个 dex 文件对应一个 Element; 57 | * 多个 Element 组成有序的数组 dexElements,查找类就是遍历这个数组; 58 | * Key.class 这个类有 bug,我们将 Key.class 修改之后,打一个新 dex 包 Patch.dex,放到 Element 数组的第一个,一旦查找到该类,后面那个有 bug 的 Key.class 就不会被加载从而达到修复 bug 的目的。 59 | 60 | 缺点: 61 | 62 | * 需要重启 App,不能即时生效,这是由于 App 运行时候,相关的类无法被卸载,需要重新启动 App。 63 | 64 | **Tinker原理**:新旧包做 diff,比较生成一个 patch.dex,与手机中的 APK 的 classes.dex 做合并,生成一个新的 classes.dex,反射把这个 classes.dex 放到 Element 的第一个元素。 65 | 66 | ### 3.2 底层替换方案 67 | 68 | 直接在 Native 层修改原有类。替换 ArtMenthod 结构体中的字段或者整个 ArtMethod 结构体。 69 | 70 | ### 3.3 Instant Run 方案 71 | 72 | Instant Run 在第一次构建 APK 会在每个方法中使用 AMS 注入类似的代码: 73 | 74 | ```java 75 | IncrementalChange localIncrementalChange = $change//类有修改,则不为空 76 | if(localIncrementalChange != null){ 77 | //执行修改类 78 | ... 79 | } 80 | 81 | ``` 82 | 83 | ## 4 动态链接库修复 84 | 85 | 主要应用 System 下面这两个方法: 86 | 87 | * System.load:参数是 so 在磁盘中的完整路径,加载指定路径的 so 88 | * System.loadLibrary:参数是 so 的名称,用于加载 App 安装后从 apk 包复制到 data/data/packagename/lib 目录下的 so 库 89 | 90 | 上面最后都调用 nativeLoad 这个 native 方法去加载so库, 这个方法的参数 fileName(so库在磁盘中的完整路径名)。最后调用 LoadNativeLibrary 函数加载类,方法和 类加载方案类似。 91 | 92 | 总结: 93 | 94 | * 将 so 补丁插入到 NativeLibraryElement 数组前部,让 so 补丁的路径先被返回和加载。 95 | * 调用 System 的 load 的方案来接管 so 的加载入口 -------------------------------------------------------------------------------- /Flutter/Flutter实战/03.布局类组件.md: -------------------------------------------------------------------------------- 1 | ## 1 简介 2 | 3 | 布局类组件都会包含一个或多个子组件,不同的布局类组件对子组件排版(layout)方式不同,分为三类: 4 | 5 | | Widget | 对应的Element | 用途 | 6 | | ----------------------------- | ------------------------------ | ------------------------------------------------------------ | 7 | | LeafRenderObjectWidget | LeafRenderObjectElement | Widget树的叶子节点,用于没有子节点的widget,通常基础组件都属于这一类,如Image。 | 8 | | SingleChildRenderObjectWidget | SingleChildRenderObjectElement | 包含一个子Widget,如:ConstrainedBox、DecoratedBox等 | 9 | | MultiChildRenderObjectWidget | MultiChildRenderObjectElement | 包含多个子Widget,一般都有一个children参数,接受一个Widget数组。如Row、Column、Stack等 | 10 | 11 | ## 2 线性布局 12 | 13 | * Row:类似`LinearLayout`控件 14 | * Column:垂直方向排列其子组件 15 | 16 | ```dart 17 | Row({ 18 | ... 19 | TextDirection textDirection,//子组件的布局顺序 20 | MainAxisSize mainAxisSize = MainAxisSize.max,//在主轴(水平)方向占用的空间 21 | MainAxisAlignment mainAxisAlignment = MainAxisAlignment.start,//子组件在Row所占用的水平空间内对齐方式 22 | VerticalDirection verticalDirection = VerticalDirection.down,//纵轴(垂直)的对齐方向 23 | CrossAxisAlignment crossAxisAlignment = CrossAxisAlignment.center,//子组件在纵轴方向的对齐方式 24 | List children = const [], 25 | }) 26 | ``` 27 | 28 | ## 3 弹性布局(Flex) 29 | 30 | 子组件按照一定比例来分配父容器空间,类似 Android 中的 FlexboxLayout。 31 | 32 | ```dart 33 | Flex({ 34 | ... 35 | @required this.direction, //弹性布局的方向, Row默认为水平方向,Column默认为垂直方向 36 | List children = const [], 37 | }) 38 | 39 | //Expanded 比例“扩伸” Row、Column和Flex子组件所占用的空间。 40 | const Expanded({ 41 | int flex = 1, 42 | @required Widget child, 43 | }) 44 | ``` 45 | 46 | ## 4 流式布局 47 | 48 | * Wrap 49 | * Flow 50 | 51 | ```dart 52 | Wrap( 53 | spacing: 8.0, // 主轴(水平)方向间距 54 | runSpacing: 4.0, // 纵轴(垂直)方向间距 55 | alignment: WrapAlignment.center, //沿主轴方向居中 56 | children: [ 57 | new Chip( 58 | avatar: new CircleAvatar(backgroundColor: Colors.blue, child: Text('A')), 59 | label: new Text('Hamilton'), 60 | ), 61 | new Chip( 62 | avatar: new CircleAvatar(backgroundColor: Colors.blue, child: Text('M')), 63 | label: new Text('Lafayette'), 64 | ), 65 | new Chip( 66 | avatar: new CircleAvatar(backgroundColor: Colors.blue, child: Text('H')), 67 | label: new Text('Mulligan'), 68 | ), 69 | new Chip( 70 | avatar: new CircleAvatar(backgroundColor: Colors.blue, child: Text('J')), 71 | label: new Text('Laurens'), 72 | ), 73 | ], 74 | ) 75 | ``` 76 | 77 | Flow: 78 | 79 | 很少用,过于复杂,需要自己实现子widget的位置转换,用于一些需要自定义布局策略或性能要求较高(如动画中)的场景。 80 | 81 | ## 5 层叠布局 82 | 83 | * Stack:允许子组件堆叠 84 | * Positioned 用于根据 Stack 的四个角来确定子组件的位置。 85 | 86 | ## 6 对齐与相对定位(Align) 87 | 88 | Align 组件可以调整子组件的位置,并且可以根据子组件的宽高来确定自身的的宽高,只要一个子组件。 89 | 90 | ```dart 91 | Align({ 92 | Key key, 93 | this.alignment = Alignment.center, 94 | this.widthFactor, 95 | this.heightFactor, 96 | Widget child, 97 | }) 98 | ``` 99 | 100 | -------------------------------------------------------------------------------- /Flutter/Flutter实战/04.容器类组件.md: -------------------------------------------------------------------------------- 1 | ## 1 填充(Padding) 2 | 3 | 给其子节点添加填充(留白),和边距效果类似。 4 | 5 | ```dart 6 | Padding({ 7 | ... 8 | EdgeInsetsGeometry padding,//一般使用EdgeInsets类 9 | Widget child, 10 | } 11 | ``` 12 | 13 | ### EdgeInsets 14 | 15 | - `fromLTRB(double left, double top, double right, double bottom)`:分别指定四个方向的填充。 16 | - `all(double value)` : 所有方向均使用相同数值的填充。 17 | - `only({left, top, right ,bottom })`:可以设置具体某个方向的填充(可以同时指定多个方向)。 18 | - `symmetric({ vertical, horizontal })`:用于设置对称方向的填充,`vertical`指`top`和`bottom`,`horizontal`指`left`和`right`。 19 | 20 | ## 2 尺寸限制类容器 21 | 22 | 用于限制容器大小。 23 | 24 | * ConstrainedBox:对子组件添加额外的约束 25 | 26 | * BoxConstraints:用于设置限制条件 27 | 28 | ```dart 29 | //最小高度为50,宽度尽可能大的红色容器。 30 | ConstrainedBox( 31 | constraints: BoxConstraints( 32 | minWidth: double.infinity, //宽度尽可能大 33 | minHeight: 50.0 //最小高度为50像素 34 | ), 35 | child: Container( 36 | height: 5.0, 37 | child: redBox 38 | ), 39 | ) 40 | ``` 41 | 42 | * SizedBox 43 | 44 | 用于给子元素指定固定的宽高 45 | 46 | ```dart 47 | SizedBox( 48 | width: 80.0, 49 | height: 80.0, 50 | child: redBox 51 | ) 52 | ``` 53 | 54 | * UnconstrainedBox:不会对子组件产生任何限制,它允许其子组件按照其本身大小绘制,“去除”父级限制 55 | 56 | ## 3 装饰容器DecoratedBox 57 | 58 | 可以在其子组件绘制前(或后)绘制一些装饰(Decoration),如背景、边框、渐变等 59 | 60 | ```dart 61 | const DecoratedBox({ 62 | Decoration decoration, //BoxDecoration 63 | DecorationPosition position = DecorationPosition.background, 64 | Widget child 65 | }) 66 | ``` 67 | 68 | ## 4 变换(Transform) 69 | 70 | 在其子组件绘制时对其应用一些矩阵变换来实现一些特效。 71 | 72 | * Transform.translate:平移 73 | * Transform.rotate:旋转 74 | * Transform.scale:缩放 75 | 76 | RotatedBox:是在layout阶段,会影响在子组件的位置和大小 77 | 78 | ## 5 Container 79 | 80 | 组合类容器。 81 | 82 | ```dart 83 | Container({ 84 | this.alignment, 85 | this.padding, //容器内补白,属于decoration的装饰范围 86 | Color color, // 背景色 87 | Decoration decoration, // 背景装饰 88 | Decoration foregroundDecoration, //前景装饰 89 | double width,//容器的宽度 90 | double height, //容器的高度 91 | BoxConstraints constraints, //容器大小的限制条件 92 | this.margin,//容器外补白,不属于decoration的装饰范围 93 | this.transform, //变换 94 | this.child, 95 | }) 96 | ``` 97 | 98 | ## 6 Scaffold、TabBar、底部导航 99 | 100 | * Scaffold:是一个路由页的骨架 101 | 102 | * AppBar:是一个Material风格的导航栏,通过它可以设置导航栏标题、导航栏菜单、导航栏底部的Tab标题 103 | 104 | * TabBar:快速生成Tab菜单 105 | 106 | * TabBarView:配合TabBar来实现同步切换和滑动状态同步 107 | 108 | * Drawer:抽屉菜单 109 | 110 | * FloatingActionButton:一种特殊Button,通常悬浮在页面的某一个位置作为某种常用动作的快捷入口 111 | 112 | * 通过`Scaffold`的`bottomNavigationBar`属性来设置底部导航。 113 | 114 | ```dart 115 | bottomNavigationBar: BottomAppBar( 116 | color: Colors.white, 117 | shape: CircularNotchedRectangle(), // 底部导航栏打一个圆形的洞 118 | child: Row( 119 | children: [ 120 | IconButton(icon: Icon(Icons.home)), 121 | SizedBox(), //中间位置空出 122 | IconButton(icon: Icon(Icons.business)), 123 | ], 124 | mainAxisAlignment: MainAxisAlignment.spaceAround, //均分底部导航栏横向空间 125 | ), 126 | ) 127 | ``` 128 | 129 | -------------------------------------------------------------------------------- /Git/001.reset和checkout区别.md: -------------------------------------------------------------------------------- 1 | ## 1 reset 和 checkout 区别 2 | 3 | ```python 4 | 1.checkout 对工作目录是安全的,它会通过检查来确保不会将已更改的文件弄丢;而 reset --hard 则会不做检查就全面地替换所有东西。 5 | 2.reset 会移动 HEAD 分支的指向(即 HEAD 指向的分支的指向),而 checkout 只会移动 HEAD 自身来指向另一个分支。 6 | ``` 7 | 8 | ![](../asset/git_reset_checkout.png) 9 | 10 | -------------------------------------------------------------------------------- /Git/part01/000.目录.md: -------------------------------------------------------------------------------- 1 | * [Git理论基础](001.Git理论基础.md) 2 | * [查看工作状态和历史提交](002.查看工作状态和历史提交.md) 3 | * [回到过去](003.回到过去.md) 4 | * [版本对比](004.版本对比.md) 5 | * [修改最后一次提交、删除文件和重命名](005.修改最后一次提交、删除文件和重命名.md) 6 | * [创建和切换分支](006.创建和切换分支.md) 7 | * [合并分支和删除分支](007.合并分支和删除分支.md) 8 | * [匿名分支和checkout命令](008.匿名分支和checkout命令.md) -------------------------------------------------------------------------------- /Git/part01/001.Git理论基础.md: -------------------------------------------------------------------------------- 1 | ## 1 初次使用配置 2 | 3 | 在命令行模式下输入以下命令。 4 | 5 | ```python 6 | git config --global user.name "用户名" 7 | git config --global user.email "邮箱" 8 | 9 | # 使用以下命令查看配置信息 10 | git config --list 11 | ``` 12 | 13 | ## 2 理论基础 14 | 15 | ### 2.1 Git 记录是什么 16 | 17 | Git 会将每个版本独立保存。 18 | 19 | ### 2.2 三棵树 20 | 21 | * 工作区域(Working Directory):存放项目的地方 22 | * 暂存区域(State(Index)):临时存放改动的地方 23 | * Git仓库(Repository(HEAD)):最终存放版本文件的地方 24 | 25 | ## 3 Git 工作流程 26 | 27 | ### 3.1 工作流程 28 | 29 | 1. 在工作目录中添加、修改文件 30 | 2. 将需要进行版本管理的文件放入到暂存区域 31 | 3. 将暂存区域的文件提交到 Git 仓库 32 | 33 | ### 3.2 Git 管理文件的三中状态 34 | 35 | * 已修改(modified) 36 | * 已暂存(staged) 37 | * 已提交(committed) 38 | 39 | ## 4 步骤 40 | 41 | ```python 42 | # 初始化仓库 43 | git init 44 | # 添加文件到暂存区域 45 | git add README.md 46 | # 将暂存区域的文件提交到 Git 仓库 47 | git commit -m "add a readme file" 48 | ``` 49 | 50 | -------------------------------------------------------------------------------- /Git/part01/002.查看工作状态和历史提交.md: -------------------------------------------------------------------------------- 1 | ## 1 查看状态 2 | 3 | ```python 4 | git status 5 | ``` 6 | 7 | ## 2 回退版本 8 | 9 | ```python 10 | git reset 11 | git reset HEAD # 回退到上一个版本 12 | ``` 13 | 14 | ## 3 查看历史提交 15 | 16 | ```python 17 | git log 18 | ``` 19 | 20 | ## 4 从暂存区检出 21 | 22 | ```python 23 | git checkout # 谨慎操作 会覆盖本地文件 24 | ``` 25 | 26 | -------------------------------------------------------------------------------- /Git/part01/003.回到过去.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## 1 reset 和 checkout 4 | 5 | ![](../../asset/git_reset.png) 6 | 7 | ## 2 reset 命令 8 | 9 | ```python 10 | git reset --mixed HEAD~ 11 | - 移动 HEAD 指向上一个快照 12 | - 将 HEAD 移动后指向的快照回滚到暂存区域 13 | - --mixed 为默认 可以省略 14 | - ~ 表示上一个版本、~~ 上上一个版本、~2 上两个版本 15 | 16 | git reset --soft HEAD~ 17 | - 移动 HEAD 指向上一个快照 18 | 19 | git reset --hard HEAD~ 20 | - 移动 HEAD 指向上一个快照 21 | - 将 HEAD 移动后指向的快照回滚到暂存区域 22 | - 将暂存区域的文件还原到工作目录 23 | - 危险操作,会覆盖本地工作目录 24 | 25 | # 回滚指定版本 26 | git reset 版本id 27 | # 例 28 | git reset ad7099 <- 一般前五位就可以了 29 | 30 | # 回滚个别文件 31 | git reset 版本快照 文件名/路径 32 | 33 | # 可以向前滚 34 | git reset 版本id 35 | # 例 36 | git reset --hard 6bbbc 37 | ``` 38 | 39 | -------------------------------------------------------------------------------- /Git/part01/004.版本对比.md: -------------------------------------------------------------------------------- 1 | ## 1 比较 2 | 3 | ```python 4 | # 比较暂存区域与工作目录 5 | git diff 6 | 7 | # 比较两个历史快照 8 | git diff 快照1 快照2 9 | 10 | # 比较当前工作目录和 Git 仓库中的快照 11 | git diff 快照id 12 | # 比较工作目录和最新的快照 13 | git diff HEAD 14 | 15 | # 比较暂存区域和 Git 仓库快照 16 | git diff --cache 17 | # 比较指定暂存区域和 Git 仓库快照 18 | git diff --cache 快照id 19 | ``` 20 | 21 | ![](../../asset/git_diff.png) -------------------------------------------------------------------------------- /Git/part01/005.修改最后一次提交、删除文件和重命名.md: -------------------------------------------------------------------------------- 1 | ## 1 修改最后一次提交 2 | 3 | ```python 4 | git commit --amend 5 | ``` 6 | 7 | ## 2 删除文件 8 | 9 | ```python 10 | # 只是删除了工作目录和暂存区的文件 11 | git rm 文件名 12 | 13 | # 强制删除了工作目录和暂存区的文件 14 | git rm -f 文件名 15 | 16 | # 删除暂存区的文件 17 | git rm --cached 文件名 18 | ``` 19 | 20 | ## 3 修改文件名 21 | 22 | ```python 23 | git mv 旧文件名 新文件名 24 | ``` 25 | 26 | -------------------------------------------------------------------------------- /Git/part01/006.创建和切换分支.md: -------------------------------------------------------------------------------- 1 | ## 1 创建分支 2 | 3 | ```python 4 | git branch 分支名称 5 | # 例 6 | git branch 分支1 7 | git log --all --oneline --graph # 以图形化 简洁模式 查看 8 | ``` 9 | 10 | ## 2 切换分支 11 | 12 | ```python 13 | git checkout 14 | # 例 15 | git checkout 分支1 16 | ``` 17 | 18 | -------------------------------------------------------------------------------- /Git/part01/007.合并分支和删除分支.md: -------------------------------------------------------------------------------- 1 | ## 1 合并分支 2 | 3 | ```python 4 | git merge 5 | # 例 6 | git branch 7 | * master 8 | 分支1 9 | 分支2 10 | git merge 分支1 //将 分支2 合并到 master 分支 11 | ``` 12 | 13 | ## 2 删除分支 14 | 15 | ```python 16 | git branch -d [name] 17 | # 例 18 | git branch -d 分支2 //删除 分支2 19 | ``` 20 | 21 | -------------------------------------------------------------------------------- /Git/part01/008.匿名分支和checkout命令.md: -------------------------------------------------------------------------------- 1 | ## 1 匿名分支 2 | 3 | ```python 4 | # 例 5 | $ git add 1.txt 6 | $ git commit -m "1.txt" 7 | 8 | $ git add 2.txt 9 | $ git commit -m "2.txt" 10 | 11 | $ git add 3.txt 12 | $ git commit -m "3.txt" 13 | 14 | $ git log --online --all --graph 15 | * 485c78e (HEAD -> master) 3.txt 16 | * abcf805 2.txt 17 | * a742c31 1.txt 18 | 19 | $ git checkout HEAD~ 20 | Note: checking out 'HEAD~'. 21 | 22 | You are in 'detached HEAD' state. You can look around, make experimental 23 | changes and commit them, and you can discard any commits you make in this 24 | state without impacting any branches by performing another checkout. 25 | 26 | If you want to create a new branch to retain commits you create, you may 27 | do so (now or later) by using -b with the checkout command again. Example: 28 | 29 | git checkout -b 30 | 31 | HEAD is now at abcf805... 2.txt 32 | # 使用了 checkout 命令但没有指定分支名, Git 会自动创建了一个匿名分支,当切换到别的分支时,这个匿名分支中的所有提交都会被丢弃掉。 33 | # 作用:用于测试、实验性代码时候 34 | ``` 35 | 36 | ## 2 checkout 37 | 38 | * 从历史快照(或暂存区域)中拷贝文件到工作目录 39 | * 切换分支 40 | 41 | ```python 42 | 1.当给定某个文件名时,Git 会指定的提交文件中拷贝到暂存区域和工作目录,比如 git checkout HEAD~。 43 | 2.没有指定具体的快照 ID,则将中暂存区域恢复指定文件到工作目录。 44 | ``` 45 | 46 | ## 3 reset 和 checkout 区别 47 | 48 | ```python 49 | 1.checkout 对工作目录是安全的,它会通过检查来确保不会将已更改的文件弄丢;而 reset --hard 则会不做检查就全面地替换所有东西。 50 | 2.reset 会移动 HEAD 分支的指向(即 HEAD 指向的分支的指向),而 checkout 只会移动 HEAD 自身来指向另一个分支。 51 | ``` 52 | 53 | ![](../../asset/git_reset_checkout.png) 54 | 55 | -------------------------------------------------------------------------------- /Git/part02/000.目录.md: -------------------------------------------------------------------------------- 1 | * [基本操作](001.基本操作.md) 2 | * [分支管理](002.分支管理.md) 3 | * [标签](003.标签.md) 4 | 5 | -------------------------------------------------------------------------------- /Git/part02/002.分支管理.md: -------------------------------------------------------------------------------- 1 | ## 1 git branch 2 | 3 | ```java 4 | //1.创建分支 5 | git branch [name] 6 | //例 7 | git branch 分支1 8 | 9 | //2.列出分支 10 | git branch 11 | ``` 12 | 13 | ## 2 git checkout 14 | 15 | 切换分支 16 | 17 | ```java 18 | git checkout [name] 19 | //例 20 | git checkout master 21 | 22 | //创建新分支并立即切换到该分支下 23 | git checkout -b [branchname] 24 | git checkout -b 分支2 25 | ``` 26 | 27 | ## 3 git merge 28 | 29 | 合并分支 30 | 31 | ```java 32 | git merge 33 | //例 34 | $ git branch 35 | * master 36 | 分支1 37 | 分支2 38 | $ git merge 分支1 //将 分支2 合并到 master 分支 39 | ``` 40 | 41 | ## 4 git branch -d 42 | 43 | 删除分支 44 | 45 | ```java 46 | git branch -d [name] 47 | //例 48 | git branch -d 分支2 //删除 分支2 49 | ``` 50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /Git/part02/003.标签.md: -------------------------------------------------------------------------------- 1 | ## 1 简介 2 | 3 | 项目一个阶段开发完成,要发布了,可以使用 git tag 打标签。 4 | 5 | ## 2 常用操作 6 | 7 | ```java 8 | //1.打标签 9 | git tag -a v1.0 //-a 创建一个带注解的标签 10 | 11 | //2.追加标签 12 | git tag -a v1.1 64ee //如果忘了给某个提交打标签,又将它发布了,我们可以给它追加标签 13 | 14 | //3.查看所有标签 15 | git tag 16 | 17 | //4.删除标签 18 | git tag -d v1.0 19 | 20 | //5.查看此版本所修改的内容 21 | git show v1.1 22 | 23 | //6.指定标签信息 24 | git tag -a [name] -m "信息" 25 | //例 26 | git tag -a v2.0 -m "支付功能完成发布" 27 | ``` 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /Gradle/000.目录.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/Gradle/000.目录.md -------------------------------------------------------------------------------- /Gradle/part01/000.目录.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/Gradle/part01/000.目录.md -------------------------------------------------------------------------------- /Gradle/part01/001.Gradle 版 Hello World.md: -------------------------------------------------------------------------------- 1 | ## 1 步骤 2 | 1. 下载 Gradle 3 | 2. 配置系统环境 4 | 3. 新建 build.gradle 5 | ```Groovy 6 | task hello { //执行一个名称为 hello 的 Task(任务) 7 | doLast{ 8 | println 'Hello World!' 9 | } 10 | } 11 | ``` 12 | 13 | 4. 使用 gradle -q hello 执行任务 14 | 15 | ![](../../asset/gradle.png) 16 | -------------------------------------------------------------------------------- /Gradle/part01/001.Gradle基础.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/Gradle/part01/001.Gradle基础.md -------------------------------------------------------------------------------- /Gradle/part01/002.Gradle Wrapper.md: -------------------------------------------------------------------------------- 1 | ## 1 Wrapper 2 | 就是对 Gradle 的一层包装,在开发中统一 Gradle 构建的版本。 3 | 4 | ## 2 生成 Wrapper 5 | 使用 gradle wrapper 生成。 6 | 7 | ![](../../asset/wrapper.png) 8 | 9 | 10 | 11 | ![](../../asset/wrappertest.png) 12 | 13 | ```groovy 14 | //wrapper 配置 15 | --gradle-version 指定版本 16 | --gradle-distribution-url 指定下载的地址 17 | ``` 18 | 19 | ## 3 gradle-wrapper.properties 配置文件 20 | 21 | ```gr 22 | //下载 Gradle 压缩包解压后存储的主目录 23 | distributionBase=GRADLE_USER_HOME 24 | //Gradle 压缩包路径 25 | distributionPath=wrapper/dists 26 | //同 distributionBase ,存放的是 zip 27 | zipStoreBase=GRADLE_USER_HOME 28 | //同 distributionPath ,存放的是 zip 29 | zipStorePath=wrapper/dists 30 | //指定 Gradle 下载的地址 31 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.7.1-bin.zip 32 | ``` 33 | 34 | -------------------------------------------------------------------------------- /Gradle/part01/003.Gradle 日志.md: -------------------------------------------------------------------------------- 1 | ## 1日志级别 2 | 3 | | 级别 | 作用 | 4 | | --------- | ---- | 5 | | ERROR | 错误 | 6 | | QUIET | 重要 | 7 | | WARNING | 警告 | 8 | | LIFECYCLE | 进度 | 9 | | INFO | 信息 | 10 | | DEBUG | 调试 | 11 | 12 | ```groovy 13 | 例: 14 | #输出 QUIET 级别及以上的日志 15 | gradle -q tasks 16 | ``` 17 | 18 | 19 | 20 | ## 2 输出错误堆栈信息 21 | 22 | ```gr 23 | -s 或者 --stacktrace 关键堆栈信息(推荐使用) 24 | -S 或者 --full-stacktrace 全部堆栈信息 25 | ``` 26 | 27 | ## 3 使用日志调试 28 | 29 | ```groovy 30 | println('println') 31 | logger.quiet('quiet日志信息.') 32 | logger.error('error日志信息.') 33 | logger.warn('warn日志信息.') 34 | logger.lifecycle('lifecycle日志信息.') 35 | logger.info('info日志信息.') 36 | logger.debug('debug日志信息.') 37 | ``` 38 | 39 | -------------------------------------------------------------------------------- /Gradle/part01/004.Gradle 命令行.md: -------------------------------------------------------------------------------- 1 | ## 1 命令 2 | 3 | ```gr 4 | //1.帮助 5 | ./gradlew -? 6 | ./gradlew -h 7 | ./gradlew -help 8 | 9 | //2.查看所有可执行的 Tasks 10 | ./gradlew tasks 11 | 12 | //3.Gradle Help 任务:帮助 Task 使用 13 | ./gradlew help -task 14 | 15 | //5.强制刷新依赖 16 | ./gradlew --refresh-dependencies assemble 17 | 18 | //6.多任务调用 19 | 例如先 clean 再生成 jar 20 | ./gradlew clean jar 21 | 22 | //7.通过任务名字缩写执行:任务名字太长,可以缩写 23 | ./gradlew connectCheck = ./gradlew cc 24 | ``` 25 | 26 | -------------------------------------------------------------------------------- /Gradle/part01/004.Gradle构建脚本基础.md: -------------------------------------------------------------------------------- 1 | ## 1 Settings 文件 2 | 3 | 配置工程的子模块 4 | 5 | ```groovy 6 | //setting.gradle 7 | include ':app', ':module_base' 8 | 9 | ``` 10 | 11 | 12 | -------------------------------------------------------------------------------- /Gradle/part01/005.Groovy基础_字符串.md: -------------------------------------------------------------------------------- 1 | ## 1 简介 2 | 3 | Groovy 是基于 JVM 虚拟机一种动态语言,语法和 Java 非常相似,而且兼容 Java。 4 | 5 | ## 2 字符串 6 | 7 | ```groovy 8 | //1.新建 build.gradle 9 | task printStringClass << { 10 | def s1 = '单引号' 11 | def s2 = "双引号" 12 | println s1.getClass().name 13 | println s2.getClass().name 14 | } 15 | //2.gradle wrapper 16 | //3.gradlew printStringClass 17 | //4.输出 18 | java.lang.String 19 | java.lang.String 20 | 21 | //注:单引号不能运算 22 | task printStringVar << { 23 | def name = "张三" 24 | println '${name}' 25 | println "${name}" 26 | } 27 | //输出 28 | ${name} 29 | 张三 30 | ``` 31 | 32 | -------------------------------------------------------------------------------- /Gradle/part01/006.Groovy基础_集合.md: -------------------------------------------------------------------------------- 1 | ## 1 集合 2 | 3 | Groovy 完全兼容 Java 集合,并且进行的扩展。 4 | 5 | ```groovy 6 | //1.List 7 | task printList << { 8 | def numList = [1,2,3]; 9 | println numList.getClass().name //类型 10 | println numList[1] //下标为 1 11 | println numList[-1] //倒数第 1 个 12 | println numList[1..2] //第 1 个 到 第 3 个 13 | numList.each{ //遍历 14 | println it 15 | } 16 | } 17 | //输出: 18 | java.util.ArrayList 19 | 2 20 | 3 21 | [2] 22 | 1 23 | 2 24 | 3 25 | 26 | //2.map 27 | task printMap << { 28 | def map = ['name':'Java','price':"90.00"]; 29 | println map.getClass().name 30 | println map['name'] 31 | println map.price 32 | map.each{ 33 | println "${it.key}:${it.value}" 34 | } 35 | } 36 | //输出: 37 | java.util.LinkedHashMap 38 | Java 39 | 90.00 40 | name:Java 41 | price:90.00 42 | ``` 43 | 44 | -------------------------------------------------------------------------------- /Gradle/part01/007.Groovy基础_方法.md: -------------------------------------------------------------------------------- 1 | ## 1 方法 2 | 3 | Groovy 完全兼容 Java 集合,并且进行的扩展。 4 | 5 | ```groovy 6 | //1.定义一个方法 7 | def method(int a,int b){ 8 | println a + b 9 | } 10 | task invokeMethod << { 11 | method(1,2) 12 | method 1,2 //可以省略() 13 | } 14 | 15 | //2.可以省略 return 16 | def method1(int a,int b){ 17 | if(a > b){ 18 | a //和 Kotlin 一样 19 | } else { 20 | b 21 | } 22 | } 23 | 24 | task invokeMethod1 { 25 | def m1 = method1 1,2 26 | def m2 = method1 6,2 27 | println "$m1,$m2" 28 | } 29 | //输出: 30 | 2,6 31 | 32 | //3.代码块可以作为参数 33 | numList.each({println it}) 34 | //简化 35 | numList.each { 36 | println it 37 | } 38 | ``` 39 | 40 | -------------------------------------------------------------------------------- /Gradle/part01/008.Groovy基础_JavaBean.md: -------------------------------------------------------------------------------- 1 | ## 1 JavaBean 2 | 3 | ```groovy 4 | class Person { 5 | private String name; //和 Java 不同,默认就有 getter/setter 6 | private int age; 7 | } 8 | task taskPerson { 9 | Person p = new Person() 10 | p.name = '张三' 11 | p.age = 22 12 | println "$p.name;$p.age" 13 | } 14 | //out: 15 | 张三;22 16 | ``` 17 | 18 | -------------------------------------------------------------------------------- /Gradle/part01/009.Groovy基础_闭包.md: -------------------------------------------------------------------------------- 1 | ## 1 闭包 2 | 3 | 方法做参数。 4 | 5 | ```groovy 6 | task helloClosure { 7 | //使用闭包 8 | customEach { //默认参数 it 9 | println it 10 | } 11 | } 12 | //自定义闭包 13 | def customEach(closure){ 14 | for(int i in 1..10){ 15 | closure(i) 16 | } 17 | } 18 | //out: 19 | 1 20 | 2 21 | 3 22 | 4 23 | 5 24 | 6 25 | 7 26 | 8 27 | 9 28 | 10 29 | ``` 30 | 31 | ## 2 向闭包传参数 32 | 33 | ```groovy 34 | task closureMap { 35 | mapEach{k,v -> 36 | println "$k,$v" 37 | } 38 | } 39 | def mapEach(closure){ 40 | def map = ['name':'Java','price':"90.00"]; 41 | map.each{ 42 | closure(it.key,it.value) 43 | } 44 | } 45 | //out: 46 | name,Java 47 | price,90.00 48 | ``` 49 | 50 | ## 3 闭包委托 51 | 52 | Groovy 闭包支持方法的委托,有 thisObject、owner、delegate 三个属性。delegate 和 owner 是相等的,但是 delegate 可以被修改。 53 | 54 | ```groovy 55 | class Student{ 56 | private String name; 57 | private int age; 58 | 59 | def dumpStudent(){ 60 | println "${name};${age}" 61 | } 62 | } 63 | 64 | task configClosure { 65 | student{ 66 | name = "张三" 67 | age = 58 68 | dumpStudent() 69 | } 70 | } 71 | 72 | def student(Closure closure){ 73 | Student s = new Student() 74 | closure.delegate = s 75 | //委托优先 76 | closure.setResolveStrategy(Closure.DELEGATE_FIRST) 77 | closure(s) 78 | } 79 | //out: 80 | 张三;58 81 | ``` 82 | 83 | -------------------------------------------------------------------------------- /Gradle/part01/010.DSL.md: -------------------------------------------------------------------------------- 1 | ## 1 DSL 2 | 3 | DSL:领域特定语言,专门关注某一领域的语言,在于专,不在全。 -------------------------------------------------------------------------------- /Gradle/part01/011.Settings文件.md: -------------------------------------------------------------------------------- 1 | ## 1 Settings 文件 2 | 配置工程的子模块 3 | ```groovy 4 | //setting.gradle 5 | include ':app', ':module_base' 6 | 7 | ``` 8 | -------------------------------------------------------------------------------- /Java/CopyOnWriteArrayList.md: -------------------------------------------------------------------------------- 1 | ## 1 简介 2 | 3 | CopyOnWriteArrayList 在 JUC 包下,支持并发的 List,它是个**线程安全**,读操作通过无锁的 ArrayList,写操作通过**创建底层数组副本**,是一种**读写分离**的并发策略,称这种容器为"**写时复制器**"。由于这个特性,CopyOnWriteArrayList 适用于**读多写少**的并发场景。但是也有缺点,一是内存占用,每次写都要创建副本,二是无法**保证实时性**。 4 | 5 | ## 2 源码 6 | 7 | ### 2.1 add 8 | 9 | ```java 10 | public boolean add(E e) { 11 | //使用 ReentrantLock 加锁,保证线程安全 12 | final ReentrantLock lock = this.lock; 13 | lock.lock(); 14 | try { 15 | Object[] elements = getArray(); 16 | int len = elements.length; 17 | //拷贝原容器,长度为原容器长度加一 18 | Object[] newElements = Arrays.copyOf(elements, len + 1); 19 | //在新副本上执行添加操作 20 | newElements[len] = e; 21 | //将原容器引用指向新副本 22 | setArray(newElements); 23 | return true; 24 | } finally { 25 | //解锁 26 | lock.unlock(); 27 | } 28 | } 29 | } 30 | ``` 31 | 32 | ### 2.2 remove 33 | 34 | ```java 35 | public E remove(int index) { 36 | //使用 ReentrantLock 加锁,保证线程安全 37 | final ReentrantLock lock = this.lock; 38 | lock.lock(); 39 | try { 40 | Object[] elements = getArray(); 41 | int len = elements.length; 42 | E oldValue = get(elements, index); 43 | int numMoved = len - index - 1; 44 | if (numMoved == 0) 45 | //如果要删除的是列表末端数据,拷贝前len-1个数据到新副本上,再切换引用 46 | setArray(Arrays.copyOf(elements, len - 1)); 47 | else { 48 | //否则,将除要删除元素之外的其他元素拷贝到新副本中,并切换引用 49 | Object[] newElements = new Object[len - 1]; 50 | System.arraycopy(elements, 0, newElements, 0, index); 51 | System.arraycopy(elements, index + 1, newElements, index, 52 | numMoved); 53 | setArray(newElements); 54 | } 55 | return oldValue; 56 | } finally { 57 | //解锁 58 | lock.unlock(); 59 | } 60 | } 61 | } 62 | ``` 63 | 64 | ### 2.3 get 65 | 66 | ```java 67 | //直接读取,无需加锁 68 | public E get(int index) { 69 | return get(getArray(), index); 70 | } 71 | 72 | private E get(Object[] a, int index) { 73 | return (E) a[index]; 74 | } 75 | ``` 76 | 77 | -------------------------------------------------------------------------------- /Java/synchronized锁升级优化.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/Java/synchronized锁升级优化.md -------------------------------------------------------------------------------- /Java/异常体系.md: -------------------------------------------------------------------------------- 1 | #### 1 分类 2 | 3 | * Error: JVM 无法处理的错误 4 | * Exception: 5 | * **受检异常** :需要用 try…catch… 语句捕获并进行处理,并且可以从异常中恢复 6 | * **非受检异常** :是程序运行时错误,例如空指针异常。 7 | 8 | ![](../asset/check.jpg) 9 | 10 | #### 2 异常处理 11 | 12 | * Error(错误):一般表示代码运行时 JVM 出现问题。比如 NoClassDefFoundError 等。比如说当jvm耗完可用内存时,将出现 OutOfMemoryError。此类错误发生时,JVM将终止线程。 13 | 14 | * 非受检异常:将由系统自动抛出,应用本身可以选择处理或者忽略该异常。 15 | 16 | * 受检异常:进行捕获或者抛出该方法之外交给上层处理。要么使用 try-catch 捕获,要么 throws 该异常。 17 | 18 | #### 3 常见的受检异常 19 | 20 | ![](../asset/受检异常.webp.jpg) 21 | 22 | #### 4 常见非受检异常 23 | 24 | ![](../asset/非受检异常.webp.jpg) -------------------------------------------------------------------------------- /Python/一个图片爬虫例子.md: -------------------------------------------------------------------------------- 1 | ```python 2 | import requests 3 | import re 4 | import os 5 | import time 6 | 7 | headers = { 8 | 'User-Agent': "Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko" 9 | } 10 | 11 | """请求网页""" 12 | #response = requests.get("https://www.vmgirls.com/15198.html", headers=headers) 13 | response = requests.get("https://www.vmgirls.com/15270.html", headers=headers) 14 | html = response.text 15 | # print(html) 16 | 17 | """解析网页""" 18 | #dir_name = re.findall('(.*?)', html)[-1] 19 | dir_name = re.findall('

(.*?)

',html)[-1] 20 | if not os.path.exists(dir_name): 21 | os.mkdir(dir_name) 22 | 23 | urls = re.findall('', html) 24 | print(urls) 25 | 26 | """保存图片""" 27 | for url in urls: 28 | time.sleep(2) 29 | file_name = url.split('/')[-1] # 文件命名 30 | print("https:" + url) 31 | response = requests.get("https:" + url, headers=headers) 32 | with open(dir_name + '/' + file_name, 'wb') as f: 33 | f.write(response.content) 34 | f.close() 35 | 36 | 37 | # 遍历目录 38 | def walkFile(file): 39 | list = [] 40 | for root, dirs, files in os.walk(file): 41 | for f in files: 42 | name = "{}".format(f).split('.')[-2] 43 | list.append("* [{}](计算机网络/{})".format(name, f)) 44 | return list 45 | 46 | 47 | if __name__ == '__main__': 48 | file = "C:\\Users\zpparts\Desktop\SoleilNotes\计算机网络" 49 | list = walkFile(file) 50 | for v in list: 51 | print(v) 52 | 53 | ``` 54 | 55 | -------------------------------------------------------------------------------- /asset/1.6内存区域.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/1.6内存区域.png -------------------------------------------------------------------------------- /asset/1.7hash链表.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/1.7hash链表.png -------------------------------------------------------------------------------- /asset/1.8hash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/1.8hash.png -------------------------------------------------------------------------------- /asset/1.8hash1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/1.8hash1.png -------------------------------------------------------------------------------- /asset/1.8内存区域.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/1.8内存区域.png -------------------------------------------------------------------------------- /asset/17CM.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/17CM.png -------------------------------------------------------------------------------- /asset/5.0-8.0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/5.0-8.0.png -------------------------------------------------------------------------------- /asset/5.0电量优化.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/5.0电量优化.png -------------------------------------------------------------------------------- /asset/ABA.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/ABA.png -------------------------------------------------------------------------------- /asset/Actiovity构成.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/Actiovity构成.png -------------------------------------------------------------------------------- /asset/Activity启动过程.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/Activity启动过程.png -------------------------------------------------------------------------------- /asset/Activity栈.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/Activity栈.png -------------------------------------------------------------------------------- /asset/Activity组成.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/Activity组成.png -------------------------------------------------------------------------------- /asset/Android系统启动流程.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/Android系统启动流程.png -------------------------------------------------------------------------------- /asset/Atomic类.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/Atomic类.png -------------------------------------------------------------------------------- /asset/CachedThreadPool.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/CachedThreadPool.png -------------------------------------------------------------------------------- /asset/DNS层次结构.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/DNS层次结构.jpg -------------------------------------------------------------------------------- /asset/Hook.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/Hook.png -------------------------------------------------------------------------------- /asset/IO体系.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/IO体系.png -------------------------------------------------------------------------------- /asset/IO控制方式.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/IO控制方式.png -------------------------------------------------------------------------------- /asset/Instantrun.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/Instantrun.png -------------------------------------------------------------------------------- /asset/JVMGC.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/JVMGC.png -------------------------------------------------------------------------------- /asset/JVM内存1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/JVM内存1.png -------------------------------------------------------------------------------- /asset/JVM内存2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/JVM内存2.png -------------------------------------------------------------------------------- /asset/UDP数据报格式.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/UDP数据报格式.png -------------------------------------------------------------------------------- /asset/View体系.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/View体系.png -------------------------------------------------------------------------------- /asset/WindowManager.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/WindowManager.png -------------------------------------------------------------------------------- /asset/android-stack_2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/android-stack_2x.png -------------------------------------------------------------------------------- /asset/apk签名过程.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/apk签名过程.jpg -------------------------------------------------------------------------------- /asset/binder机制.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/binder机制.jpg -------------------------------------------------------------------------------- /asset/c.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/c.jpg -------------------------------------------------------------------------------- /asset/c_数据类型.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/c_数据类型.png -------------------------------------------------------------------------------- /asset/ca.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/ca.png -------------------------------------------------------------------------------- /asset/channel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/channel.png -------------------------------------------------------------------------------- /asset/check.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/check.jpg -------------------------------------------------------------------------------- /asset/context.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/context.jpg -------------------------------------------------------------------------------- /asset/context继承.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/context继承.png -------------------------------------------------------------------------------- /asset/c数据类型.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/c数据类型.png -------------------------------------------------------------------------------- /asset/c编译过程.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/c编译过程.png -------------------------------------------------------------------------------- /asset/dart线程模型.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/dart线程模型.jpg -------------------------------------------------------------------------------- /asset/dump.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/dump.png -------------------------------------------------------------------------------- /asset/event.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/event.jpg -------------------------------------------------------------------------------- /asset/executor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/executor.png -------------------------------------------------------------------------------- /asset/final-architecture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/final-architecture.png -------------------------------------------------------------------------------- /asset/gc root.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/gc root.png -------------------------------------------------------------------------------- /asset/git_diff.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/git_diff.png -------------------------------------------------------------------------------- /asset/git_reset.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/git_reset.png -------------------------------------------------------------------------------- /asset/git_reset_checkout.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/git_reset_checkout.png -------------------------------------------------------------------------------- /asset/git基本操作.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/git基本操作.png -------------------------------------------------------------------------------- /asset/gradle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/gradle.png -------------------------------------------------------------------------------- /asset/handler.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/handler.png -------------------------------------------------------------------------------- /asset/http.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/http.png -------------------------------------------------------------------------------- /asset/http2.0.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/http2.0.jpg -------------------------------------------------------------------------------- /asset/https.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/https.png -------------------------------------------------------------------------------- /asset/https原理.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/https原理.png -------------------------------------------------------------------------------- /asset/http报文结构.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/http报文结构.jpg -------------------------------------------------------------------------------- /asset/http请求.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/http请求.jpg -------------------------------------------------------------------------------- /asset/iostream2xx.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/iostream2xx.png -------------------------------------------------------------------------------- /asset/ip互联.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/ip互联.png -------------------------------------------------------------------------------- /asset/javacrash.jfif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/javacrash.jfif -------------------------------------------------------------------------------- /asset/java线程的状态.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/java线程的状态.png -------------------------------------------------------------------------------- /asset/java编译.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/java编译.png -------------------------------------------------------------------------------- /asset/jetpack.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/jetpack.jpg -------------------------------------------------------------------------------- /asset/linux目录结构.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/linux目录结构.jpg -------------------------------------------------------------------------------- /asset/mvc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/mvc.png -------------------------------------------------------------------------------- /asset/mvp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/mvp.png -------------------------------------------------------------------------------- /asset/mvvm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/mvvm.png -------------------------------------------------------------------------------- /asset/newFixedThreadPool.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/newFixedThreadPool.png -------------------------------------------------------------------------------- /asset/newSingleThreadExecutor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/newSingleThreadExecutor.png -------------------------------------------------------------------------------- /asset/next.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/next.png -------------------------------------------------------------------------------- /asset/okhttp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/okhttp.png -------------------------------------------------------------------------------- /asset/oopxxx.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/oopxxx.png -------------------------------------------------------------------------------- /asset/osi模式.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/osi模式.png -------------------------------------------------------------------------------- /asset/p2p和cs.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/p2p和cs.jpg -------------------------------------------------------------------------------- /asset/pcb内容.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/pcb内容.png -------------------------------------------------------------------------------- /asset/sche2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/sche2.png -------------------------------------------------------------------------------- /asset/scrr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/scrr.png -------------------------------------------------------------------------------- /asset/service.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/service.png -------------------------------------------------------------------------------- /asset/service启动过程.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/service启动过程.png -------------------------------------------------------------------------------- /asset/servie生命周期.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/servie生命周期.png -------------------------------------------------------------------------------- /asset/tcpip.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/tcpip.png -------------------------------------------------------------------------------- /asset/tcpip和osi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/tcpip和osi.png -------------------------------------------------------------------------------- /asset/tcp报文.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/tcp报文.png -------------------------------------------------------------------------------- /asset/tcp报文段.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/tcp报文段.png -------------------------------------------------------------------------------- /asset/topbanner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/topbanner.png -------------------------------------------------------------------------------- /asset/udp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/udp.png -------------------------------------------------------------------------------- /asset/v1签名.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/v1签名.png -------------------------------------------------------------------------------- /asset/v2签名.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/v2签名.jpg -------------------------------------------------------------------------------- /asset/v3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/v3.png -------------------------------------------------------------------------------- /asset/view坐标.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/view坐标.png -------------------------------------------------------------------------------- /asset/wrapper.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/wrapper.png -------------------------------------------------------------------------------- /asset/wrappertest.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/wrappertest.png -------------------------------------------------------------------------------- /asset/www.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/www.jpg -------------------------------------------------------------------------------- /asset/三次握手.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/三次握手.png -------------------------------------------------------------------------------- /asset/三种常用的数据编码方式.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/三种常用的数据编码方式.png -------------------------------------------------------------------------------- /asset/三种数据交换的方式.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/三种数据交换的方式.png -------------------------------------------------------------------------------- /asset/两级目录结构.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/两级目录结构.jpg -------------------------------------------------------------------------------- /asset/中断.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/中断.png -------------------------------------------------------------------------------- /asset/中断处理过程.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/中断处理过程.png -------------------------------------------------------------------------------- /asset/二叉查找树.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/二叉查找树.png -------------------------------------------------------------------------------- /asset/二叉查找树问题.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/二叉查找树问题.png -------------------------------------------------------------------------------- /asset/五层协议.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/五层协议.png -------------------------------------------------------------------------------- /asset/代理模式.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/代理模式.png -------------------------------------------------------------------------------- /asset/以存储器为中心的计算机结构.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/以存储器为中心的计算机结构.png -------------------------------------------------------------------------------- /asset/使用示意.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/使用示意.png -------------------------------------------------------------------------------- /asset/依赖关系.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/依赖关系.png -------------------------------------------------------------------------------- /asset/保活.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/保活.png -------------------------------------------------------------------------------- /asset/典型冯诺依曼机.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/典型冯诺依曼机.png -------------------------------------------------------------------------------- /asset/内存模型.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/内存模型.png -------------------------------------------------------------------------------- /asset/加密方式.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/加密方式.png -------------------------------------------------------------------------------- /asset/协议接口服务.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/协议接口服务.png -------------------------------------------------------------------------------- /asset/单向关联.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/单向关联.png -------------------------------------------------------------------------------- /asset/单模光纤.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/单模光纤.png -------------------------------------------------------------------------------- /asset/单级目录结构.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/单级目录结构.jpg -------------------------------------------------------------------------------- /asset/双向关联.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/双向关联.png -------------------------------------------------------------------------------- /asset/双绞线.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/双绞线.png -------------------------------------------------------------------------------- /asset/受检异常.webp.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/受检异常.webp.jpg -------------------------------------------------------------------------------- /asset/右旋.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/右旋.gif -------------------------------------------------------------------------------- /asset/同轴电缆.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/同轴电缆.png -------------------------------------------------------------------------------- /asset/四次挥手.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/四次挥手.png -------------------------------------------------------------------------------- /asset/域名解析过程.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/域名解析过程.jpg -------------------------------------------------------------------------------- /asset/复制.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/复制.png -------------------------------------------------------------------------------- /asset/多模光纤.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/多模光纤.png -------------------------------------------------------------------------------- /asset/实现关系.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/实现关系.png -------------------------------------------------------------------------------- /asset/对象的创建.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/对象的创建.png -------------------------------------------------------------------------------- /asset/对象的访问.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/对象的访问.png -------------------------------------------------------------------------------- /asset/小顶堆.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/小顶堆.jpg -------------------------------------------------------------------------------- /asset/小顶堆.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/小顶堆.png -------------------------------------------------------------------------------- /asset/左旋.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/左旋.gif -------------------------------------------------------------------------------- /asset/左旋右旋规则.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/左旋右旋规则.png -------------------------------------------------------------------------------- /asset/常用的系统服务1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/常用的系统服务1.png -------------------------------------------------------------------------------- /asset/常用的系统服务2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/常用的系统服务2.png -------------------------------------------------------------------------------- /asset/应用层协议.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/应用层协议.jpg -------------------------------------------------------------------------------- /asset/循环队列.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/循环队列.png -------------------------------------------------------------------------------- /asset/快恢复.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/快恢复.png -------------------------------------------------------------------------------- /asset/慢开始.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/慢开始.png -------------------------------------------------------------------------------- /asset/手机淘宝.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/手机淘宝.png -------------------------------------------------------------------------------- /asset/拓扑.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/拓扑.png -------------------------------------------------------------------------------- /asset/指令执行.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/指令执行.png -------------------------------------------------------------------------------- /asset/控制连接.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/控制连接.jpg -------------------------------------------------------------------------------- /asset/操作系统历史.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/操作系统历史.png -------------------------------------------------------------------------------- /asset/数字签名.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/数字签名.png -------------------------------------------------------------------------------- /asset/数字调制.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/数字调制.png -------------------------------------------------------------------------------- /asset/数据编码.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/数据编码.png -------------------------------------------------------------------------------- /asset/无环图目录结构.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/无环图目录结构.jpg -------------------------------------------------------------------------------- /asset/时隙ALOHA.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/时隙ALOHA.png -------------------------------------------------------------------------------- /asset/普通Activity创建.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/普通Activity创建.png -------------------------------------------------------------------------------- /asset/标记整理.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/标记整理.png -------------------------------------------------------------------------------- /asset/标记清除.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/标记清除.png -------------------------------------------------------------------------------- /asset/树形目录结构.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/树形目录结构.jpg -------------------------------------------------------------------------------- /asset/校验.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/校验.png -------------------------------------------------------------------------------- /asset/根Activity启动过程.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/根Activity启动过程.png -------------------------------------------------------------------------------- /asset/模型.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/模型.png -------------------------------------------------------------------------------- /asset/死锁.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/死锁.png -------------------------------------------------------------------------------- /asset/消息机制.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/消息机制.png -------------------------------------------------------------------------------- /asset/电子邮件.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/电子邮件.jpg -------------------------------------------------------------------------------- /asset/电子邮件发送接收过程.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/电子邮件发送接收过程.jpg -------------------------------------------------------------------------------- /asset/磁盘结构.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/磁盘结构.jpg -------------------------------------------------------------------------------- /asset/程序装入过程.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/程序装入过程.jpg -------------------------------------------------------------------------------- /asset/类加载修复.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/类加载修复.png -------------------------------------------------------------------------------- /asset/类加载器.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/类加载器.png -------------------------------------------------------------------------------- /asset/类图.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/类图.png -------------------------------------------------------------------------------- /asset/类生命周期.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/类生命周期.png -------------------------------------------------------------------------------- /asset/系统结构.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/系统结构.png -------------------------------------------------------------------------------- /asset/纯ALOHA.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/纯ALOHA.png -------------------------------------------------------------------------------- /asset/线程.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/线程.png -------------------------------------------------------------------------------- /asset/线程模型.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/线程模型.png -------------------------------------------------------------------------------- /asset/线程池执行的过程.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/线程池执行的过程.png -------------------------------------------------------------------------------- /asset/线程状态转换.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/线程状态转换.png -------------------------------------------------------------------------------- /asset/线程调度.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/线程调度.png -------------------------------------------------------------------------------- /asset/组件化.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/组件化.png -------------------------------------------------------------------------------- /asset/组件化架构.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/组件化架构.png -------------------------------------------------------------------------------- /asset/组合关系.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/组合关系.png -------------------------------------------------------------------------------- /asset/继承关系.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/继承关系.png -------------------------------------------------------------------------------- /asset/编译过程.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/编译过程.png -------------------------------------------------------------------------------- /asset/聚合关系.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/聚合关系.png -------------------------------------------------------------------------------- /asset/自关联.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/自关联.png -------------------------------------------------------------------------------- /asset/计算机功能.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/计算机功能.png -------------------------------------------------------------------------------- /asset/计算机系统多层次结构.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/计算机系统多层次结构.png -------------------------------------------------------------------------------- /asset/边缘部分.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/边缘部分.png -------------------------------------------------------------------------------- /asset/运行时数据区.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/运行时数据区.png -------------------------------------------------------------------------------- /asset/进程状态转换.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/进程状态转换.png -------------------------------------------------------------------------------- /asset/逻辑结构.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/逻辑结构.png -------------------------------------------------------------------------------- /asset/链式存储结构.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/链式存储结构.png -------------------------------------------------------------------------------- /asset/集合框架.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/集合框架.png -------------------------------------------------------------------------------- /asset/集合框架2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/集合框架2.png -------------------------------------------------------------------------------- /asset/非受检异常.webp.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/非受检异常.webp.jpg -------------------------------------------------------------------------------- /asset/高速缓存区.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/asset/高速缓存区.jpg -------------------------------------------------------------------------------- /js/JavaScript基础.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/js/JavaScript基础.md -------------------------------------------------------------------------------- /其他/001.HTTP1.0、HTTP2.0、HTTP3.0.md: -------------------------------------------------------------------------------- 1 | ## 1 HTTP 优化 2 | 3 | 影响 HTTP 网络请求的因素: 4 | 5 | * 带宽 6 | * 延迟 7 | - 线头器阻塞(HOL Blocking):是一种出现在[缓存](https://baike.baidu.com/item/缓存)式通信网络交换中的一种现象。交换通常由[缓存](https://baike.baidu.com/item/缓存)式输入端口、一个交换架构以及缓存式输出端口组成。**当在相同的输入端口上到达的包被指向不同的输出端口的时候就会出现线头阻塞**。 8 | - DNS查询(DNS Lookup) 9 | - 建立连接(Initial connection) 10 | 11 | ## 2 HTTP 12 | 13 | ### 2.1 HTTP 1.0 14 | 15 | * 请求与响应支持 HTTP 头,响应含状态行,增加了状态码 16 | * 支持 HEAD,POST 方法 17 | * 支持传输 HTML 文件以外其他类型的内容 18 | 19 | 缺点: 20 | 21 | * **非持久连接**:客户端必须为每一个待请求的对象建立并维护一个新的连接,短连接增加了网络传输的负担 22 | 23 | ### 2.2 HTTP 1.1 24 | 25 | * 支持**长连接** 26 | * 在HTTP1.0的基础上引入了更多的缓存控制策略 27 | * 引入了**请求范围**设置,优化了带宽 28 | * 在错误通知管理中新增了错误状态响应码 29 | * 增加了Host头处理,可以传递主机名(hostname) 30 | 31 | ### 2.3 HTTPS 32 | 33 | - HTTPS 运行在安全套接字协议(Secure Sockets Layer,**SSL** )或传输层安全协议(Transport Layer Security,**TLS**)之上,所有在TCP中传输的内容都需要经过加密。 34 | - 连接方式不同,HTTP的端口是 80,HTTPS的端口是 443. 35 | - HTTPS 可以有效防止运营商劫持。 36 | 37 | ### 2.4 HTTP 1.x优化(SPDY) 38 | 39 | SPDY :**在 HTTP 之前做了一层会话层**,为了达到减少页面加载时间的目标,SPDY 引入了一个新的二进制分帧数据层,以实现优先次序、最小化及消除不必要的网络延迟,目的是更有效地利用底层 TCP 连接。 40 | 41 | - 多路复用,为多路复用设立了请求优先级 42 | - 对 header 部分进行了压缩 43 | - 引入了 HTTPS 加密传输 44 | - 客户端可以在缓存中取到之前请求的内容 45 | 46 | ### 2.5 HTTP 2.0 47 | 48 | * 使用二进制分帧层:在应用层与传输层之间增加一个二进制分帧层 49 | * **多路复用** 50 | * 服务端推送:logo、CSS 文件直接推给客户端 51 | * 数据流优先级:对数据流可以设置优先值,比如设置先传 css 文件等 52 | * 头部压缩 53 | * 支持明文传输,HTTP 1.X 使用 SSL/TLS 加密传输。 54 | 55 | ![](../asset/http2.0.jpg) 56 | 57 | ### 2.6 HTTP 3.0(QUIC) 58 | 59 | QUIC (Quick UDP Internet Connections),快速 UDP 互联网连接,基于 **UDP 协议**的。 60 | 61 | #### 2.6.1 线头阻塞(HOL)问题的解决更为彻底 62 | 63 | 基于TCP的HTTP/2,尽管从逻辑上来说,不同的流之间相互独立,不会相互影响,但在实际传输方面,数据还是要一帧一帧的发送和接收,一旦某一个流的数据有丢包,则同样会阻塞在它之后传输的流数据传输。而基于 UDP 的 **QUIC 协议**则可以更为彻底地解决这样的问题,让不同的流之间真正的实现相互独立传输,互不干扰。 64 | 65 | #### 2.6.2 切换网络时的连接保持 66 | 67 | 当前移动端的应用环境,用户的网络可能会经常切换,比如从办公室或家里出门,WiFi断开,网络切换为 3G 或 4G。基于TCP的协议,由于切换网络之后,IP会改变,因而之前的连接不可能继续保持。而基于 UD P的 QUIC 协议,则可以内建与 TCP 中不同的连接标识方法,从而在网络完成切换之后,恢复之前与服务器的连接。 -------------------------------------------------------------------------------- /其他/博客.md: -------------------------------------------------------------------------------- 1 | https://androidperformance.com/2018/05/07/Android-performance-optimization-skills-and-tools/ -------------------------------------------------------------------------------- /其他/滑动窗口.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/其他/滑动窗口.md -------------------------------------------------------------------------------- /其他/笔记.md: -------------------------------------------------------------------------------- 1 | ## 1 hashCode() 和 equals() 2 | 3 | hashCode:获取哈希表,确定该对象在哈希表中的索引位置,本地方法,内存地址转换整数,默认行为是对堆上的对象产生独特值。如果没有重写 `hashCode()`,则该 class 的两个对象无论如何都不会相等(即使这两个对象指向相同的数据)。 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /其他/红黑树.md: -------------------------------------------------------------------------------- 1 | ## 1 二叉查找树 2 | 3 | 红黑树是面试中一个非常重要的考点,在了解红黑树,我们需要知道为啥需要红黑树,红黑树主要为了解决二叉查找树出现瘸腿问题。 4 | 5 | 二叉查找树,Binary Search Tree(BST),下图就是标准的二叉查找树,具有以下特征(左小右大): 6 | 7 | 1. 若左子树不空,则左子树上所有结点的值均小于它的根结点)的值; 8 | 9 | 2. 若右子树不空,则右子树上所有结点的值均大于它的根结点的值; 10 | 11 | 3. 左、右子树也分别为二叉排序树; 12 | 13 | 4. 没有键值相等的结点。 14 | 15 | ![](../asset/二叉查找树.png) 16 | 17 | 红黑树主要为了解决二叉查找树出现瘸腿问题,所谓瘸腿问题如下图所示: 18 | 19 | ![](../asset/二叉查找树问题.png) 20 | 21 | 明显可以看到 BST 一条腿特别长。 22 | 23 | ## 2 红黑树 24 | 25 | 红黑树是每个结点都带有颜色属性的二叉查找树,不是红色就是黑色。 在二叉查找树强制一般要求以外,对于任何有效的红黑树增加了如下的要求: 26 | 27 | * 结点是红色或黑色; 28 | 29 | * 根结点是黑色; 30 | 31 | * 所有叶子都是黑色,叶子是 NIL 结点; 32 | * 每个红色结点的两个子结点都是黑色,也就是从每个叶子到根的所有路径上不能有两个连续的红色结点; 33 | * 从任一节结点其每个叶子的所有路径都包含相同数目的黑色结点。 34 | 35 | 为了满足红黑树的特征,因此可以通过以下两个操作满足: 36 | 37 | * 改变颜色:红变黑、黑变红 38 | * 旋转(左旋、右选) 39 | 40 | 左旋操作: 41 | 42 | ![](../asset/左旋.gif) 43 | 44 | 右旋操作: 45 | 46 | ![](../asset/右旋.gif) 47 | 48 | ## 3 构建红黑树规则 49 | 50 | 所有插入的点默认为**红色**。 51 | 52 | 变颜色情况:当前结点父亲为红色,叔叔为也红色: 53 | 54 | * 父亲 -> 黑色 55 | * 叔叔 -> 黑色 56 | * 爷爷 -> 红色 57 | * 把操作节点变为爷爷 58 | 59 | 左旋:当前父结点为红色,叔叔为黑色,且位于右子树,父结点左旋 60 | 61 | 右旋:当前父结点为红色,叔叔为黑色,且位于左子树,右旋: 62 | 63 | * 父亲 -> 黑色 64 | * 爷爷 -> 红色 65 | * 以爷爷结点旋转 66 | 67 | ![](../asset/左旋右旋规则.png) 68 | 69 | 如上图所示,插入 6: 70 | 71 | 变颜色情况:当前结点父亲为红色,叔叔为也红色: 72 | 73 | - 父亲(7) -> 黑色 74 | - 叔叔(13) -> 黑色 75 | - 爷爷(12) -> 红色 76 | - 把操作节点变为爷爷(12) 77 | 78 | 左旋:当前(12)父结点(5)为红色,叔叔(1)为黑色,且位于右子树,父结点(5)左旋 79 | 80 | 右旋:当前(5)父结点(12)为红色,叔叔(30)为黑色,且位于左子树,右旋: 81 | 82 | - 父亲(12) -> 黑色 83 | - 爷爷(19) -> 红色 84 | - 以爷爷(19)结点旋转 -------------------------------------------------------------------------------- /其他/面经整理.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/其他/面经整理.md -------------------------------------------------------------------------------- /密码学/001.密码学概述.md: -------------------------------------------------------------------------------- 1 | ## 1 基本概念 2 | 密码学是网络安全、信息安全、区块链等产品的基础,常见的非对称加密、对称加密、散列函数等,都属于密码学范畴。 3 | 4 | 密码学分为 5 | * 古典密码学 6 | * 近代密码学 7 | * 现代密码学 8 | 9 | ## 2 古典密码学 10 | * 替换法:固定的信息将原文替换成无法直接阅读的密文信息,i love you -> t hate set 11 | * 移位法:将原文中的所有字母都在字母表上向后(或向前)按照一个固定数目进行偏移后得出密文,例如恺撒密码, abc -> def。 12 | 13 | 破解方式: 14 | * 频率分析(概率论) 15 | 16 | ## 3 近代密码学 17 | 恩尼格玛机:是二战时期纳粹德国使用的加密机器,后被英国破译,参与破译的人员有被称为计算机科学之父、人工智能之父的图灵,本质就是移位和替代。 18 | 19 | ## 4 现代密码学 20 | 21 | ### 4.1 散列函数 22 | 也见杂凑函数、摘要函数或哈希函数,**将任意长度的消息经过运算,变成固定长度数值**,常见的有 MD5、SHA-1、SHA256,多应用在文件校验,数字签名中。 23 | 24 | **MD5**:将任意长度的原文生成一个128位(16字节)的哈希值 25 | 26 | **SHA-1**:将任意长度的原文生成一个160位(20字节)的哈希值 27 | 28 | ### 4.2 对称密码 29 | 应用**相同的加密密钥和解密密钥** 30 | 31 | 对称密码分为: 32 | * 序列密码(流密码):对信息流中的每一个元素(一个字母或一个比特)作为基本的处理单元进行加密。 33 | * 分组密码(块密码):先对信息流分块,再对每一块分别加密。 34 | 35 | ### 4.3 非对称密码 36 | 有两个密钥: 37 | * 公钥(public key) 38 | * 私钥(private key) 39 | 40 | 1. 加密和解密运算使用的密钥不同; 41 | 2. 公钥加密,私钥解密; 42 | 3. 私钥加密(签名),公钥解密(验签); 43 | 4. 公钥可以公开的,大家使用公钥对信息进行加密,再发送给私钥的持有者,私钥持有者使用私钥对信息进行解密,获得信息原文; 44 | 5. 私钥只能有一人持有,不用当心被信息被破解; 45 | 46 | 47 | ### 4.4 保证密码安全 48 | * 不要使用常用的密码,如 123456; 49 | * 不同账号尽量不要使用用一个密码,避免一个数据库被脱库,其他都被破解; 50 | * 在设置密码时增加注册时间、注册地点、应用特性等信息,如 beijing20120202 -------------------------------------------------------------------------------- /密码学/002.凯撒密码.md: -------------------------------------------------------------------------------- 1 | ## 1 简介 2 | 3 | 凯撒密码最早由古罗马军事统帅盖乌斯·尤利乌斯·凯撒在军队中用来传递加密信息,故称凯撒密码。这是一种位移加密方式,只对26个字母进行位移替换加密,规则简单,容易破解。 4 | 5 | ```java 6 | //就是右移3位 7 | ABCDEF.... 8 | XYZABC.... 9 | ``` 10 | 11 | ## 2 频度分析法破解恺撒加密 12 | 13 | - 将明文字母的出现频率与密文字母的频率相比较的过程 14 | - 通过分析每个符号出现的频率而轻易地破译代换式密码 15 | - 在每种语言中,冗长的文章中的字母表现出一种可对之进行分辨的频率 16 | - e 是英语中最常用的字母,其出现频率为八分之一 -------------------------------------------------------------------------------- /密码学/006.数字签名.md: -------------------------------------------------------------------------------- 1 | ## 1 数字签名 2 | 3 | 数字签名(又称[公钥](https://baike.baidu.com/item/公钥)数字签名)是只有信息的发送者才能产生的别人无法伪造的一段数字串,这段数字串同时也是对信息的发送者发送信息真实性的一个有效证明。它是一种类似写在纸上的普通的物理签名,但是使用了[公钥加密](https://baike.baidu.com/item/公钥加密/6245950)领域的技术来实现的,用于鉴别数字信息的方法。一套数字签名通常定义两种互补的运算,一个用于签名,另一个用于验证。数字签名是非对称[密钥加密技术](https://baike.baidu.com/item/密钥加密技术)与[数字摘要](https://baike.baidu.com/item/数字摘要/4069118)技术的应用。 4 | 5 | 数字签名的主要作用就是保证了**数据的有效性**(验证是谁发的)和**完整性**(证明信息没有被篡改)。 6 | 7 | ![](../asset/数字签名.png) 8 | 9 | * 用户 A -> 文件经过单向散列函数 -> 得到 128 位的摘要 -> A私钥加密 -> 得到加密的摘要 10 | * 把文件 + 加密的摘要 + A 公钥 -> 传输给 用户 B 11 | 12 | * 用户 B 13 | - 文件经过单向散列函数 -> 得到 128 位的摘要(摘要 1) 14 | - A 公钥对加密的摘要进行解密 -> 得到 128 位的摘要(摘要 2) 15 | - 判断摘要 1 和 摘要 2 是否相等,不相等,文件被篡改 16 | 17 | ## 2 CA 证书 18 | 19 | ![](../asset/ca.png) 20 | 21 | * 用户 A 向证书颁发机构提交个人信息,申请证书,机构给用户 A 生成 CA 证书(A 公钥、B公钥、CA 数字签名) 22 | 23 | * 用户 B 要信任第三方认证机构的 CA 证书 24 | 25 | * 用户 A 发送的数据,A公钥 上有认证机构 CA 的数字签名,用户 B 根据 CA 公钥验证 A 公钥得合法性。 26 | * 合法来,下面的流程就和数字签名一样。 -------------------------------------------------------------------------------- /操作系统/001.计算机系统概述.md: -------------------------------------------------------------------------------- 1 | ## 1 操作系统的基本概念 2 | 3 | ### 1.1 操作系统的特征 4 | 5 | * 并发 6 | * 共享 7 | - 互斥共享:同一时刻,仅允许一个进程访问,例如打印机 8 | * 同时访问:一段时间允许多个进程访问,例如,磁盘 9 | * 虚拟 10 | - 时分复用技术:处理器的分时共享 11 | * 空分复用技术:虚拟存储器 12 | * 异步:多道程序走走停停,进程以不可预知的速度前进 13 | 14 | ### 1.2 操作系统的目标和功能 15 | 16 | * 作为计算机系统资源的管理者 17 | - 处理机管理 18 | - 存储器管理 19 | - 文件管理 20 | - 设备管理 21 | * 作为用户与计算机硬件系统之间的接口 22 | - 命令接口 23 | - 联机命令接口:交互式命令接口 24 | - 脱机命令接口:批处理系统,提交一组作业。 25 | - 程序接口:图形用户界面(GUI) 26 | * 用作扩充机器:覆盖了软件的机器称为扩充机器,又称虚拟机 27 | 28 | ## 2 操作系统的发展与分类 29 | 30 | * 手工操作阶段 31 | * 批处理阶段 32 | * 单道批处理系统 33 | * 多道批处理系统 34 | * 分时操作系统 35 | * 将处理器运行时间划分为时间片,将时间片分配给不同作业/用户从而占用处理机 36 | * 同时性、交互性、独立性、及时性 37 | * 实时操作系统 38 | * 保证在规定时间内完成某项规定任务 39 | * 分布式计算机系统 40 | * 个人计算机系统 41 | 42 | ## 3 操作系统的运行环境 43 | 44 | 程序运行的过程其实就是 CPU 执行机器指令的过程。 45 | 46 | ### 3.1 操作系统的运行机制 47 | 48 | CPU 执行两种性质程序:内核程序、用户自编程序 49 | 50 | 内核: 51 | 52 | * 时钟管理:操作系统对用户提供标准时间,**根据时钟对进程进行管理**,实现进程切换。 53 | * 中断管理:提高多道程序运行环境中的 CPU 利用率。 54 | * 原语(运行原子性):处于系统的最底层,最接近硬件。 55 | * 进程管理 56 | * 存储器管理 57 | * 设备管理 58 | 59 | ### 3.2 中断与异常 60 | 61 | 中断机制:为了核心态与用户态切换。 62 | 63 | 核心态可以执行用户态无法执行的**特权指令**。 64 | 65 | * 中断(外中断):CPU 指令之外的事件发生(I/O中断、时钟中断) 66 | * 异常(内中断):CPU 执行指令内部的事件(非法操作码、除零、算术溢出) 67 | 68 | 系统调用: 69 | 70 | * 设备功能 71 | * 文件管理 72 | * 进程管理 73 | * 进程通信 74 | * 内存管理 75 | 76 | ### 3.3 用户态与内核态 77 | 78 | 处于内核态(核心态、管态):运行内核程序,执行**特权指令** 79 | 80 | 处于用户态(目态):运行应用程序,执行非特权指令 81 | 82 | CPU 有一个寄存器叫程序状态字寄存器(psw),1 代表 内核态,0 代表 用户态 83 | 84 | ## 4 大内核与为内核 85 | 86 | * 大内核:操作系统的主要功能进行集中,提供服务 87 | * 微内核:将内核中的基本功能(如:进程管理)保留在内核中,不需要的核心态功能转移到用户态。(性能问题,需要**频繁的用户态与内核态之间切换**) 88 | 89 | -------------------------------------------------------------------------------- /操作系统/003.内存管理.md: -------------------------------------------------------------------------------- 1 | ## 1 内存管理概念 2 | 3 | ### 1.1 内存管理的基本原理和要求 4 | 5 | 内存:内存可存放数据,程序执行前需要**先放到内存**中才能被 CPU 处理 -- 缓和 CPU 与硬盘之间的速度矛盾。 6 | 7 | 功能: 8 | 9 | * 内存空间的分配与回收 10 | * 地址转换 11 | * 内存空间的扩充 12 | * 存储保护 13 | 14 | #### 1.1.1 程序的装入和链接 15 | 16 | 创建步骤:编译、链接、装入 17 | 18 | 链接的类型:静态链接、装入时动态链接、运行时动态链接 19 | 20 | 装入模式:绝对装入、可重定位装入、动态运行时装入 21 | 22 | ### 1.2 覆盖与交换 23 | 24 | 多道程序环境用来扩充内存的方法。 25 | 26 | 覆盖:将程序分为多个段,常用的段常驻内存,不常用的段需要时才调入内存 27 | 28 | 交换:内存中某些段移出内存,把外存中具备运行的装入内存 29 | 30 | ### 1.3 连续分配管理方式 31 | 32 | 一个程序分配一个连续的内存空间 33 | 34 | * 单一连续分配 35 | * 固定分区分配 36 | * 动态分区分配 37 | * 首次适应算法 38 | * 最佳适应算法 39 | * 最坏适应算法 40 | * 邻近适应算法 41 | 42 | ### 1.4 非连续分配管理方式 43 | 44 | 一个程序分散地装入不相邻的内存分区,根据分区大小是否固定,分为**分页存储管理、分段存储管理**。 45 | 46 | **分页存储管理**根据运行时是否把作业的所有页面都装入内存才能运行,又分为**基本分页存储管理方式**、**请求分页存储管理方式**。 47 | 48 | ### 1.5 基本分页存储管理方式 49 | 50 | * 分页管理不会产生碎片 51 | * 将主存空间划分为**大小相等且固定的块**,块相对较小,作为主存的基本单位,进程以块为单位空间申请。 52 | 53 | ### 1.5 基本分段存储管理方式 54 | 55 | * 按照**用户进程**中的自然段划分逻辑空间。 56 | 57 | ### 1.6 段页式管理方式 58 | 59 | * 作业的地址空间首先被分为若干逻辑段,每段都有自己的段号 60 | * 每个段分为若干大小固定的页 61 | * 对内存空间的管理仍然和分页存储管理一样 62 | * 会产生碎片 63 | 64 | ### 1.7 分页和分段区别 65 | 66 | - 对程序员的透明性:分页透明,但是分段需要程序员显式划分每个段。 67 | - 地址空间的维度:分页是一维地址空间,分段是二维的。 68 | - 大小是否可以改变:页的大小固定,段的大小可以**动态改变**。 69 | - 出现的原因:分页主要用于实现虚拟内存,从而获得更大的地址空间;分段主要是为了使程序和数据可以被划分为逻辑上独立的地址空间并且有助于共享和保护。 70 | 71 | ## 2 虚拟内存管理 72 | 73 | ### 2.1 基本概念 74 | 75 | 传统存储管理方式的特征: 76 | 77 | * 一次性 78 | * 驻留性 79 | 80 | 局部性原理: 81 | 82 | * 时间局部性 83 | * 空间局部性 84 | 85 | 虚拟存储器的定义:基于局部性原理,程序的一部分装入内存,一部分留在外存,需要的时候调入内存。 86 | 87 | 特征:多次性、对换性、虚拟性 88 | 89 | 实现: 90 | 91 | * 请求分页存储管理 92 | * 请求分段存储管理 93 | * 请求段页式存储管理 94 | 95 | ### 2.2 请求分页管理方式 96 | 97 | 系统建立在基本分页系统基础之上,为了支持虚拟存储器功能而增加了**请求调页功能**和**页面置换功能** 98 | 99 | ### 2.3 页面置换算法 100 | 101 | * 最佳置换算法(OPT) 102 | * 先进先出页面置换算法(FIFO) 103 | * 最近最久未使用置换算法(LRU) 104 | * 时钟置换算法(CLOCK) 105 | 106 | ### 2.4 页面分配策略 107 | 108 | * 固定分配局部置换 109 | * 可变分配全局置换 110 | * 可变分配局部置换 111 | 112 | ### 2.5 抖动 113 | 114 | 刚换出的页面又要换入内存。 115 | 116 | 原因: 117 | 118 | * 分配的物理页帧数不足(主要原因) 119 | * 置换算法不当 120 | 121 | ### 2.6 工作集 122 | 123 | 某段时间内,进程要访问的页面集合。 -------------------------------------------------------------------------------- /操作系统/004.文件管理.md: -------------------------------------------------------------------------------- 1 | ## 1 文件系统基础 2 | 3 | ### 1.1 文件的相关概念 4 | 5 | 文件是以**计算机硬盘为载体**的存储在计算机上的信息集合,可以是文本文档、图片、程序。 6 | 7 | 文件的结构:数据项、记录、文件(有结构文件、无结构式文件) 8 | 9 | 文件的属性:名称、标识符、类型、位置、大小、保护、时间日期和用户标识 10 | 11 | 文件的基本操作:创建文件、写文件、读文件、文件重定位、删除文件、截断文件 12 | 13 | ### 1.2 文件的逻辑结构 14 | 15 | * 无结构文件(流式文件)-> 如文本文件 16 | * 有结构文件(记录式文件):顺序文件、索引文件、索引顺序文件 -> 如数据库 17 | 18 | ### 1.3 目录结构 19 | 20 | 使多个用户可以共享使用一个文件 21 | 22 | - 单级目录结构 23 | 24 | ![](../asset/%E5%8D%95%E7%BA%A7%E7%9B%AE%E5%BD%95%E7%BB%93%E6%9E%84.jpg) 25 | 26 | - 两级目录结构 27 | 28 | ![](../asset/%E4%B8%A4%E7%BA%A7%E7%9B%AE%E5%BD%95%E7%BB%93%E6%9E%84.jpg) 29 | 30 | - 多级目录结构 31 | 32 | ![](../asset/%E6%A0%91%E5%BD%A2%E7%9B%AE%E5%BD%95%E7%BB%93%E6%9E%84.jpg) 33 | 34 | - 无环图目录结构 35 | 36 | ![](../asset/%E6%97%A0%E7%8E%AF%E5%9B%BE%E7%9B%AE%E5%BD%95%E7%BB%93%E6%9E%84.jpg) 37 | 38 | ### 1.4 文件共享 39 | 40 | 保证不同的用户对文件有不同的操作权限 41 | 42 | - 基于索引结点的共享文件(硬链接) 43 | - 利用符号链实现文件共享(软连接):B 要共享 A 文件 F,创建一个 文件 F(只包含链接文件 F 的路径名) 写入到 B 目录中。 44 | 45 | ### 1.5 文件保护 46 | 47 | * 口令保护 48 | 49 | * 加密保护 50 | 51 | * 访问控制 52 | 53 | ## 2 文件系统实现 54 | 55 | ### 2.1 文件层结构 56 | 57 | * 用户调用接口 58 | * 文件目录系统 59 | * 存储控制验证 60 | * 逻辑文件系统关于信息缓冲区 61 | * 物理文件系统 62 | * 辅助分配模块 63 | * 设备管理程序模块 64 | 65 | ### 2.2 目录实现 66 | 67 | * 线性列表 68 | * 哈希表 69 | 70 | ### 2.3 文件实现 71 | 72 | 文件分配方式:连续分配、链接分配、索引分配 73 | 74 | ## 3 磁盘组织与管理 75 | 76 | ### 3.1 磁盘结构 77 | 78 | 磁盘:是由表面涂有磁性物质的金属或塑料构成的圆形盘片,通过一个称为**磁头**的导体线圈从磁盘存储数据。 79 | 80 | ![](../asset/磁盘结构.jpg) 81 | 82 | ### 3.2 磁盘调度算法 83 | 84 | * 先来先服务(FCFS) 85 | * 最短寻址时间优先(SSTF) 86 | * 扫描算法(SCAN) 87 | * 循环算法(S-SCAN) 88 | 89 | ### 3.3 磁盘的管理 90 | 91 | * 磁盘初始化:对磁盘进行低级格式化和逻辑格式化 92 | * 引导块:存放自举程序 93 | * 坏块:对于损坏扇区的处理 -------------------------------------------------------------------------------- /操作系统/005.输入输出(IO)管理.md: -------------------------------------------------------------------------------- 1 | ## 1 IO管理概述 2 | 3 | ### 1.1 I/O 设备 4 | 5 | I/O 设备的类型分类。 6 | 7 | #### 1.1.1 按使用特性 8 | 9 | - 人机交互类外部设备,例如打印机、显示器等。 10 | - 存储设备,例如磁盘、光盘等。 11 | - 网络通信设备,例如网络接口等。 12 | 13 | #### 1.1.2 按传输速率 14 | 15 | - 低速设备:键盘、鼠标。 16 | - 中速设备:打印机、激光机等。 17 | - 高速设备:磁带机、磁盘机等。 18 | 19 | #### 1.1.3 按信息交换的单位分类 20 | 21 | - 块设备:信息存取以数据块为单位。 22 | - 字符设备:传输单位以字符为单位,如打印机、交互式终端机。 23 | 24 | ### 1.2 I/O控制方式 25 | 26 | ![](../asset/IO控制方式.png) 27 | 28 | #### 2.2.1 程序直接控制方式 29 | 30 | CPU 和 I/O 设备串行工作,由用户进程直接控制主存或 CPU 和外围设备之间的信息传送。 31 | 32 | #### 2.2.2 中断驱动方式 33 | 34 | 允许 I/O 设备主动打断 CPU 的运行并请求服务。为了减少程序直接控制方式下 CPU 的等待时间以及提高系统的并行程度,外围设备仅当操作正常结束或异常结束时才向 CPU 发出中断请求。在 I/O 设备输入每个数据的过程中,由于无需 CPU 的干预,一定程度上实现了 CPU 与 I/O设备的并行工作。仅当输入或输出完一个数据时,才需 CPU 花费极短的时间做中断处理。 35 | 36 | #### 2.2.3 DMA 方式(直接存储器存储) 37 | 38 | 用窃取或挪用总线控制权,在设备和主存之间开辟直接数据交换通道,成批地交换数据,而不必让 CPU 干预。 39 | 40 | #### 2.2.4 通道控制方式 41 | 42 | 通道,独立于 CPU 的专门负责输入输出控制的处理机,它控制设备与内存直接进行数据交换。有自己的通道指令,这些指令由 CPU 启动,并在操作结束时向 CPU 发出中断信号。 43 | 44 | 通道控制方式,实现了CPU、通道和I/O设备三者的并行操作,从而更加有效地提高整个系统的资源利用率。 45 | 46 | ### 1.3 I/O子系统的层次结构 47 | 48 | * 用户层I/O软件:实现与用户交互的接口 49 | * 设备独立性软件:实现用户程序与设备驱动器的统一结构、设备命令、设备保以及设备分配与释放 50 | * 设备驱动程序:与硬件直接相关,负责具体实现系统对设备发出的操作指令 51 | * 中断处理程序:用于处理中断相关事项 52 | * 硬件设备:包括一个机械部件(设备本身)和一个电子部件(控制器) 53 | 54 | ## 2 IO 核心子系统 55 | 56 | ### 2.1 I/O子系统概述 57 | 58 | 主要提供IO调度、缓冲与高速缓存、设备分配与回收、假脱机、设备保护和差错处理 59 | 60 | ### 2.2 IO调度概念 61 | 62 | 通过IO调度改善系统整体性能,使得进程之间公平共享设备访问,减少IO完成所需要的平均等待时间。 63 | 64 | ### 2.3 高速缓存与缓冲区 65 | 66 | 高速缓存在内存中分为两种形式: 67 | 68 | * 在内存中开辟一个**单独的存储空间**作为磁速缓存,大小固定 69 | * 把未利用的内存空间作为一个缓沖池,供请求分页系统和磁盘I/O时共享。 70 | 71 | 缓存区: 72 | 73 | - 釆用硬件缓冲器,但由于成本太高,除一些关键部位外,一般不釆用硬件缓冲器 74 | - 釆用缓冲区(位于内存区域)。 75 | 76 | 缓存区分类: 77 | 78 | * 单缓存 79 | * 双缓存 80 | * 循环缓存 81 | * 缓冲池 82 | 83 | ![](../asset/高速缓存区.jpg) 84 | 85 | ### 2.4 设备分配与回收 86 | 87 | 充分发挥设备的使用效率,避免进程死锁。 88 | 89 | 设备分类: 90 | 91 | - 独占设备 92 | - 共享设备 93 | - 虚拟设备 94 | 95 | ### 2.5 IO调度 96 | 97 | * 安全分配方式:为进程分配一个设备后就将该进程阻塞,本次I/O完成后才将进程唤醒。 98 | 99 | * 不安全分配方式:进程发出I/O请求后,系统为其分配I/O设备,进程可继续执行,之后还可以发出新的I/O请求,只有某个I/O请求得不到满足时才将进程阻塞。不安全分配方式一个进程可以同时使用多个设备。 100 | 101 | ### 2.6 SPOOLING技术(假脱机技术) 102 | 103 | 如果设备被占用,先把数据暂存,等到设备空闲了就把这些数据输送到设备中。 104 | 105 | -------------------------------------------------------------------------------- /数据结构/001.绪论.md: -------------------------------------------------------------------------------- 1 | ## 1 数据结构的基本概念 2 | 3 | ### 1.1 基本概念和术语 4 | 5 | * 数据:信息的载体,描述客观事物属性,能被计算机识别处理的符号集合。 6 | * 数据元素:数据的基本单位,作为一个元素进行考虑和处理。 7 | * 数据类型:一个值的集合和定义以及一组操作的总称,分类: 8 | * 原子类型 9 | * 结构类型 10 | * 抽象数据类型 11 | * 数据结构:数据元素之间的特定关系。 12 | * 包括三个方面:逻辑结构、存储结构、数据的运算 13 | 14 | ### 1.2 数据结构三要素 15 | 16 | 数据的**逻辑结构**:数据元素之间的逻辑关系,独立于计算机,分为以下两类: 17 | 18 | * 线性结构 19 | * 线性表 20 | * 栈 21 | * 队列 22 | * 数组 23 | * 非线性结构 24 | * 集合 25 | * 树 26 | * 图 27 | 28 | 数据的**存储结构**:数据结构在计算机中的表示(映像),也称**物理结构**。 29 | 30 | * 顺序存储 31 | * 链式存储 32 | * 索引存储 33 | * 散列存储 34 | 35 | 数据的**运算**:施加在数据上的运算,包括运算的定义和实现。 36 | 37 | ### 1.3 算法和算法评价 38 | 39 | 算法:特定问题求解步骤一种描述 40 | 41 | 特征:有穷性、确定性、可行性、输入、输出 42 | 43 | 优秀算法的标准:正确性、可读性、健壮性、效率与低存储量需求 44 | 45 | 效率的度量:时间复杂度、空间复杂度 -------------------------------------------------------------------------------- /数据结构/002.线性表.md: -------------------------------------------------------------------------------- 1 | ## 1 定义 2 | 3 | 线性表是具有**相同数据类型**的 n 个数据元素的有限序列,n 为表长,n = 0 为空表。 4 | 5 | ## 2 顺序表 6 | 7 | 一组地址连续的存储单元依次存储线性表中的数据元素。 8 | 9 | ```c 10 | //静态分配 11 | #define MaxSize 10 12 | typedef struct{ 13 | ElemType data[MaxSize]; 14 | int length; 15 | }SqList; 16 | ``` 17 | 18 | 19 | 20 | ## 3 链表 -------------------------------------------------------------------------------- /数据结构/003.栈和队列.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/数据结构/003.栈和队列.md -------------------------------------------------------------------------------- /数据结构/004.串.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/数据结构/004.串.md -------------------------------------------------------------------------------- /数据结构/005.树与二叉树.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/数据结构/005.树与二叉树.md -------------------------------------------------------------------------------- /数据结构/006.图.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/数据结构/006.图.md -------------------------------------------------------------------------------- /数据结构/007.查找.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/数据结构/007.查找.md -------------------------------------------------------------------------------- /数据结构/008.排序.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/数据结构/008.排序.md -------------------------------------------------------------------------------- /数据结构/01.数据结构和算法概述.md: -------------------------------------------------------------------------------- 1 | ## 1 数据结构 2 | 3 | 是一门研究非数值计算的程序设计问题中的操作对象,以及他们之间的关系和操作等相关问题的学科。简单来说是把数据元素按照一定的关系组织起来的集合,用来组织和存储数据。 4 | 5 | ## 2 分类 6 | 7 | 数据结构分为两类: 8 | 9 | * 逻辑结构:从具体问题中抽象出来的模型,是抽象意义上的结构,按照对象中数据元素之间的相互关系分类。 10 | * 物理结构:逻辑结构在计算机中真正的表示方式(又称为映像)称为物理结构,也可以叫做存储结构。常见的物理结构有**顺序存储结构、链式存储结构**。 11 | 12 | 逻辑结构: 13 | 14 | ![](../asset/逻辑结构.png) 15 | 16 | 物理结构: 17 | 18 | ![](../asset/链式存储结构.png) 19 | 20 | ## 3 算法 21 | 22 | 是指解题方案的准确而完整的描述,是一系列解决问题的清晰指令,算法代表着用系统的方法解决问题的策略机制。也就是说,能够对一定规范的输入,在有限时间内获得所要求的输出。 23 | 24 | 算法追求的目标: 25 | 26 | * **花最少的时间完成需求**; 27 | * **占用最少的内存空间完成需求**; 28 | 29 | ## 4 算法分析 30 | 31 | 算法的时间耗费分析,称为时间复杂度分析,算法的空间耗费分析,称为空间复杂度分析。 32 | 33 | 常见的算法时间复杂度: 34 | 35 | | 描述 | 复杂度 | 说明 | 例子 | 36 | | ------------ | -------- | -------- | -------------- | 37 | | 常数级别 | O(1) | 普通语句 | 将两个数相加 | 38 | | 对数级别 | O(logn) | 二分策略 | 二分查找 | 39 | | 线性级别 | O(n) | 循环 | 找出最大元素 | 40 | | 线型对数级别 | O(nlogn) | 分治思想 | 归并排序 | 41 | | 平方级别 | O(n^2) | 双层循环 | 检查所有元素对 | 42 | | 立方级别 | O(n^3) | 三层循环 | 检查所有三元组 | 43 | | 指数级别 | O(2^n) | 穷举 | 检查所有子集 | 44 | 45 | -------------------------------------------------------------------------------- /数据结构/part01/000.目录.md: -------------------------------------------------------------------------------- 1 | 本笔记整理自 B 站免费教程,仅供参考,建议去 B 站学习原教程。 2 | 3 | [PHP基础丨Git零基础入门到实战详解](https://www.bilibili.com/video/BV1sJ411D7xN) 4 | 5 | -------------------------------------------------------------------------------- /数据结构/part01/001.数据结构与算法的关系.md: -------------------------------------------------------------------------------- 1 | ## 1 数据结构和算法的重要性 2 | 1. 算法是程序的灵魂,优秀的程序可以在海量数据计算时,依然保持高速计算; 3 | 2. 一般来讲 程序会使用了内存计算框架(比如Spark)和缓存技术(比如Redis等)来优化程序,再深入的思考一下,这些计算框架和缓存技术, 它的核心功能是哪个部分呢? 4 | 3. 拿实际工作经历来说, 在Unix下开发服务器程序,功能是要支持上千万人同时在线, 在上线前,做内测,一切OK,可上线后,服务器就支撑不住了, 公司的CTO对代码进行优化,再次上线,坚如磐石。你就能感受到程序是有灵魂的,就是算法; 5 | 4. 目前程序员面试的门槛越来越高,很多一线IT公司(大厂),都会有数据结构和算法面试题(负责的告诉你,肯定有的); 6 | 5. 如果你不想永远都是代码工人,那就花时间来研究下数据结构和算法; 7 | 8 | ## 2 数据结构和算法概述 9 | 1. 数据 data 结构(structure)是一门研究*组织数据方式*的学科,有了编程语言也就有了数据结构.学好数据结构可以 编写出更加漂亮,更加有效率的代码。 10 | 2. 程序 = 数据结构 + 算法; 11 | 3. 数据结构是算法的基础, 要学好算法,需要把数据结构学到位; -------------------------------------------------------------------------------- /数据结构/part01/002.线性结构和非线性结构.md: -------------------------------------------------------------------------------- 1 | ## 1 简介 2 | 数据结构包括:线性结构、非线性结构。 3 | ## 2 线性结构 4 | * 数据元素之间存在一对一的线性关系 5 | 6 | * 两种存储结构 7 | 8 | - 顺序存储结构:数组 9 | - 链式存储结构:链表 10 | 11 | * 顺序存储的线性表称为**顺序表**,顺序表中的**存储元素是连续**的 12 | 13 | * 链式存储的线性表称为链表,链表中的**存储元素不一定是连续的**,元素节点中存放数据元素以及相邻元素的地 14 | 15 | 址信息 16 | 17 | * 线性结构常见的有:**数组、队列、链表、栈** 18 | 19 | ## 3 非线性结构 20 | 21 | 非线性结构包括:二维数组、多维数组、广义表、树结构、图结构。 -------------------------------------------------------------------------------- /数据结构/part01/003.稀疏数组.md: -------------------------------------------------------------------------------- 1 | ## 1 简介 2 | 当一个数组中大部分元素为0,或者为同一个值的数组时,可以使用稀疏数组来保存该数组。 3 | 处理方法: 4 | * 记录数组一共有几行几列,有多少个不同的值 5 | * 把具有不同值的元素的行列及值记录在一个小规模的数组中,从而缩小程序的规模 6 | 7 | ## 2 应用实例 8 | * 使用稀疏数组,来保留类似前面的二维数组(棋盘、地图等等) 9 | * 可以把稀疏数组存盘,并且可以从新恢复原来的二维数组数 10 | 11 | ## 3 二维数组和稀疏数组互转 -------------------------------------------------------------------------------- /数据结构/part01/005.单链表.md: -------------------------------------------------------------------------------- 1 | ## 1 简介 2 | 3 | 1. 链表是以节点的方式来存储,**是链式存储**。 4 | 2. 每个节点包含 data 域, next 域:指向下一个节点。 5 | 3. 链表不一定是连续存储。 6 | 4. 链表分**带头节点的链表**和**没有头节点的链表**。 7 | 8 | -------------------------------------------------------------------------------- /数据结构/part01/006.单链表面试题.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/数据结构/part01/006.单链表面试题.md -------------------------------------------------------------------------------- /算法/labuladong的算法小抄.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/算法/labuladong的算法小抄.md -------------------------------------------------------------------------------- /算法/剑指Offer/03.数组中重复的数字.md: -------------------------------------------------------------------------------- 1 | #### [剑指 Offer 03. 数组中重复的数字](https://leetcode-cn.com/problems/shu-zu-zhong-zhong-fu-de-shu-zi-lcof/) 2 | 3 | 难度 简单 4 | 5 | 找出数组中重复的数字。 6 | 7 | 8 | 在一个长度为 n 的数组 nums 里的所有数字都在 0~n-1 的范围内。数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。 9 | 10 | **示例 1:** 11 | 12 | ``` 13 | 输入: 14 | [2, 3, 1, 0, 2, 5, 3] 15 | 输出:2 或 3 16 | ``` 17 | 18 | 19 | 20 | **限制:** 21 | 22 | ``` 23 | 2 <= n <= 100000 24 | ``` 25 | 26 | #### 解法 27 | 28 | ```java 29 | //原地替换 30 | class Solution { 31 | public int findRepeatNumber(int[] nums) { 32 | if (nums == null || nums.length == 0) return -1; 33 | for (int i = 0; i < nums.length; i++) { 34 | if (i != nums[i]) { 35 | if (nums[i] == nums[nums[i]]) { 36 | return nums[i]; 37 | } else { 38 | int tmp = nums[nums[i]]; 39 | nums[nums[i]] = nums[i]; 40 | nums[i] = tmp; 41 | } 42 | } 43 | } 44 | return -1; 45 | } 46 | } 47 | ``` 48 | 49 | -------------------------------------------------------------------------------- /算法/剑指Offer/04.二维数组中的查找.md: -------------------------------------------------------------------------------- 1 | #### [剑指 Offer 04. 二维数组中的查找](https://leetcode-cn.com/problems/er-wei-shu-zu-zhong-de-cha-zhao-lcof/) 2 | 3 | 难度 中等 4 | 5 | 在一个 n * m 的二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个高效的函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。 6 | 7 | 8 | 9 | **示例:** 10 | 11 | 现有矩阵 matrix 如下: 12 | 13 | ``` 14 | [ 15 | [1, 4, 7, 11, 15], 16 | [2, 5, 8, 12, 19], 17 | [3, 6, 9, 16, 22], 18 | [10, 13, 14, 17, 24], 19 | [18, 21, 23, 26, 30] 20 | ] 21 | ``` 22 | 23 | 给定 target = `5`,返回 `true`。 24 | 25 | 给定 target = `20`,返回 `false`。 26 | 27 | 28 | 29 | **限制:** 30 | 31 | ``` 32 | 0 <= n <= 1000 33 | 0 <= m <= 1000 34 | ``` 35 | 36 | #### 解法 37 | 38 | ```java 39 | //从右上角开始找 40 | class Solution { 41 | public boolean findNumberIn2DArray(int[][] matrix, int target) { 42 | if (matrix == null || matrix.length == 0 || matrix[0].length == 0) return false; 43 | int i = 0; 44 | int j = matrix[0].length - 1; 45 | while(i >= 0 && i < matrix.length && j >= 0 && j < matrix[0].length) { 46 | if (target == matrix[i][j]) return true; 47 | else if (target < matrix[i][j]) j--; 48 | else i++; 49 | } 50 | return false; 51 | } 52 | } 53 | ``` 54 | 55 | -------------------------------------------------------------------------------- /算法/剑指Offer/05.替换空格.md: -------------------------------------------------------------------------------- 1 | #### [剑指 Offer 05. 替换空格](https://leetcode-cn.com/problems/ti-huan-kong-ge-lcof/) 2 | 3 | 难度 简单 4 | 5 | 请实现一个函数,把字符串 `s` 中的每个空格替换成"%20"。 6 | 7 | 8 | 9 | **示例 1:** 10 | 11 | ``` 12 | 输入:s = "We are happy." 13 | 输出:"We%20are%20happy." 14 | ``` 15 | 16 | 17 | 18 | **限制:** 19 | 20 | ``` 21 | 0 <= s 的长度 <= 10000 22 | ``` 23 | 24 | #### 解法 25 | 26 | ```java 27 | class Solution { 28 | public String replaceSpace(String s) { 29 | if (s == null || s.length() == 0) return s; 30 | StringBuilder sb = new StringBuilder(); 31 | for (int i = 0; i < s.length(); i++) { 32 | if (s.charAt(i) == ' ') { 33 | sb.append("%20"); 34 | } else { 35 | sb.append(s.charAt(i)); 36 | } 37 | } 38 | return sb.toString(); 39 | } 40 | } 41 | ``` 42 | 43 | -------------------------------------------------------------------------------- /算法/剑指Offer/06.从尾到头打印链表.md: -------------------------------------------------------------------------------- 1 | #### [剑指 Offer 06. 从尾到头打印链表](https://leetcode-cn.com/problems/cong-wei-dao-tou-da-yin-lian-biao-lcof/) 2 | 3 | 难度 简单 4 | 5 | 输入一个链表的头节点,从尾到头反过来返回每个节点的值(用数组返回)。 6 | 7 | 8 | 9 | **示例 1:** 10 | 11 | ``` 12 | 输入:head = [1,3,2] 13 | 输出:[2,3,1] 14 | ``` 15 | 16 | 17 | 18 | **限制:** 19 | 20 | ``` 21 | 0 <= 链表长度 <= 10000 22 | ``` 23 | 24 | #### 解法 25 | 26 | ```java 27 | //递归 28 | class Solution { 29 | public int[] reversePrint(ListNode head) { 30 | if (head == null) return new int[0]; 31 | List list = new ArrayList<>(); 32 | helper(list, head); 33 | int size = list.size(); 34 | int[] ret = new int[size]; 35 | for (int i = 0; i < size; i++) { 36 | ret[i] = list.get(i); 37 | } 38 | return ret; 39 | } 40 | private void helper(List list, ListNode head) { 41 | if (head == null) return; 42 | helper(list, head.next); 43 | list.add(head.val); 44 | } 45 | } 46 | 47 | //辅助栈 48 | class Solution { 49 | public int[] reversePrint(ListNode head) { 50 | if (head == null) return new int[0]; 51 | Deque stack = new ArrayDeque<>(); 52 | while (head != null) { 53 | stack.push(head.val); 54 | head = head.next; 55 | } 56 | int size = stack.size(); 57 | int[] ret = new int[size]; 58 | for (int i = 0; i < size; i++) { 59 | ret[i] = stack.pop(); 60 | } 61 | return ret; 62 | } 63 | } 64 | ``` 65 | 66 | -------------------------------------------------------------------------------- /算法/剑指Offer/07.重建二叉树.md: -------------------------------------------------------------------------------- 1 | #### [剑指 Offer 07. 重建二叉树](https://leetcode-cn.com/problems/zhong-jian-er-cha-shu-lcof/) 2 | 3 | 难度 中等 4 | 5 | 输入某二叉树的前序遍历和中序遍历的结果,请重建该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。 6 | 7 | 8 | 9 | 例如,给出 10 | 11 | ``` 12 | 前序遍历 preorder = [3,9,20,15,7] 13 | 中序遍历 inorder = [9,3,15,20,7] 14 | ``` 15 | 16 | 返回如下的二叉树: 17 | 18 | ``` 19 | 3 20 | / \ 21 | 9 20 22 | / \ 23 | 15 7 24 | ``` 25 | 26 | 27 | 28 | **限制:** 29 | 30 | ``` 31 | 0 <= 节点个数 <= 5000 32 | ``` 33 | 34 | #### 解法 35 | 36 | ```java 37 | class Solution { 38 | HashMap map = new HashMap<>(); 39 | int[] preorder; 40 | public TreeNode buildTree(int[] preorder, int[] inorder) { 41 | this.preorder = preorder; 42 | for (int i = 0; i < inorder.length; i++) { 43 | map.put(inorder[i], i); 44 | } 45 | return helper(0, 0, inorder.length - 1); 46 | } 47 | 48 | private TreeNode helper(int pre_root, int in_l, int in_r) { 49 | if (in_l > in_r) return null; 50 | TreeNode tn = new TreeNode(preorder[pre_root]); 51 | int i = map.get(preorder[pre_root]); 52 | tn.left = helper(pre_root + 1, in_l, i - 1); 53 | tn.right = helper(pre_root + 1 + (i - in_l), i + 1, in_r); 54 | return tn; 55 | } 56 | } 57 | ``` 58 | 59 | -------------------------------------------------------------------------------- /算法/剑指Offer/10-1.斐波那契数列.md: -------------------------------------------------------------------------------- 1 | #### [剑指 Offer 10- I. 斐波那契数列](https://leetcode-cn.com/problems/fei-bo-na-qi-shu-lie-lcof/) 2 | 3 | 难度简单 4 | 5 | 写一个函数,输入 `n` ,求斐波那契(Fibonacci)数列的第 `n` 项(即 `F(N)`)。斐波那契数列的定义如下: 6 | 7 | ``` 8 | F(0) = 0, F(1) = 1 9 | F(N) = F(N - 1) + F(N - 2), 其中 N > 1. 10 | ``` 11 | 12 | 斐波那契数列由 0 和 1 开始,之后的斐波那契数就是由之前的两数相加而得出。 13 | 14 | 答案需要取模 1e9+7(1000000007),如计算初始结果为:1000000008,请返回 1。 15 | 16 | 17 | 18 | **示例 1:** 19 | 20 | ``` 21 | 输入:n = 2 22 | 输出:1 23 | ``` 24 | 25 | **示例 2:** 26 | 27 | ``` 28 | 输入:n = 5 29 | 输出:5 30 | ``` 31 | 32 | 33 | 34 | **提示:** 35 | 36 | - `0 <= n <= 100` 37 | 38 | #### 解法 39 | 40 | ```java 41 | class Solution { 42 | public int fib(int n) { 43 | if(n == 0 || n == 1) return n; 44 | int a = 0, b = 1, s = 1; 45 | for(int i = 2; i < n; i++) { 46 | a = b; 47 | b = s; 48 | s = (a + b) % 1000000007; 49 | } 50 | return s; 51 | } 52 | } 53 | ``` 54 | 55 | -------------------------------------------------------------------------------- /算法/剑指Offer/10-2.青蛙跳台阶.md: -------------------------------------------------------------------------------- 1 | #### [剑指 Offer 10- II. 青蛙跳台阶问题](https://leetcode-cn.com/problems/qing-wa-tiao-tai-jie-wen-ti-lcof/) 2 | 3 | 难度简单 4 | 5 | 一只青蛙一次可以跳上1级台阶,也可以跳上2级台阶。求该青蛙跳上一个 `n` 级的台阶总共有多少种跳法。 6 | 7 | 答案需要取模 1e9+7(1000000007),如计算初始结果为:1000000008,请返回 1。 8 | 9 | **示例 1:** 10 | 11 | ``` 12 | 输入:n = 2 13 | 输出:2 14 | ``` 15 | 16 | **示例 2:** 17 | 18 | ``` 19 | 输入:n = 7 20 | 输出:21 21 | ``` 22 | 23 | **示例 3:** 24 | 25 | ``` 26 | 输入:n = 0 27 | 输出:1 28 | ``` 29 | 30 | **提示:** 31 | 32 | - `0 <= n <= 100` 33 | 34 | 注意:本题与主站 70 题相同:https://leetcode-cn.com/problems/climbing-stairs/ 35 | 36 | #### 解法 37 | 38 | ```java 39 | class Solution { 40 | public int numWays(int n) { 41 | int a = 0, b = 0, s = 1; 42 | for(int i = 0; i < n; i++) { 43 | a = b; 44 | b = s; 45 | s = (a + b) % 1000000007; 46 | } 47 | return s; 48 | } 49 | } 50 | ``` 51 | 52 | -------------------------------------------------------------------------------- /算法/剑指Offer/22.链表倒数第k个节点.md: -------------------------------------------------------------------------------- 1 | #### [剑指 Offer 22. 链表中倒数第k个节点](https://leetcode-cn.com/problems/lian-biao-zhong-dao-shu-di-kge-jie-dian-lcof/) 2 | 3 | 难度:简单 4 | 5 | 输入一个链表,输出该链表中倒数第k个节点。为了符合大多数人的习惯,本题从1开始计数,即链表的尾节点是倒数第1个节点。 6 | 7 | 例如,一个链表有 `6` 个节点,从头节点开始,它们的值依次是 `1、2、3、4、5、6`。这个链表的倒数第 `3` 个节点是值为 `4` 的节点。 8 | 9 | 10 | 11 | **示例:** 12 | 13 | ``` 14 | 给定一个链表: 1->2->3->4->5, 和 k = 2. 15 | 16 | 返回链表 4->5. 17 | ``` 18 | 19 | #### 解法 20 | 21 | ```java 22 | //步长 23 | class Solution { 24 | public ListNode getKthFromEnd(ListNode head, int k) { 25 | ListNode pre = head; 26 | ListNode cur = head; 27 | for (int i = 0; i < k; i++) cur = cur.next; 28 | while (cur != null) { 29 | cur = cur.next; 30 | pre = pre.next; 31 | } 32 | return pre; 33 | } 34 | } 35 | ``` 36 | 37 | -------------------------------------------------------------------------------- /算法/剑指Offer/40.最小的k个数.md: -------------------------------------------------------------------------------- 1 | #### [剑指 Offer 40. 最小的k个数](https://leetcode-cn.com/problems/zui-xiao-de-kge-shu-lcof/) 2 | 3 | 难度 简单 4 | 5 | 输入整数数组 `arr` ,找出其中最小的 `k` 个数。例如,输入4、5、1、6、2、7、3、8这8个数字,则最小的4个数字是1、2、3、4。 6 | 7 | 8 | 9 | **示例 1:** 10 | 11 | ``` 12 | 输入:arr = [3,2,1], k = 2 13 | 输出:[1,2] 或者 [2,1] 14 | ``` 15 | 16 | **示例 2:** 17 | 18 | ``` 19 | 输入:arr = [0,1,2,1], k = 1 20 | 输出:[0] 21 | ``` 22 | 23 | 24 | 25 | **限制:** 26 | 27 | - `0 <= k <= arr.length <= 10000` 28 | - `0 <= arr[i] <= 10000` 29 | 30 | #### 解法 31 | 32 | ```java 33 | //大顶堆 34 | class Solution { 35 | public int[] getLeastNumbers(int[] arr, int k) { 36 | if (arr == null || arr.length == 0 || k == 0) return new int[0]; 37 | Queue queue = new PriorityQueue<>((v1, v2) -> v2 - v1); 38 | for (int num : arr) { 39 | if (queue.size() < k) { 40 | queue.offer(num); 41 | } else if (num < queue.peek()) { 42 | queue.poll(); 43 | queue.offer(num); 44 | } 45 | } 46 | int size = queue.size(); 47 | int[] ret = new int[size]; 48 | for (int i = 0; i < size; i++) { 49 | ret[i] = queue.poll(); 50 | } 51 | return ret; 52 | } 53 | } 54 | ``` 55 | 56 | -------------------------------------------------------------------------------- /算法/剑指Offer/57-2.和为s的连续正数序列.md: -------------------------------------------------------------------------------- 1 | #### [剑指 Offer 57 - II. 和为s的连续正数序列](https://leetcode-cn.com/problems/he-wei-sde-lian-xu-zheng-shu-xu-lie-lcof/) 2 | 3 | 难度简单 4 | 5 | 输入一个正整数 `target` ,输出所有和为 `target` 的连续正整数序列(至少含有两个数)。 6 | 7 | 序列内的数字由小到大排列,不同序列按照首个数字从小到大排列。 8 | 9 | 10 | 11 | **示例 1:** 12 | 13 | ``` 14 | 输入:target = 9 15 | 输出:[[2,3,4],[4,5]] 16 | ``` 17 | 18 | **示例 2:** 19 | 20 | ``` 21 | 输入:target = 15 22 | 输出:[[1,2,3,4,5],[4,5,6],[7,8]] 23 | ``` 24 | 25 | 26 | 27 | **限制:** 28 | 29 | - `1 <= target <= 10^5` 30 | 31 | #### 解法 32 | 33 | ```java 34 | //滑动窗口 35 | class Solution { 36 | public int[][] findContinuousSequence(int target) { 37 | List ret = new ArrayList<>(); 38 | int i = 1; 39 | int j = 2; 40 | int sum = 3; 41 | while (i < j) { 42 | if (sum == target) { 43 | int[] tmp = new int[j - i + 1]; 44 | for (int k = i; k <= j; k++) { 45 | tmp[k - i] = k; 46 | } 47 | ret.add(tmp); 48 | } 49 | if (sum >= target) { 50 | sum -= i++; 51 | } else { 52 | sum += ++j; 53 | } 54 | } 55 | return ret.toArray(new int[0][]); 56 | } 57 | } 58 | ``` 59 | 60 | -------------------------------------------------------------------------------- /算法/剑指Offer/67.把字符串转换成整数.md: -------------------------------------------------------------------------------- 1 | #### [剑指 Offer 67. 把字符串转换成整数](https://leetcode-cn.com/problems/ba-zi-fu-chuan-zhuan-huan-cheng-zheng-shu-lcof/) 2 | 3 | 难度 中等 4 | 5 | 写一个函数 StrToInt,实现把字符串转换成整数这个功能。不能使用 atoi 或者其他类似的库函数。 6 | 7 | 8 | 9 | 首先,该函数会根据需要丢弃无用的开头空格字符,直到寻找到第一个非空格的字符为止。 10 | 11 | 当我们寻找到的第一个非空字符为正或者负号时,则将该符号与之后面尽可能多的连续数字组合起来,作为该整数的正负号;假如第一个非空字符是数字,则直接将其与之后连续的数字字符组合起来,形成整数。 12 | 13 | 该字符串除了有效的整数部分之后也可能会存在多余的字符,这些字符可以被忽略,它们对于函数不应该造成影响。 14 | 15 | 注意:假如该字符串中的第一个非空格字符不是一个有效整数字符、字符串为空或字符串仅包含空白字符时,则你的函数不需要进行转换。 16 | 17 | 在任何情况下,若函数不能进行有效的转换时,请返回 0。 18 | 19 | **说明:** 20 | 21 | 假设我们的环境只能存储 32 位大小的有符号整数,那么其数值范围为 [−231, 231 − 1]。如果数值超过这个范围,请返回 INT_MAX (231 − 1) 或 INT_MIN (−231) 。 22 | 23 | **示例 1:** 24 | 25 | ``` 26 | 输入: "42" 27 | 输出: 42 28 | ``` 29 | 30 | **示例 2:** 31 | 32 | ``` 33 | 输入: " -42" 34 | 输出: -42 35 | 解释: 第一个非空白字符为 '-', 它是一个负号。 36 | 我们尽可能将负号与后面所有连续出现的数字组合起来,最后得到 -42 。 37 | ``` 38 | 39 | **示例 3:** 40 | 41 | ``` 42 | 输入: "4193 with words" 43 | 输出: 4193 44 | 解释: 转换截止于数字 '3' ,因为它的下一个字符不为数字。 45 | ``` 46 | 47 | **示例 4:** 48 | 49 | ``` 50 | 输入: "words and 987" 51 | 输出: 0 52 | 解释: 第一个非空字符是 'w', 但它不是数字或正、负号。 53 | 因此无法执行有效的转换。 54 | ``` 55 | 56 | **示例 5:** 57 | 58 | ``` 59 | 输入: "-91283472332" 60 | 输出: -2147483648 61 | 解释: 数字 "-91283472332" 超过 32 位有符号整数范围。 62 | 因此返回 INT_MIN (−231) 。 63 | ``` 64 | 65 | #### 解法 66 | 67 | ```java 68 | class Solution { 69 | public int strToInt(String str) { 70 | char[] c = str.trim().toCharArray(); 71 | if(c.length == 0) return 0; 72 | int res = 0; 73 | int max = Integer.MAX_VALUE / 10; // 2147483647 74 | int isMinus = 1; 75 | if(c[0] == '-') isMinus = -1; 76 | for(int i = (isMinus == 1 && c[0] != '+') ? 0 : 1 ; i < c.length; i++) { 77 | if(c[i] < '0' || c[i] > '9') break; 78 | if(res > max || (res == max && c[i] > '7')) return isMinus == 1 ? Integer.MAX_VALUE : Integer.MIN_VALUE; 79 | res = res * 10 + c[i] - '0'; 80 | } 81 | return isMinus * res; 82 | } 83 | } 84 | ``` 85 | 86 | -------------------------------------------------------------------------------- /算法/剑指Offer/68-1.二叉搜索树中的最近公共祖先.md: -------------------------------------------------------------------------------- 1 | #### [剑指 Offer 68 - I. 二叉搜索树的最近公共祖先](https://leetcode-cn.com/problems/er-cha-sou-suo-shu-de-zui-jin-gong-gong-zu-xian-lcof/) 2 | 3 | 难度 简单 4 | 5 | 给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先。 6 | 7 | [百度百科](https://baike.baidu.com/item/最近公共祖先/8918834?fr=aladdin)中最近公共祖先的定义为:“对于有根树 T 的两个结点 p、q,最近公共祖先表示为一个结点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(**一个节点也可以是它自己的祖先**)。” 8 | 9 | 例如,给定如下二叉搜索树: root = [6,2,8,0,4,7,9,null,null,3,5] 10 | 11 | ![img](https://assets.leetcode-cn.com/aliyun-lc-upload/uploads/2018/12/14/binarysearchtree_improved.png) 12 | 13 | 14 | 15 | **示例 1:** 16 | 17 | ``` 18 | 输入: root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 8 19 | 输出: 6 20 | 解释: 节点 2 和节点 8 的最近公共祖先是 6。 21 | ``` 22 | 23 | **示例 2:** 24 | 25 | ``` 26 | 输入: root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 4 27 | 输出: 2 28 | 解释: 节点 2 和节点 4 的最近公共祖先是 2, 因为根据定义最近公共祖先节点可以为节点本身。 29 | ``` 30 | 31 | 32 | 33 | **说明:** 34 | 35 | - 所有节点的值都是唯一的。 36 | - p、q 为不同节点且均存在于给定的二叉搜索树中。 37 | 38 | #### 解法 39 | 40 | ```java 41 | class Solution { 42 | public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) { 43 | while (root != null) { 44 | if (p.val < root.val && q.val < root.val) { 45 | root = root.left; 46 | } else if (p.val > root.val && q.val > root.val) { 47 | root = root.right; 48 | } else { 49 | break; 50 | } 51 | } 52 | return root; 53 | } 54 | } 55 | ``` 56 | 57 | -------------------------------------------------------------------------------- /算法/剑指Offer/68-2.二叉树的最近公共祖先.md: -------------------------------------------------------------------------------- 1 | #### [剑指 Offer 68 - II. 二叉树的最近公共祖先](https://leetcode-cn.com/problems/er-cha-shu-de-zui-jin-gong-gong-zu-xian-lcof/) 2 | 3 | 难度 简单 4 | 5 | 给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。 6 | 7 | [百度百科](https://baike.baidu.com/item/最近公共祖先/8918834?fr=aladdin)中最近公共祖先的定义为:“对于有根树 T 的两个结点 p、q,最近公共祖先表示为一个结点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(**一个节点也可以是它自己的祖先**)。” 8 | 9 | 例如,给定如下二叉树: root = [3,5,1,6,2,0,8,null,null,7,4] 10 | 11 | ![img](https://assets.leetcode-cn.com/aliyun-lc-upload/uploads/2018/12/15/binarytree.png) 12 | 13 | 14 | 15 | **示例 1:** 16 | 17 | ``` 18 | 输入: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 1 19 | 输出: 3 20 | 解释: 节点 5 和节点 1 的最近公共祖先是节点 3。 21 | ``` 22 | 23 | **示例 2:** 24 | 25 | ``` 26 | 输入: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 4 27 | 输出: 5 28 | 解释: 节点 5 和节点 4 的最近公共祖先是节点 5。因为根据定义最近公共祖先节点可以为节点本身。 29 | ``` 30 | 31 | 32 | 33 | **说明:** 34 | 35 | - 所有节点的值都是唯一的。 36 | - p、q 为不同节点且均存在于给定的二叉树中。 37 | 38 | #### 解法 39 | 40 | ````java 41 | //递归 42 | class Solution { 43 | public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) { 44 | if(root == null) return null; 45 | if(p.val == root.val || q.val == root.val) return root; 46 | 47 | TreeNode left = lowestCommonAncestor(root.left, p, q); 48 | TreeNode right = lowestCommonAncestor(root.right, p, q); 49 | 50 | if(left == null) return right; 51 | else if(right == null) return left; 52 | else return root; 53 | } 54 | } 55 | ```` 56 | 57 | -------------------------------------------------------------------------------- /算法/算法训练/字符串/387.字符串中的第一个唯一字符.md: -------------------------------------------------------------------------------- 1 | #### [387. 字符串中的第一个唯一字符](https://leetcode-cn.com/problems/first-unique-character-in-a-string/) 2 | 3 | 难度简单360收藏分享切换为英文接收动态反馈 4 | 5 | 给定一个字符串,找到它的第一个不重复的字符,并返回它的索引。如果不存在,则返回 -1。 6 | 7 | 8 | 9 | **示例:** 10 | 11 | ``` 12 | s = "leetcode" 13 | 返回 0 14 | 15 | s = "loveleetcode" 16 | 返回 2 17 | ``` 18 | 19 | 20 | 21 | **提示:**你可以假定该字符串只包含小写字母。 22 | 23 | #### 解法 24 | 25 | ```java 26 | class Solution { 27 | public int firstUniqChar(String s) { 28 | if (s == null || s.length() == 0) return -1; 29 | Map map = new HashMap<>(); 30 | for (int i = 0; i < s.length(); i++) { 31 | char c = s.charAt(i); 32 | Integer count = map.getOrDefault(c, 0) + 1; 33 | map.put(c, count); 34 | } 35 | for (int i = 0; i < s.length(); i++) { 36 | if (map.get(s.charAt(i)) == 1) return i; 37 | } 38 | return -1; 39 | } 40 | } 41 | 42 | class Solution { 43 | public int firstUniqChar(String s) { 44 | int arr[] = new int[26];//26 个字母 45 | int length = s.length(); 46 | for(int i = 0; i < length; i++){ 47 | arr[s.charAt(i)- 'a']++; 48 | } 49 | for(int i = 0; i < length; i++){ 50 | if(arr[s.charAt(i) - 'a'] == 1) return i; 51 | } 52 | return -1; 53 | } 54 | } 55 | ``` 56 | 57 | -------------------------------------------------------------------------------- /算法/算法训练/字符串/58.最后一个单词的长度.md: -------------------------------------------------------------------------------- 1 | #### [58. 最后一个单词的长度](https://leetcode-cn.com/problems/length-of-last-word/) 2 | 3 | 难度简单289收藏分享切换为英文接收动态反馈 4 | 5 | 给你一个字符串 `s`,由若干单词组成,单词之间用空格隔开。返回字符串中最后一个单词的长度。如果不存在最后一个单词,请返回 0 。 6 | 7 | **单词** 是指仅由字母组成、不包含任何空格字符的最大子字符串。 8 | 9 | 10 | 11 | **示例 1:** 12 | 13 | ``` 14 | 输入:s = "Hello World" 15 | 输出:5 16 | ``` 17 | 18 | **示例 2:** 19 | 20 | ``` 21 | 输入:s = " " 22 | 输出:0 23 | ``` 24 | 25 | 26 | 27 | **提示:** 28 | 29 | - `1 <= s.length <= 104` 30 | - `s` 仅有英文字母和空格 `' '` 组成 31 | 32 | #### 解法 33 | 34 | ```java 35 | class Solution { 36 | public int lengthOfLastWord(String s) { 37 | if (s == null || s.length() == 0) return 0; 38 | s = s.trim(); 39 | int count = 0; 40 | for (int i = s.length() - 1; i >= 0; i--) { 41 | if (s.charAt(i) != ' ') count++; 42 | else break; 43 | } 44 | return count; 45 | } 46 | } 47 | ``` 48 | 49 | -------------------------------------------------------------------------------- /算法/算法训练/字符串/709.转换成小写字母.md: -------------------------------------------------------------------------------- 1 | #### [709. 转换成小写字母](https://leetcode-cn.com/problems/to-lower-case/) 2 | 3 | 难度简单 4 | 5 | 实现函数 ToLowerCase(),该函数接收一个字符串参数 str,并将该字符串中的大写字母转换成小写字母,之后返回新的字符串。 6 | 7 | 8 | 9 | **示例 1:** 10 | 11 | ``` 12 | 输入: "Hello" 13 | 输出: "hello" 14 | ``` 15 | 16 | **示例 2:** 17 | 18 | ``` 19 | 输入: "here" 20 | 输出: "here" 21 | ``` 22 | 23 | **示例** **3:** 24 | 25 | ``` 26 | 输入: "LOVELY" 27 | 输出: "lovely" 28 | ``` 29 | 30 | 通过次数62,665提交次数 31 | 32 | #### 解法 33 | 34 | ```java 35 | class Solution { 36 | public String toLowerCase(String str) { 37 | if (str == null || str.length() == 0) return str; 38 | char[] ch = str.toCharArray(); 39 | for (int i = 0; i < ch.length; i++) { 40 | if (ch[i] >= 'A' && ch[i] <= 'Z') { 41 | ch[i] += 32; 42 | } 43 | } 44 | return String.valueOf(ch); 45 | } 46 | } 47 | 48 | class Solution { 49 | public String toLowerCase(String str) { 50 | if (str == null || str.length() == 0) return str; 51 | char[] ch = str.toCharArray(); 52 | for (int i = 0; i < str.length(); i++) { 53 | ch[i] |= 32; 54 | } 55 | return String.valueOf(ch); 56 | } 57 | } 58 | //大写变小写、小写变大写:字符 ^= 32; 59 | //大写变小写、小写变小写:字符 |= 32; 60 | //大写变大写、小写变大写:字符 &= 33;(这句话是错误的!!!,应该是&= -33) 61 | ``` 62 | 63 | -------------------------------------------------------------------------------- /算法/算法训练/字符串/8.字符串转换整数 (atoi).md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/算法/算法训练/字符串/8.字符串转换整数 (atoi).md -------------------------------------------------------------------------------- /计算机组成原理/002.数据的表示和运算.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/计算机组成原理/002.数据的表示和运算.md -------------------------------------------------------------------------------- /计算机组成原理/003.存储系统.md: -------------------------------------------------------------------------------- 1 | ## 1 存储器的层次结构 2 | 3 | ### 1.1 存储器分类 4 | 5 | #### 1.1.1 按层次分类 6 | 7 | * 主存 8 | * 辅存 9 | * 高速缓冲存储器(cache) 10 | 11 | #### 1.1.2 存储介质分类 12 | 13 | 14 | 15 | #### 1.1.3 存储方式分类 16 | 17 | * 随机存储器(RAM) 18 | * 只读存储器(ROM) 19 | 20 | #### 1.1.4 信息可保存性 21 | 22 | * 易失性存储器 23 | * 非易失性存储器 24 | 25 | ### 1.2 存储器的性能指标 26 | 27 | * 存储容量 28 | * 单位成本 29 | * 主存带宽 30 | 31 | ### 1.3 存储器的层次化结构 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /计算机组成原理/004.指令系统.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/计算机组成原理/004.指令系统.md -------------------------------------------------------------------------------- /计算机组成原理/005.中央处理器.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/计算机组成原理/005.中央处理器.md -------------------------------------------------------------------------------- /计算机组成原理/006.总线.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/计算机组成原理/006.总线.md -------------------------------------------------------------------------------- /计算机组成原理/007.IO系统.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/计算机组成原理/007.IO系统.md -------------------------------------------------------------------------------- /计算机网络/004.网络层.md: -------------------------------------------------------------------------------- 1 | ## 1 网络层的功能 2 | 3 | ### 1.1 异构网络互联 4 | 5 | #### 1.1.1 异构网络 6 | 7 | 不同的寻址方案、网络介入机制、差错处理方法、路由选择机制 8 | 9 | #### 1.1.2 网络互联 10 | 11 | 将两个以上的计算机网络,通过一定的方法,用一种或多种通信处理设备(中间设备)**相互连接**起来,构成大网络。 12 | 13 | 使用物理层或数据链路层的中继系统只是扩大网络,不能称为网络互联。 14 | 15 | 中继系统: 16 | 17 | * 物理层:中继器、集线器(Hub) 18 | * 数据链路层:网桥、交换机 19 | * 网络层:路由器 20 | * 网络层以上:网关 21 | 22 | ### 1.2 路由与转发 23 | 24 | 路由器主要的两个功能: 25 | 26 | * 路由选择:确定哪一条路径 27 | * 分组转发:当一个分组到达时所采取的动作 28 | 29 | ### 1.3 拥塞转发 30 | 31 | 在通信子网中,因出现过量的分组而引起网络性能下降的现象称为拥塞。 32 | 33 | ## 2 路由算法 34 | 35 | ### 2.1 静态路由与动态路由 36 | 37 | 静态路由算法(非自适应路由算法):管理员手工配置的路由信息 38 | 39 | 动态路由算法(自适应路由算法):路由器上的路由表项是通过相互连接的路由器之间彼此交换信息,然后按照一定的算法优化出来,选择最优的路由。 40 | 41 | ### 2.2 动态路由算法 42 | 43 | - 距离-向量路由算法:所有结点都定期地将它们的整个路由选择表传送给所有与之直接相邻的结点。 44 | - 链路状态路由算法:要求每个参与该算法的结点都具有完全的网络拓扑信息,主动测试所有相邻的结点状态,定期把状态传播给其他结点。 45 | 46 | ### 2.3 层次路由 47 | 48 | 当网络规模扩大时,路由器的路由表成比例堤增大,所以需要层次路由。 49 | 50 | 路由选择协议: 51 | 52 | - 内部网关协议(IGP):自治系统内所使用的路由选择协议 53 | - 外部网关协议(EGP):不同自治系统的路由之间交换路由信息,并负责为分组在不同自治系统之间选择最优的路径 54 | 55 | ## 3 IPv4 56 | 57 | ### 3.1 概述 58 | 59 | IP 地址:表示路由器主机的接口 ,<网络号>,<主机号> -> 192.168.1.1 60 | 61 | ### 3.2 IPv4分组 62 | 63 | IPv4 即普通使用的 IP (版本 4) 64 | 65 | 分组格式: 66 | 67 | ![](../asset/ip数据报的格式.png) 68 | 69 | IP数据报分片: 70 | 71 | * 最大传送单元(MTU):一个链路层数据报能承载的最大数据量 72 | - 以太网:1500B 73 | - 广域网:一般不超过576B 74 | * 当数据报长度大于链路MTU时,就会进行进行**分片传输** 75 | 76 | ### 3.3 IPv4 地址与 NAT 77 | 78 | IP 地址分类: 79 | 80 | ![](../asset/分类ip地址.png) 81 | 82 | 特殊含义地址: 83 | 84 | * 主机号全为 1,本网络的广播地址 85 | * 主机号全为 0,本网络本身 86 | * 127.0.0.0,本机本身 87 | * 255.255.255.255,表示整个 TCP/IP网络广播地址 88 | * 0.0.0.0 表示本网络上的本主机 89 | 90 | **NET(网络地址转换)**:在专用网连接到因特网的路由器安装 NAT软件,安装了 NAT 软件的路由器叫 NAT路由器,至少有一个有效的外部全球 IP 地址。 91 | 92 | ### 3.4 子网划分与子网掩码、CIDR 93 | 94 | ### 3.5 IP地址与硬件地址 95 | 96 | ### 3.6 地址解释协议(ARP) 97 | 98 | ### 3.7 动态主机配置协议(DHCP) 99 | 100 | ### 3.8 网际控制报文协议(ICMP) 101 | 102 | ## 4 IPV6 103 | 104 | ### 4.1 功能 105 | 106 | ### 4.2 IPV6的特点 107 | 108 | ### 4.3 IPV6地址 109 | 110 | ### 4.4 IPV4向IPV6过渡 111 | 112 | ## 5 路由协议 113 | 114 | ### 5.1 自治系统(AS) 115 | 116 | ### 5.2 域内路由与域间路由 117 | 118 | ### 5.3 路由信息协议(RIP) 119 | 120 | ### 5.4 开放最短路径优先(OSPF)协议 121 | 122 | ### 5.5 边界网关协议(BGP) 123 | 124 | ### 5.6 路由协议比较 125 | 126 | ## 6 IP组播 127 | 128 | ### 6.1 概念 129 | 130 | ### 6.2 地址 131 | 132 | ### 6.3 IGMP 与组播路由算法 133 | 134 | ## 7 移动IP 135 | 136 | ### 7.1 概念 137 | 138 | ### 7.2 通信过程 139 | 140 | ## 8 网络层设备 141 | 142 | ### 8.1 路由器的组成和功能 143 | 144 | ### 8.2 路由表与路由转发 -------------------------------------------------------------------------------- /计算机网络/006.应用层.md: -------------------------------------------------------------------------------- 1 | ## 1 网络应用模型 2 | 3 | ### 1.1 客户/服务器模型 4 | 5 | 总是打开一个主机称为服务器,服务与其他客户机的请求。 6 | 7 | ### 1.2 P2P 模型 8 | 9 | 任意一对计算机-称为对等方,直接相互通信。(每一台计算机既是客户机,又是服务器) 10 | 11 | ![](../asset/模型.png) 12 | 13 | ## 2 域名系统(DNS) 14 | 15 | 具有特定含义的主机名(www.baidu.com -> 192.139.1.1)转换成 IP 地址。 16 | 17 | ### 2.1 概述 18 | 19 | ### 2.2 层次域名空间 20 | 21 | www.baidu.com -> 三级域名.二级域名.顶级域名 22 | 23 | 顶级域名(国家顶级域名(cn、us、jp)、通用顶级域名(com、org、net)、基础结构域名(arpa-> 只有一个,叫方向域名解析(方向域名))) 24 | 25 | ### 2.3 域名服务器 26 | 27 | 域名系统被设计成联机分布式的数据库系统,并采用客户/服务器模型。4 种类型的域名服务器。 28 | 29 | * 根域名服务器:管辖顶级域 30 | * 顶级域名服务器:管理二级域名 31 | * 授权域名服务器(权限域名服务器):管辖的主机名转换为该主机的 IP 地址 32 | * 本地域名服务器:对域名系统非常重要,ISP、一所大学、甚至一个系都可以有一个本地域名服务器。 33 | 34 | ![](../asset/DNS层次结构.jpg) 35 | 36 | ### 2.4 域名解析过程 37 | 38 | 正向解析:域名 -> IP 39 | 反向解析:IP -> 域名 40 | 41 | 当客户端需要域名解析时,通过本机的DNS客户端构造一个DNS请求报文,以 UDP 数据报文 发往本地域名服务器。 42 | 43 | 域名解析有两种方式: 44 | 45 | * 递归查询(负载过大,不常用) 46 | * 递归与迭代相结合查询 47 | 48 | ![](../asset/域名解析过程.jpg) 49 | 50 | 为了提高 DNS 的查询效率,通常采用**高速缓存**,DNS 会将 DNS 信息缓存到高速缓存中,并且美国一段时间就会丢弃高速缓存。 51 | 52 | ## 3 文件传输协议(FTP) 53 | 54 | ### 3.1 FTP 的工作原理 55 | 56 | 使用 TCP 可靠的除数服务,一个 FTP 服务器可以为多个客户进程提高服务,分为两个部分:主进程(接收请求),若干从属进程(处理单个请求)。 57 | 58 | FTP 服务器在整个会话期间**保留状态信息**。 59 | 60 | ### 3.2 控制连接与数据连接 61 | 62 | FTP 工作时使用两个并行 TCP 连接:控制连接(port:21)、数据连接(post:20) 63 | 64 | ![](../asset/控制连接.jpg) 65 | 66 | 67 | 68 | ## 4 电子邮件 69 | 70 | ### 4.1 电子邮件系统的组成结构 71 | 72 | 电子邮件是一种一步异步通信方式。 73 | 74 | 一个电子邮件系统由三个组成构件:用户代理(User Agent)、邮件服务器、电子邮件使用协议,如 SMTP、POP3(或 IMAP) 等。 75 | 76 | ![](../asset/电子邮件.jpg) 77 | 78 | * 用户代理(UA):用户与电子邮件系统的接口,如 Outlook、Foxmain 等。 79 | * 邮件服务器:组成电子邮件系统的核心。 80 | * 邮件发送协议和读取协议:SMTP(PUSH 推方式)、POP3(PULL 拉)。 81 | 82 | 83 | 84 | ![](../asset/电子邮件发送接收过程.jpg) 85 | 86 | ### 4.2 电子邮件格式与 MIME 87 | 88 | 电子邮件格式: 89 | 90 | ```java 91 | From:hoo@hus.edu.cn 92 | To:3988099@qq.com 93 | Subject:Say hello 94 | balabala.... 95 | 96 | 首部(From、To、Subject) + 主体 97 | ``` 98 | 99 | ### 4.3 SMTP 和 POP3 100 | 101 | #### 4.3.1 SMTP 102 | 103 | 简单邮件传输协议:提供可靠有效的电子邮件传输的协议,用的是 TCP 连接,端口号 25。 104 | 105 | 三个部分:连接建立、邮件传送、连接释放 106 | 107 | #### 4.3.2 POP3 108 | 109 | 邮局协议:简单功能有限的邮件读取协议,传输层使用 TCP ,端口 110。 110 | 111 | ## 5 万维网(WWW) 112 | 113 | ### 5.1 WWW 的概念与组成结构 114 | 115 | 三个标准组成: 116 | 117 | * 统一资源定位符(URL):负责标识万维网上的各种文档。 118 | * 超文本传输协议(HTTP 端口 80):应用层协议,使用 TCP 谅解进行可可靠传输。 119 | * 超文本标记语言(HTML):文档结构标记语言,使用约定的标记对页面上的各种信息进行描述。 120 | 121 | ![](../asset/www.jpg) 122 | 123 | ### 5.2 浏览器访问过程 124 | 125 | ```java 126 | 1.浏览器分析链接指向页面的 URL (http://www.baidu.com/index.html) 127 | 2.浏览器解析 DNS 请求解析 IP 地址 128 | 3.域名系统 DNS 解析 IP 地址 129 | 4.建立 TCP 连接(端口 80) 130 | 5.发出 HTTP 请求 GET /index.html 131 | 6.服务器 HTTP 响应返回 132 | 7.释放 TCP 连接 133 | 8.解析 html 文件,显示 134 | ``` 135 | 136 | ### 5.3 HTTP 特点 137 | 138 | * http 是无状态的 139 | * 通常使用 Cookie 加数据库跟踪用户活动 140 | * 采用 TCP 作为运输层协议,保证数据可靠传输,但,HTTP 是无连接的 141 | * HTTP 即可以使用非持久连接,也可以使用持久连接(HTTP/1.1 支持) 142 | 143 | ![](../asset/http请求.jpg) 144 | 145 | ### 5.4 HTTP 报文结构 146 | 147 | * 请求报文:客户端 -> 服务器 148 | * 响应报文:服务器 -> 客户端 149 | 150 | ![](../asset/http报文结构.jpg) 151 | 152 | ### 5.5 常用应用层协议 153 | 154 | ![](../asset/应用层协议.jpg) -------------------------------------------------------------------------------- /计算机网络/other/001.HTTP1.0、HTTP2.0、HTTP3.0.md: -------------------------------------------------------------------------------- 1 | ## 1 HTTP 优化 2 | 3 | 影响 HTTP 网络请求的因素: 4 | 5 | * 带宽 6 | * 延迟 7 | - 线头器阻塞(HOL Blocking):是一种出现在[缓存](https://baike.baidu.com/item/缓存)式通信网络交换中的一种现象。交换通常由[缓存](https://baike.baidu.com/item/缓存)式输入端口、一个交换架构以及缓存式输出端口组成。**当在相同的输入端口上到达的包被指向不同的输出端口的时候就会出现线头阻塞**。 8 | - DNS查询(DNS Lookup) 9 | - 建立连接(Initial connection) 10 | 11 | ## 2 HTTP 12 | 13 | ### 2.1 HTTP 1.0 14 | 15 | * 请求与响应支持 HTTP 头,响应含状态行,增加了状态码 16 | * 支持 HEAD,POST 方法 17 | * 支持传输 HTML 文件以外其他类型的内容 18 | 19 | 缺点: 20 | 21 | * **非持久连接**:客户端必须为每一个待请求的对象建立并维护一个新的连接,短连接增加了网络传输的负担 22 | 23 | ### 2.2 HTTP 1.1 24 | 25 | * 支持长连接 26 | * 在HTTP1.0的基础上引入了更多的缓存控制策略 27 | * 引入了**请求范围**设置,优化了带宽 28 | * 在错误通知管理中新增了错误状态响应码 29 | * 增加了Host头处理,可以传递主机名(hostname) 30 | 31 | ### 2.3 HTTPS 32 | 33 | - HTTPS 运行在安全套接字协议(Secure Sockets Layer,**SSL** )或传输层安全协议(Transport Layer Security,**TLS**)之上,所有在TCP中传输的内容都需要经过加密。 34 | - 连接方式不同,HTTP的端口是 80,HTTPS的端口是 443. 35 | - HTTPS 可以有效防止运营商劫持。 36 | 37 | ### 2.4 HTTP 1.x优化(SPDY) 38 | 39 | SPDY :**在 HTTP 之前做了一层会话层**,为了达到减少页面加载时间的目标,SPDY 引入了一个新的二进制分帧数据层,以实现优先次序、最小化及消除不必要的网络延迟,目的是更有效地利用底层 TCP 连接。 40 | 41 | - 多路复用,为多路复用设立了请求优先级 42 | - 对 header 部分进行了压缩 43 | - 引入了 HTTPS 加密传输 44 | - 客户端可以在缓存中取到之前请求的内容 45 | 46 | ### 2.5 HTTP 2.0 47 | 48 | * 使用二进制分帧层:在应用层与传输层之间增加一个二进制分帧层 49 | * **多路复用** 50 | * 服务端推送:logo、CSS 文件直接推给客户端 51 | * 数据流优先级:对数据流可以设置优先值,比如设置先传 css 文件等 52 | * 头部压缩 53 | * 支持明文传输,HTTP 1.X 强制使用 SSL/TLS 加密传输。 54 | 55 | ![](../../asset/http2.0.jpg) 56 | 57 | ### 2.6 HTTP 3.0(QUIC) 58 | 59 | QUIC (Quick UDP Internet Connections),快速 UDP 互联网连接,基于 **UDP 协议**的。 60 | 61 | #### 2.6.1 线头阻塞(HOL)问题的解决更为彻底 62 | 63 | 基于TCP的HTTP/2,尽管从逻辑上来说,不同的流之间相互独立,不会相互影响,但在实际传输方面,数据还是要一帧一帧的发送和接收,一旦某一个流的数据有丢包,则同样会阻塞在它之后传输的流数据传输。而基于 UDP 的 **QUIC 协议**则可以更为彻底地解决这样的问题,让不同的流之间真正的实现相互独立传输,互不干扰。 64 | 65 | #### 2.6.2 切换网络时的连接保持 66 | 67 | 当前移动端的应用环境,用户的网络可能会经常切换,比如从办公室或家里出门,WiFi断开,网络切换为 3G 或 4G。基于TCP的协议,由于切换网络之后,IP会改变,因而之前的连接不可能继续保持。而基于 UD P的 QUIC 协议,则可以内建与 TCP 中不同的连接标识方法,从而在网络完成切换之后,恢复之前与服务器的连接。 -------------------------------------------------------------------------------- /计算机网络/计算机网络.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yoyiyi/SoleilNotes/4db41a9d68a2f3ed2a07739a547af9f625f9c799/计算机网络/计算机网络.md -------------------------------------------------------------------------------- /设计模式/001.设计模式七大原则.md: -------------------------------------------------------------------------------- 1 | ## 1 设计模式的目的 2 | 3 | 编写软件过程中,面临着来自耦合性、内聚性以及可维护性,可扩展性,重用性,灵活性等多方面的挑战,设计模式是为了让程序,具有更好代码重用性、可读性、可扩展性、可靠性。 4 | 5 | 设计模式是解决特定问题的一系列套路,是前辈们的代码设计经验的总结,具有一定的普遍性,可以反复使用。 6 | 7 | ## 2 设计模式的七大原则 8 | 9 | ### 2.1 单一职责原则 10 | 11 | 一个类应该只负责一项职责。 12 | 13 | ### 2.2 接口隔离原则 14 | 15 | 客户端不应该依赖它不需要的接口,即一个类对另一个类的依赖应该建立在最小的接口上。 16 | 17 | ### 2.3 依赖倒置原则 18 | 19 | * 高层模块不应该依赖低层模块,二者都应该依赖其抽象。 20 | 21 | * 抽象不应该依赖细节,细节应该依赖抽象。 22 | 23 | * 依赖倒转(倒置)的中心思想是**面向接口编程**。 24 | 25 | * 依赖倒转原则是基于这样的设计理念:相对于细节的多变性,抽象的东西要稳定的多。以抽象为基础搭建的架构比以细节为基础的架构要稳定的多。在 java 中,抽象指的是接口或抽象类,细节就是具体的实现类。 26 | 27 | * 使用接口或抽象类的目的是制定好规范,而不涉及任何具体的操作,把展现细节的任务交给他们的实现类去完成。 28 | 29 | ### 2.4 里式替换原则 30 | 31 | * 子类中尽量不要重写父类的方法。 32 | * 任何基类可以出现的地方,子类一定可以出现。 33 | * 里氏替换原则告诉我们,继承实际上让两个类耦合性增强了,在适当的情况下,可以通过聚合,组合,依赖 来解决问题。 34 | 35 | ### 2.5 开闭原则 36 | 37 | * 一个软件实体如类,**模块和函数应该对扩展开放(对提供方),对修改关闭(对使用方)**。用抽象构建框架,用实现扩展细节。 38 | * 当软件需要变化时,尽量通过扩展软件实体的行为来实现变化,而不是通过修改已有的代码来实现变化。 39 | * 最少知道原则,即一个类对自己依赖的类知道的越少越好。 40 | 41 | ### 2.6 迪米特原则 42 | 43 | * 一个对象应该对其他对象**保持最少的了解**。 44 | * 类与类关系越密切,耦合度越大。 45 | * 又叫最少知道原则,即一个类对自己依赖的类知道的越少越好。 46 | 47 | ### 2.7 合成复用原则 48 | 49 | * 尽量使用合成/聚合的方式,而不是使用继承。 50 | 51 | -------------------------------------------------------------------------------- /设计模式/002.设计模式简介.md: -------------------------------------------------------------------------------- 1 | ## 1 简介 2 | 3 | 软件设计模式(Software Design Pattern),又称设计模式,是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。它描述了在软件设计过程中的一些不断重复发生的问题,以及该问题的解决方案。也就是说,它是解决特定问题的一系列套路,是前辈们的代码设计经验的总结,具有一定的普遍性,可以反复使用。 4 | 5 | ## 2 分类 6 | 7 | - **创建型模式** 8 | 9 | 描述“**怎样创建对象**”,它的主要特点是”将对象的创建与使用分离“,包括以下 5 种: 10 | 11 | * 单例 12 | * 原型 13 | * 工厂方法 14 | * 抽象工厂 15 | * 建造者 16 | 17 | - **结构型模式** 18 | 19 | 描述**如何将类或对象按某种布局组成更大的结构**,包括以下 7 种: 20 | 21 | * 代理 22 | * 适配器 23 | * 桥接 24 | * 装饰 25 | * 外观 26 | * 享元 27 | * 组合 28 | 29 | - **行为型模式** 30 | 31 | 描述**类或对象之间怎样相互协作共同完成单个对象无法单独完成的任务,以及怎样分配职责**,包括以下 11 种: 32 | 33 | * 模板方法 34 | * 策略 35 | * 命令 36 | * 职责链 37 | * 状态 38 | * 观察者 39 | * 中介者 40 | * 迭代器 41 | * 访问者 42 | * 备忘录 43 | * 解释器 -------------------------------------------------------------------------------- /设计模式/003.UML.md: -------------------------------------------------------------------------------- 1 | ## 1 UML 图 2 | 3 | 统一建模语言(Unified Modeling Language,UML)是用来设计软件的可视化建模语言。它的特点是简单、统一、图形化、能表达软件设计中的动态与静态信息。 4 | 5 | UML 从目标系统的不同角度出发,定义了用例图、类图、对象图、状态图、活动图、时序图、协作图、构件图、部署图等 9 种图。 6 | 7 | ## 2 类图 8 | 9 | 类图(Class diagram)是显示了模型的静态结构,特别是模型中存在的类、类的内部结构以及它们与其他类的关系等。类图不显示暂时性的信息。类图是面向对象建模的主要组成部分。它既用于应用程序的系统分类的一般概念建模,也用于详细建模,将模型转换成编程代码。类图也可用于数据建模。 10 | 11 | ### 2.2 表示方式 12 | 13 | ![](../asset/类图.png) 14 | 15 | * +:表示 public 16 | * -:表示 private 17 | * \#:表示 protected 18 | 19 | 属性的完整表示方式是: **可见性 名称 :类型 [ = 缺省值]** 20 | 21 | 方法的完整表示方式是: **可见性 名称(参数列表) [ : 返回类型]** 22 | 23 | ### 2.3 类与类的关系 24 | 25 | #### 2.3.1 关联关系 26 | 27 | 对象之间的一种引用关系,用于表示一类对象与另一类对象之间的联系。 28 | 29 | * 单向关联 30 | 31 | ![](../asset/单向关联.png) 32 | 33 | * 双向关联 34 | 35 | ![](../asset/双向关联.png) 36 | 37 | * 自关联 38 | 39 | ![](../asset/自关联.png) 40 | 41 | #### 2.3.2 聚合关系 42 | 43 | 是关联关系的一种,是强的关联关系。聚合关系是整体和个体的关系。关联关系的两个类处于同一层次上,而聚合关系两个类处于不同的层次,一个是整体,一个是部分。 44 | 45 | ![](../asset/聚合关系.png) 46 | 47 | #### 2.3.3 组合关系 48 | 49 | 是关联关系的一种,是比聚合关系强的关系。它要求普通的聚合关系中代表整体的对象负责代表部分的对象的生命周期,组合关系不能共享。 50 | 51 | ![](../asset/组合关系.png) 52 | 53 | #### 2.3.4 依赖关系 54 | 55 | 依赖关系是一种使用关系,它是对象之间耦合度最弱的一种关联方式,是临时性的关联。在代码中,某个类的方法通过局部变量、方法的参数或者对静态方法的调用来访问另一个类(被依赖类)中的某些方法来完成一些职责。 56 | 57 | ![](../asset/依赖关系.png) 58 | 59 | #### 2.3.5 继承关系 60 | 61 | 继承关系是对象之间耦合度最大的一种关系,表示一般与特殊的关系,是父类与子类之间的关系,是一种继承关系。 62 | 63 | ![](../asset/继承关系.png) 64 | 65 | #### 2.3.6 实现关系 66 | 67 | 实现关系是接口与实现类之间的关系。在这种关系中,类实现了接口,类中的操作实现了接口中所声明的所有的抽象操作。 68 | 69 | ![](../asset/实现关系.png) -------------------------------------------------------------------------------- /设计模式/007.创建者模式_建造者模式.md: -------------------------------------------------------------------------------- 1 | ## 1 建造者模式 2 | 3 | 1. 建造者模式(**Builder** **Pattern**) 又叫生成器模式,是一种对象构建模式。它可以将复杂对象的建造过程抽象出来(抽象类别),使这个抽象过程的不同实现方法可以构造出不同表现(属性)的对象。 4 | 2. 建造者模式是一步一步创建一个复杂的对象,它允许用户只通过指定复杂对象的类型和内容就可以构建它们, 用户不需要知道内部的具体构建细节。 5 | 6 | 四个角色: 7 | 8 | * Product(产品角色): 一个具体的产品对象。 9 | 10 | * Builder(抽象建造者): 创建一个 Product 对象的各个部件指定的 接口**/**抽象类。 11 | 12 | * ConcreteBuilder(具体建造者): 实现接口,构建和装配各个部件。 13 | 14 | * Director(指挥者): 构建一个使用 Builder 接口的对象。它主要是用于创建一个复杂的对象。它主要有两个作用,一是:隔离了客户与对象的生产过程,二是:负责控制产品对象的生产过程。 15 | 16 | ## 2 例子 17 | 18 | 使用建造者模式创建一台电脑。 19 | 20 | ```java 21 | //具体要构建的对象,电脑 22 | public class Computer { 23 | private String cpu; 24 | private String memory; 25 | private String disk; 26 | 27 | public String getCpu() { 28 | return cpu; 29 | } 30 | 31 | public void setCpu(String cpu) { 32 | this.cpu = cpu; 33 | } 34 | 35 | public String getMemory() { 36 | return memory; 37 | } 38 | 39 | public void setMemory(String memory) { 40 | this.memory = memory; 41 | } 42 | 43 | public String getDisk() { 44 | return disk; 45 | } 46 | 47 | public void setDisk(String disk) { 48 | this.disk = disk; 49 | } 50 | 51 | @Override 52 | public String toString() { 53 | return "Computer{" + 54 | "cpu='" + cpu + '\'' + 55 | ", memory='" + memory + '\'' + 56 | ", disk='" + disk + '\'' + 57 | '}'; 58 | } 59 | } 60 | 61 | //抽象接口来描述电脑构建和装配过程 62 | public interface ComputerBuilder { 63 | 64 | ComputerBuilder buildCpu(String cpu); 65 | 66 | ComputerBuilder buildMemory(String memory); 67 | 68 | ComputerBuilder buildDisk(String disk); 69 | 70 | Computer build(); 71 | } 72 | 73 | //定义ComputerBuild接口的具体实现,实现构建方法和装配电脑的各个组件 74 | public class ComputerConcreteBuilder implements ComputerBuilder { 75 | 76 | private final Computer computer = new Computer(); 77 | 78 | public ComputerBuilder buildCpu(String cpu) { 79 | computer.setCpu(cpu); 80 | return this; 81 | } 82 | 83 | public ComputerBuilder buildMemory(String memory) { 84 | computer.setMemory(memory); 85 | return this; 86 | } 87 | 88 | public ComputerBuilder buildDisk(String disk) { 89 | computer.setDisk(disk); 90 | return this; 91 | } 92 | 93 | public Computer build(){ 94 | return computer; 95 | } 96 | } 97 | 98 | public class TestComputer { 99 | public static void main(String[] args) { 100 | ComputerBuilder builder = new ComputerConcreteBuilder(); 101 | Computer computer = builder.buildCpu("AMD") 102 | .buildMemory("三星") 103 | .buildDisk("金士顿") 104 | .build(); 105 | System.out.println(computer);//Computer{cpu='AMD', memory='三星', disk='金士顿'} 106 | } 107 | } 108 | 109 | ``` 110 | 111 | ## 3 注意事项 112 | 113 | 1. 客户端(使用程序)不必知道产品内部组成的细节,将产品本身与产品的创建过程解耦,使得相同的创建过程可以创建不同的产品对象。 114 | 115 | 2. 每一个具体建造者都相对独立,而与其他的具体建造者无关,因此可以很方便地替换具体建造者或增加新的具体建造者, 用户使用不同的具体建造者即可得到不同的产品对象。 116 | 3. 主要解决在软件系统中,有时候面临着"一个复杂对象"的创建工作,其通常由各个部分的子对象用一定的算法构成;由于需求的变化,这个复杂对象的各个部分经常面临着剧烈的变化,但是将它们组合在一起的算法却相对稳定。 117 | 4. 抽象工厂模式 VS 建造者模式 118 | * 抽象工厂模式:实现对产品家族(一系列具有不同分类维度的产品组合)的创建,不需要关心构建过程,只关心什么产品由什么工厂生产即可。 119 | * 建造者模式:要求按照指定的蓝图建造产,建造者模式更加关注与零件装配的顺序。 120 | 121 | -------------------------------------------------------------------------------- /设计模式/008.结构型模式_适配器模式.md: -------------------------------------------------------------------------------- 1 | ## 1 适配器模式 2 | 3 | 适配器模式(Adapter Pattern):将某个类的接口转换成客户端期望的另一个接口表示,主的目的是兼容性,让原本因接口不匹配不能一起工作的两个类可以协同工作,其别名为包装器(Wrapper),属于结构型模式,主要分为三类:类适配器模式、对象适配器模式、接口适配器模式。 4 | 5 | ## 2 工作原理 6 | 7 | 1. 适配器模式:将一个类的接口转换成另一种接口,让原本接口不兼容的类可以兼容。 8 | 2. 从用户的角度看不到被适配者,是解耦的。 9 | 3. 用户调用适配器转化出来的目标接口方法,适配器再调用被适配者的相关接口方法。 10 | 4. 用户收到反馈结果,感觉只是和目标接口交互。 11 | 12 | ## 3 类适配器模式 13 | 14 | 手机需要 5V(dst 目标)充电 ,现在有 220V 交流电(src 被适配者),需要转接头转成 5V(充电器)。 15 | 16 | ```java 17 | //适配接口 18 | public interface IVoltage5V { 19 | int output5V(); 20 | } 21 | 22 | public class Phone { 23 | public void charging(IVoltage5V iVoltage5V){ 24 | if (iVoltage5V.output5V() > 5){ 25 | System.out.println("不能充电"); 26 | }else if (iVoltage5V.output5V() == 5){ 27 | System.out.println("可以充电"); 28 | } 29 | 30 | } 31 | } 32 | 33 | //被适配的类 34 | public class Voltage220V { 35 | //输出 220V 的电压 36 | public int output220V() { 37 | int src = 220; 38 | System.out.println("电压 = " + src + "伏"); 39 | return src; 40 | } 41 | } 42 | 43 | //适配器类 44 | public class VoltageAdapter extends Voltage220V implements IVoltage5V { 45 | @Override 46 | public int output5V() { 47 | int output220V = output220V(); 48 | //转换成 5v 49 | return output220V / 44; 50 | } 51 | } 52 | 53 | public class TestClient { 54 | public static void main(String[] args) { 55 | VoltageAdapter adapter = new VoltageAdapter(); 56 | Phone phone = new Phone(); 57 | phone.charging(adapter); 58 | } 59 | } 60 | 61 | ``` 62 | 63 | 1. Java 是单继承机制,所以类适配器需要继承 src 类这一点算是一个缺点, 因为这要求 dst 必须是接口,有一定局限性。 64 | 65 | 2. src 类的方法在 Adapter 中都会暴露出来,也增加了使用的成本。 66 | 67 | 3. 由于其继承了 src 类,所以它可以根据需求重写 src 类的方法,使得 Adapter 的灵活性增强了。 68 | 69 | ## 4 对象适配器模式 70 | 71 | 基本思路和类的适配器模式相同,只是将 Adapter 类作修改,不是继承 src 类,而是持有 src 类的实例,以解决兼容性的问题。 即:持有 src 类,实现 dst 类接口,完成 src -> dst 的适配。 72 | 73 | ```java 74 | public class ObjectVoltageAdapter implements IVoltage5V { 75 | private Voltage220V voltage220V; 76 | 77 | public ObjectVoltageAdapter(Voltage220V voltage220){ 78 | this.voltage220V = voltage220; 79 | } 80 | 81 | @Override 82 | public int output5V() { 83 | int output220V = voltage220V.output220V(); 84 | //转换成 5v 85 | return output220V / 44; 86 | } 87 | } 88 | 89 | ``` 90 | 91 | 1. 对象适配器和类适配器其实算是同一种思想,只不过实现方式不同。 92 | 93 | 2. 根据合成复用原则,使用组合替代继承, 所以它解决了类适配器必须继承 src 的局限性问题,也不再要求 dst必须是接口。 94 | 95 | 3. 使用成本更低,更灵活。 96 | 97 | ## 5 接口适配器模式 98 | 99 | 当不需要全部实现接口提供的方法时,可先设计一个抽象类实现接口,并为该接口中每个方法提供一个默认实现(空方法),那么该抽象类的子类可有选择地覆盖父类的某些方法来实现需求,适用于一个接口不想使用其所有的方法的情况。 -------------------------------------------------------------------------------- /设计模式/010.结构型模式_装饰者模式.md: -------------------------------------------------------------------------------- 1 | ## 1 概述 2 | 3 | 在不改变现有对象结构的情况下,动态地给该对象增加一些职责(即**增加其额外功能**)的模式。 4 | 5 | 装饰(Decorator)模式中的角色: 6 | 7 | - 抽象构件(Component)角色 :定义一个抽象接口以规范准备接收附加责任的对象。 8 | - 具体构件(Concrete Component)角色 :实现抽象构件,通过装饰角色为其添加一些职责。 9 | - 抽象装饰(Decorator)角色 : 继承或实现抽象构件,并包含具体构件的实例,可以通过其子类扩展具体构件的功能。 10 | - 具体装饰(ConcreteDecorator)角色 :实现抽象装饰的相关方法,并给具体构件对象添加附加的责任。 11 | 12 | ## 2 例子 13 | 14 | 快餐店有炒面、炒饭这些快餐,可以额外附加鸡蛋、火腿、培根这些配菜,加配菜需要额外加钱,最后结账也不同。 15 | 16 | ```java 17 | //快餐接口 18 | public abstract class FastFood { 19 | private float price; 20 | private String desc; 21 | 22 | public FastFood() {} 23 | 24 | public FastFood(float price, String desc) { 25 | this.price = price; 26 | this.desc = desc; 27 | } 28 | 29 | public void setPrice(float price) { 30 | this.price = price; 31 | } 32 | 33 | public float getPrice() { 34 | return price; 35 | } 36 | 37 | public String getDesc() { 38 | return desc; 39 | } 40 | 41 | public void setDesc(String desc) { 42 | this.desc = desc; 43 | } 44 | 45 | //获取价格 46 | public abstract float cost(); 47 | } 48 | 49 | //普通炒饭 50 | public class FriedRice extends FastFood { 51 | public FriedRice() { 52 | super(10, "炒饭"); 53 | } 54 | public float cost() { 55 | return getPrice(); 56 | } 57 | } 58 | 59 | //配料类 60 | public abstract class Garnish extends FastFood { 61 | private FastFood fastFood; 62 | 63 | public FastFood getFastFood() { 64 | return fastFood; 65 | } 66 | 67 | public void setFastFood(FastFood fastFood) { 68 | this.fastFood = fastFood; 69 | } 70 | 71 | public Garnish(FastFood fastFood, float price, String desc) { 72 | super(price,desc); 73 | this.fastFood = fastFood; 74 | } 75 | } 76 | 77 | //鸡蛋配料 78 | public class Egg extends Garnish { 79 | 80 | public Egg(FastFood fastFood) { 81 | super(fastFood,1,"鸡蛋"); 82 | } 83 | 84 | public float cost() { 85 | return getPrice() + getFastFood().getPrice(); 86 | } 87 | 88 | @Override 89 | public String getDesc() { 90 | return super.getDesc() + getFastFood().getDesc(); 91 | } 92 | } 93 | 94 | //测试类 95 | public class Client { 96 | public static void main(String[] args) { 97 | //点一份炒饭 98 | FastFood food = new FriedRice(); 99 | //花费的价格 100 | System.out.println(food.getDesc() + " " + food.cost() + "元"); 101 | 102 | System.out.println("========"); 103 | //点一份鸡蛋炒饭 104 | FastFood food1 = new FriedRice(); 105 | food1 = new Egg(food1); 106 | //花费的价格 107 | System.out.println(food1.getDesc() + " " + food1.cost() + "元"); 108 | } 109 | } 110 | ``` 111 | 112 | 优点: 113 | 114 | - 装饰者模式可以带来比继承更加灵活性的**扩展功能**,使用更加方便,可以通过组合不同的装饰者对象来获取具有不同行为状态的多样化的结果。 115 | - 装饰者模式比继承**更具良好的扩展性**,完美的遵循开闭原则,继承是静态的附加责任,装饰者则是动态的附加责任。 116 | - 装饰类和被装饰类可以独立发展,不会相互耦合,装饰模式是继承的一个替代模式,装饰模式可以动态扩展一个实现类的功能。 117 | 118 | ## 4 代理和装饰者的区别 119 | 120 | 静态代理和装饰者模式的区别: 121 | 122 | - 相同点: 123 | - 都要实现与目标类相同的业务接口 124 | - 在两个类中都要声明目标对象 125 | - 都可以在不修改目标类的前提下增强目标方法 126 | - 不同点: 127 | - 目的不同:装饰者是为了增强目标对象,静态代理是为了保护和隐藏目标对象; 128 | - 获取目标对象构建的地方不同:装饰者是由外界传递进来,可以通过构造方法传递,静态代理是在代理类内部创建,以此来隐藏目标对象 -------------------------------------------------------------------------------- /设计模式/011.结构型模式_桥接模式.md: -------------------------------------------------------------------------------- 1 | ## 1 概述 2 | 3 | 将**抽象与实现分离**,使它们可以独立变化。它是用组合关系代替继承关系来实现,从而降低了抽象和实现这两个可变维度的耦合度。 4 | 5 | 桥接(Bridge)模式包含以下主要角色: 6 | 7 | - 抽象化(Abstraction)角色 :定义抽象类,并包含一个对实现化对象的引用。 8 | - 扩展抽象化(Refined Abstraction)角色 :是抽象化角色的子类,实现父类中的业务方法,并通过组合关系调用实现化角色中的业务方法。 9 | - 实现化(Implementor)角色 :定义实现化角色的接口,供扩展抽象化角色调用。 10 | - 具体实现化(Concrete Implementor)角色 :给出实现化角色接口的具体实现。 11 | 12 | ## 2 例子 13 | 14 | 视频播放器 15 | 16 | 需要开发一个跨平台视频播放器,可以在不同操作系统平台(如Windows、Mac、Linux等)上播放多种格式的视频文件,常见的视频格式包括RMVB、AVI、WMV等。该播放器包含了两个维度,适合使用桥接模式。 17 | 18 | ```java 19 | /视频文件 20 | public interface VideoFile { 21 | void decode(String fileName); 22 | } 23 | 24 | //avi文件 25 | public class AVIFile implements VideoFile { 26 | public void decode(String fileName) { 27 | System.out.println("avi视频文件:"+ fileName); 28 | } 29 | } 30 | 31 | //rmvb文件 32 | public class REVBBFile implements VideoFile { 33 | 34 | public void decode(String fileName) { 35 | System.out.println("rmvb文件:" + fileName); 36 | } 37 | } 38 | 39 | //操作系统版本 40 | public abstract class OperatingSystemVersion { 41 | 42 | protected VideoFile videoFile; 43 | 44 | public OperatingSystemVersion(VideoFile videoFile) { 45 | this.videoFile = videoFile; 46 | } 47 | 48 | public abstract void play(String fileName); 49 | } 50 | 51 | //Windows版本 52 | public class Windows extends OperatingSystem { 53 | 54 | public Windows(VideoFile videoFile) { 55 | super(videoFile); 56 | } 57 | 58 | public void play(String fileName) { 59 | videoFile.decode(fileName); 60 | } 61 | } 62 | 63 | //mac版本 64 | public class Mac extends OperatingSystemVersion { 65 | 66 | public Mac(VideoFile videoFile) { 67 | super(videoFile); 68 | } 69 | 70 | public void play(String fileName) { 71 | videoFile.decode(fileName); 72 | } 73 | } 74 | 75 | //测试类 76 | public class Client { 77 | public static void main(String[] args) { 78 | OperatingSystem os = new Windows(new AVIFile()); 79 | os.play("战狼3"); 80 | } 81 | } 82 | ``` 83 | 84 | 优点: 85 | 86 | - 桥接模式提高了系统的可扩充性,在两个变化维度中任意扩展一个维度,都不需要修改原有系统。 87 | 88 | 如:如果现在还有一种视频文件类型wmv,我们只需要再定义一个类实现VideoFile接口即可,其他类不需要发生变化。 89 | 90 | - 实现细节对客户透明 91 | 92 | ## 3 使用场景 93 | 94 | - 当一个类存在**两个独立变化的维度**,且这两个维度都需要进行扩展时。 95 | - 当一个系统不希望使用继承或因为多层次继承导致系统类的个数急剧增加时。 96 | - 当一个系统需要在构件的抽象化角色和具体化角色之间增加更多的灵活性时。避免在两个层次之间建立静态的继承联系,通过桥接模式可以使它们在抽象层建立一个关联关系。 97 | 98 | 99 | 100 | -------------------------------------------------------------------------------- /设计模式/012.结构型模式_外观模式.md: -------------------------------------------------------------------------------- 1 | ## 1 概述 2 | 3 | 又叫门面模式,是一种通过为多个复杂的子系统提供一个一致的接口,而使这些子系统更加容易被访问的模式。该模式**对外有一个统一接口**,外部应用程序不用关心内部子系统的具体的细节,这样会大大降低应用程序的复杂度,提高了程序的可维护性。 4 | 5 | 外观(Facade)模式包含以下主要角色: 6 | 7 | - 外观(Facade)角色:为多个子系统对外提供一个共同的接口。 8 | - 子系统(Sub System)角色:实现系统的部分功能,客户可以通过外观角色访问它。 9 | 10 | ## 2 例子 11 | 12 | 启动一台电脑,电脑内部,包括 CPU 启动、硬盘启动、内存启动等,但是我们无需关心这些细节,电脑自提供一个开机的方法。 13 | 14 | ```java 15 | //电脑接口 16 | public interface Computer { 17 | void open(); 18 | } 19 | 20 | //CPU 21 | public class Cpu implements Computer { 22 | @Override 23 | public void open() { 24 | System.out.println("启动CPU"); 25 | } 26 | } 27 | 28 | //硬盘 29 | public class Ssd implements Computer { 30 | @Override 31 | public void open() { 32 | System.out.println("启动硬盘"); 33 | } 34 | } 35 | 36 | //内存 37 | public class Ddr implements Computer { 38 | @Override 39 | public void open() { 40 | System.out.println("启动内存"); 41 | } 42 | } 43 | 44 | //外观类 45 | public class Facade { 46 | private Computer cpu; 47 | private Computer ddr; 48 | private Computer ssd; 49 | public Facade() { 50 | cpu = new Cpu(); 51 | ddr = new Ddr(); 52 | ssd = new Ssd(); 53 | } 54 | 55 | public void open() { 56 | cpu.open(); 57 | ddr.open(); 58 | ssd = new Ssd(); 59 | } 60 | } 61 | 62 | public class TestClient { 63 | public static void main(String[] args) { 64 | //创建外观对象 65 | Facade facade = new Facade(); 66 | //客户端直接与外观对象进行交互 67 | facade.open(); 68 | } 69 | } 70 | ``` 71 | 72 | ## 3 优缺点 73 | 74 | 优点: 75 | 76 | - 降低了子系统与客户端之间的**耦合度**,使得子系统的变化不会影响调用它的客户类。 77 | - 对客户屏蔽了子系统组件,减少了客户处理的对象数目,并使得子系统使用起来更加容易。 78 | 79 | 缺点: 80 | 81 | - 不符合开闭原则,修改很麻烦。 -------------------------------------------------------------------------------- /设计模式/013.结构型模式_享元模式.md: -------------------------------------------------------------------------------- 1 | ## 1 概述 2 | 3 | 运用**共享技术(共享对象)**来有效地支持大量细粒度对象的复用。它通过共享已经存在的对象来大幅度减少需要创建的对象数量、避免大量相似对象的开销,从而提高系统资源的利用率。 4 | 5 | 享元(Flyweight )模式中存在以下两种状态: 6 | 7 | 1. 内部状态,即不会随着环境的改变而改变的可共享部分。 8 | 2. 外部状态,指随环境改变而改变的不可以共享的部分。享元模式的实现要领就是区分应用中的这两种状态,并将外部状态外部化。 9 | 10 | 享元模式的主要有以下角色: 11 | 12 | - 抽象享元角色(Flyweight):通常是一个接口或抽象类,在抽象享元类中声明了具体享元类公共的方法,这些方法可以向外界提供享元对象的内部数据(内部状态),同时也可以通过这些方法来设置外部数据(外部状态)。 13 | - 具体享元(Concrete Flyweight)角色 :它实现了抽象享元类,称为享元对象;在具体享元类中为内部状态提供了存储空间。通常我们可以结合单例模式来设计具体享元类,为每一个具体享元类提供唯一的享元对象。 14 | - 非享元(Unsharable Flyweight)角色 :并不是所有的抽象享元类的子类都需要被共享,不能被共享的子类可设计为非共享具体享元类;当需要一个非共享具体享元类的对象时可以直接通过实例化创建。 15 | - 享元工厂(Flyweight Factory)角色 :负责创建和管理享元角色。当客户对象请求一个享元对象时,享元工厂检査系统中是否存在符合要求的享元对象,如果存在则提供给客户;如果不存在的话,则创建一个新的享元对象。 16 | 17 | ## 2 例子 18 | 19 | 俄罗斯方块有不同的形状,每个不同的方块都是一个实例对象。 20 | 21 | ```java 22 | public abstract class AbstractBox { 23 | public abstract String getShape(); 24 | 25 | public void display(String color) { 26 | System.out.println("方块形状:" + this.getShape() + " 颜色:" + color); 27 | } 28 | } 29 | 30 | 31 | public class IBox extends AbstractBox { 32 | 33 | @Override 34 | public String getShape() { 35 | return "I"; 36 | } 37 | } 38 | 39 | public class LBox extends AbstractBox { 40 | 41 | @Override 42 | public String getShape() { 43 | return "L"; 44 | } 45 | } 46 | 47 | public class OBox extends AbstractBox { 48 | 49 | @Override 50 | public String getShape() { 51 | return "O"; 52 | } 53 | } 54 | 55 | //创建一个工厂类 56 | public class BoxFactory { 57 | private static HashMap<> map; 58 | 59 | private BoxFactory() { 60 | map = new HashMap(); 61 | AbstractBox iBox = new IBox(); 62 | AbstractBox lBox = new LBox(); 63 | AbstractBox oBox = new OBox(); 64 | map.put("I", iBox); 65 | map.put("L", lBox); 66 | map.put("O", oBox); 67 | } 68 | 69 | public static final BoxFactory getInstance() { 70 | return SingletonHolder.INSTANCE; 71 | } 72 | 73 | private static class SingletonHolder { 74 | private static final BoxFactory INSTANCE = new BoxFactory(); 75 | } 76 | 77 | public AbstractBox getBox(String key) { 78 | return map.get(key); 79 | } 80 | } 81 | ``` 82 | 83 | ## 3 优缺点 84 | 85 | 优点: 86 | 87 | - 极大减少内存中相似或相同对象数量,节约系统资源,提供系统性能 88 | - 享元模式中的外部状态相对独立,且不影响内部状态 89 | 90 | 缺点: 91 | 92 | * 为了使对象可以共享,需要将享元对象的部分状态外部化,分离内部状态和外部状态,使程序逻辑复杂 -------------------------------------------------------------------------------- /设计模式/014.结构型模式_组合模式.md: -------------------------------------------------------------------------------- 1 | ## 1 概述 2 | 3 | 又称为**部分整体模式**,是用于把一组**相似**的对象当作一个单一的对象。组合模式依据树形结构来组合对象,用来表示部分以及整体层次。属于结构型模式,它创建了对象组的**树形结构**。 4 | 5 | 组合模式主要包含三种角色: 6 | 7 | - 抽象根节点(Component):定义系统各层次对象的共有方法和属性,可以预先定义一些默认行为和属性。 8 | - 树枝节点(Composite):定义树枝节点的行为,存储子节点,组合树枝节点和叶子节点形成一个树形结构。 9 | - 叶子节点(Leaf):叶子节点对象,其下再无分支,是系统层次遍历的最小单位。 10 | 11 | 分类: 12 | 13 | * 透明组合模式:抽象根节点角色中声明了所有用于管理成员对象的方法,add,remove 等。 14 | * 安全组合模式:抽象构件角色中没有声明任何用于管理成员对象的方法。 15 | 16 | ## 2 例子 17 | 18 | 一个公司组织架构,有许多员工,员工有上下级关系。 19 | 20 | ```java 21 | public class Employee { 22 | private String name; 23 | private List employees; 24 | 25 | public Employee(String name) { 26 | this.name = name; 27 | employees = new ArrayList<>(); 28 | } 29 | 30 | public String getName() { 31 | return name; 32 | } 33 | 34 | public void add(Employee employee) { 35 | employees.add(employee); 36 | } 37 | 38 | public void remove(Employee employee) { 39 | employees.remove(employee); 40 | } 41 | 42 | public void setName(String name) { 43 | this.name = name; 44 | } 45 | 46 | public List getEmployees() { 47 | return employees; 48 | } 49 | 50 | public void setEmployees(List employees) { 51 | this.employees = employees; 52 | } 53 | 54 | @Override 55 | public String toString() { 56 | return "Employee{" + 57 | "name='" + name + '\'' + 58 | ", employees=" + employees + 59 | '}'; 60 | } 61 | } 62 | 63 | public class TestClient { 64 | public static void main(String[] args) { 65 | final Employee a = new Employee("总裁"); 66 | final Employee b1 = new Employee("人事经理"); 67 | final Employee b2 = new Employee("财务经理"); 68 | 69 | final Employee c1 = new Employee("人事专员1"); 70 | final Employee c2 = new Employee("人事专员2"); 71 | 72 | 73 | a.add(b1); 74 | a.add(b2); 75 | 76 | b1.add(c1); 77 | b1.add(c2); 78 | 79 | System.out.println(a); 80 | for (Employee employee : a.getEmployees()) { 81 | System.out.println(employee); 82 | for (Employee sub : employee.getEmployees()) { 83 | System.out.println(sub); 84 | } 85 | } 86 | } 87 | } 88 | ``` 89 | 90 | ## 3 优缺点 91 | 92 | - 组合模式可以清楚地定义分层次的复杂对象,表示对象的全部或部分层次,它让客户端忽略了层次的差异,方便对整个层次结构进行控制。 93 | - 客户端可以一致地使用一个组合结构或其中单个对象,不必关心处理的是单个对象还是整个组合结构,简化了客户端代码。 94 | - 在组合模式中增加新的树枝节点和叶子节点都很方便,无须对现有类库进行任何修改,符合“开闭原则”。 95 | - 组合模式为树形结构的面向对象实现提供了一种灵活的解决方案,通过叶子节点和树枝节点的递归组合,可以形成复杂的树形结构,但对树形结构的控制却非常简单。 -------------------------------------------------------------------------------- /设计模式/015.结构型模式_桥接模式.md: -------------------------------------------------------------------------------- 1 | ## 1 概述 2 | 3 | **将抽象与实现分离**,使它们可以独立变化。它是用组合关系代替继承关系来实现,从而降低了抽象和实现这两个可变维度的耦合度。 4 | 5 | 桥接(Bridge)模式包含以下主要角色: 6 | 7 | * 抽象化(Abstraction)角色 :定义抽象类,并包含一个对实现化对象的引用。 8 | * 扩展抽象化(Refined Abstraction)角色 :是抽象化角色的子类,实现父类中的业务方法,并通过组合关系调用实现化角色中的业务方法。 9 | * 实现化(Implementor)角色 :定义实现化角色的接口,供扩展抽象化角色调用。 10 | * 具体实现化(Concrete Implementor)角色 :给出实现化角色接口的具体实现。 11 | 12 | ## 2 例子 13 | 14 | 需要开发一个跨平台视频播放器,可以在不同操作系统平台(如Windows、Mac、Linux等)上播放多种格式的视频文件,常见的视频格式包括RMVB、AVI、WMV等。该播放器包含了两个维度,适合使用桥接模式。 15 | 16 | 类图如下: 17 | 18 | ```java 19 | //视频文件 20 | public interface VideoFile { 21 | void decode(String fileName); 22 | } 23 | 24 | //avi文件 25 | public class AVIFile implements VideoFile { 26 | public void decode(String fileName) { 27 | System.out.println("avi视频文件:"+ fileName); 28 | } 29 | } 30 | 31 | //rmvb文件 32 | public class REVBBFile implements VideoFile { 33 | public void decode(String fileName) { 34 | System.out.println("rmvb文件:" + fileName); 35 | } 36 | } 37 | 38 | //操作系统版本 39 | public abstract class OperatingSystemVersion { 40 | protected VideoFile videoFile; 41 | 42 | public OperatingSystemVersion(VideoFile videoFile) { 43 | this.videoFile = videoFile; 44 | } 45 | public abstract void play(String fileName); 46 | } 47 | 48 | //Windows版本 49 | public class Windows extends OperatingSystem { 50 | public Windows(VideoFile videoFile) { 51 | super(videoFile); 52 | } 53 | 54 | public void play(String fileName) { 55 | videoFile.decode(fileName); 56 | } 57 | } 58 | 59 | //mac版本 60 | public class Mac extends OperatingSystemVersion { 61 | public Mac(VideoFile videoFile) { 62 | super(videoFile); 63 | } 64 | 65 | public void play(String fileName) { 66 | videoFile.decode(fileName); 67 | } 68 | } 69 | 70 | //测试类 71 | public class TestClient { 72 | public static void main(String[] args) { 73 | OperatingSystem os = new Windows(new AVIFile()); 74 | os.play("战狼3"); 75 | } 76 | } 77 | ``` 78 | 79 | ## 3 优缺点 80 | 81 | - 桥接模式提高了系统的可扩充性,在两个变化维度中任意扩展一个维度,都不需要修改原有系统。 82 | 83 | 如:如果现在还有一种视频文件类型 wmv,我们只需要再定义一个类实现VideoFile接口即可,其他类不需要发生变化。 84 | 85 | - 实现细节对客户透明 86 | 87 | - 一个类存在两个独立变化的维度,且这两个维度都需要进行扩展时,适合使用桥接模式。 88 | 89 | -------------------------------------------------------------------------------- /设计模式/016.行为型模式_模板模式.md: -------------------------------------------------------------------------------- 1 | ## 1 概述 2 | 3 | 定义一个操作中的算法骨架,而将算法的一些步骤延迟到子类中,使得子类可以不改变该算法结构的情况下重定义该算法的某些特定步骤。 4 | 5 | 模板方法(Template Method)模式包含以下主要角色: 6 | 7 | - 抽象类(Abstract Class):负责给出一个算法的轮廓和骨架。它由一个模板方法和若干个基本方法构成。 8 | 9 | - 模板方法:定义了算法的骨架,按某种顺序调用其包含的基本方法。 10 | 11 | - 基本方法:是实现算法各个步骤的方法,是模板方法的组成部分。基本方法又可以分为三种: 12 | 13 | - 抽象方法(Abstract Method) :一个抽象方法由抽象类声明、由其具体子类实现。 14 | 15 | - 具体方法(Concrete Method) :一个具体方法由一个抽象类或具体类声明并实现,其子类可以进行覆盖也可以直接继承。 16 | 17 | - 钩子方法(Hook Method) :在抽象类中已经实现,包括用于判断的逻辑方法和需要子类重写的空方法两种。 18 | 19 | 一般钩子方法是用于判断的逻辑方法,这类方法名一般为 isXxx,返回值类型为boolean类型。 20 | 21 | - 具体子类(Concrete Class):实现抽象类中所定义的抽象方法和钩子方法,它们是一个顶级逻辑的组成步骤。 22 | 23 | ## 2 例子 24 | 25 | 打游戏有一般先初始化游戏、开始游戏、结束游戏。 26 | 27 | ```java 28 | public abstract class Game { 29 | public abstract void initialize(); 30 | 31 | public abstract void startPlay(); 32 | 33 | public abstract void endPlay(); 34 | 35 | //模板 36 | public final void play() { 37 | //初始化游戏 38 | initialize(); 39 | //开始游戏 40 | startPlay(); 41 | //结束游戏 42 | endPlay(); 43 | } 44 | } 45 | 46 | public class Honor extends Game { 47 | 48 | @Override 49 | void endPlay() { 50 | System.out.println("王者荣耀结束"); 51 | } 52 | 53 | @Override 54 | void initialize() { 55 | System.out.println("王者荣耀初始化"); 56 | } 57 | 58 | @Override 59 | void startPlay() { 60 | System.out.println("王者荣耀开始"); 61 | } 62 | } 63 | 64 | public class TestClient { 65 | public static void main(String[] args) { 66 | final Honor honor = new Honor(); 67 | honor.play(); 68 | } 69 | } 70 | ``` 71 | 72 | ## 3 优缺点 73 | 74 | 优点 75 | 76 | - 提高代码复用性 77 | 78 | 将相同部分的代码放在抽象的父类中,而将不同的代码放入不同的子类中。 79 | 80 | - 实现了反向控制 81 | 82 | 通过一个父类调用其子类的操作,通过对子类的具体实现扩展不同的行为,实现了反向控制 ,并符合“开闭原则”。 83 | 84 | 缺点 85 | 86 | - 对每个不同的实现都需要定义一个子类,这会导致类的个数增加,系统更加庞大,设计也更加抽象。 87 | - 父类中的抽象方法由子类实现,子类执行的结果会影响父类的结果,这导致一种反向的控制结构,它提高了代码阅读的难度。 -------------------------------------------------------------------------------- /设计模式/017.行为型模式_策略模式.md: -------------------------------------------------------------------------------- 1 | ## 1 概述 2 | 3 | 该模式**定义了一系列算法**,并将每个算法封装起来,使它们可以相互替换,且算法的变化不会影响使用算法的客户。属于对象行为模式,它通过对算法进行封装,把使用算法的责任和算法的实现分割开来,并委派给不同的对象对这些算法进行管理。 4 | 5 | 策略模式的主要角色如下: 6 | 7 | - 抽象策略(Strategy)类:这是一个抽象角色,通常由一个接口或抽象类实现。此角色给出所有的具体策略类所需的接口。 8 | - 具体策略(Concrete Strategy)类:实现了抽象策略定义的接口,提供具体的算法实现或行为。 9 | - 环境(Context)类:持有一个策略类的引用,最终给客户端调用。 10 | 11 | ## 2 例子 12 | 13 | 百货公司在定年度的促销活动。针对不同的节日(春节、中秋节、圣诞节)推出不同的促销活动,由促销员将促销活动展示给客户。 14 | 15 | ```java 16 | //抽象策略 17 | public interface Strategy { 18 | void show(); 19 | } 20 | 21 | //具体策略角色 22 | //为春节准备的促销活动A 23 | public class StrategyA implements Strategy { 24 | public void show() { 25 | System.out.println("买一送一"); 26 | } 27 | } 28 | 29 | //为中秋准备的促销活动B 30 | public class StrategyB implements Strategy { 31 | public void show() { 32 | System.out.println("满200元减50元"); 33 | } 34 | } 35 | 36 | //为圣诞准备的促销活动C 37 | public class StrategyC implements Strategy { 38 | public void show() { 39 | System.out.println("满1000元加一元换购任意200元以下商品"); 40 | } 41 | } 42 | 43 | //环境角色(Context) 44 | public class SalesMan { 45 | //抽象策略角色的引用 46 | private Strategy strategy; 47 | 48 | public SalesMan(Strategy strategy) { 49 | this.strategy = strategy; 50 | } 51 | 52 | //向客户展示促销活动 53 | public void salesManShow(){ 54 | strategy.show(); 55 | } 56 | } 57 | ``` 58 | 59 | ## 3 优缺点 60 | 61 | 优点: 62 | 63 | - 策略类之间可以自由切换 64 | 65 | 由于策略类都实现同一个接口,所以使它们之间可以自由切换。 66 | 67 | - 易于扩展 68 | 69 | 增加一个新的策略只需要添加一个具体的策略类即可,基本不需要改变原有的代码,符合“开闭原则“ 70 | 71 | - 避免使用多重条件选择语句(if else),充分体现面向对象设计思想。 72 | 73 | 缺点: 74 | 75 | - 客户端必须知道所有的策略类,并自行决定使用哪一个策略类。 76 | - 策略模式将造成产生很多策略类,可以通过使用享元模式在一定程度上减少对象的数量。 77 | 78 | -------------------------------------------------------------------------------- /设计模式/018.行为型模式_命令模式.md: -------------------------------------------------------------------------------- 1 | ## 1 概述 2 | 3 | 将一个请求封装为一个对象,使发出请求的责任和执行请求的责任分割开。这样两者之间通过命令对象进行沟通,这样方便将命令对象进行存储、传递、调用、增加与管理。 4 | 5 | 命令模式包含以下主要角色: 6 | 7 | - 抽象命令类(Command)角色: 定义命令的接口,声明执行的方法。 8 | - 具体命令(Concrete Command)角色:具体的命令,实现命令接口;通常会持有接收者,并调用接收者的功能来完成命令要执行的操作。 9 | - 实现者/接收者(Receiver)角色: 接收者,真正执行命令的对象。任何类都可能成为一个接收者,只要它能够实现命令要求实现的相应功能。 10 | - 调用者/请求者(Invoker)角色: 要求命令对象执行请求,通常会持有命令对象,可以持有很多的命令对象。这个是客户端真正触发命令并要求命令执行相应操作的地方,也就是说相当于使用命令对象的入口。 11 | 12 | ## 2 例子 13 | 14 | ```java 15 | //接收者:真正执行命令的对象 16 | public class Receiver { 17 | public void action(){ 18 | System.out.println("命令执行了......."); 19 | } 20 | } 21 | 22 | //抽象命令类:抽象的命令,可以根据不同类型的命令写出不同的实现 23 | public interface ICommand { 24 | //调用命令 25 | void execute(); 26 | } 27 | 28 | //具体命令类 29 | class ConcreteCommand implements ICommand{ 30 | private Receiver receiver;//持有真正执行命令对象的引用 31 | public ConcreteCommand(Receiver receiver) { 32 | super(); 33 | this.receiver = receiver; 34 | } 35 | @Override 36 | public void execute() { 37 | //调用接收者执行命令的方法 38 | receiver.action(); 39 | } 40 | } 41 | 42 | //请求者/调用者:发起执行命令请求的对象 43 | public class Invoker { 44 | private ICommand command;//持有命令对象的引用 45 | 46 | public Invoker(ICommand command) { 47 | super(); 48 | this.command = command; 49 | } 50 | 51 | public void call() { 52 | //请求者调用命令对象执行命令的那个execute方法 53 | command.execute(); 54 | } 55 | } 56 | 57 | public class TestClient { 58 | public static void main(String[] args) { 59 | //通过请求者(invoker)调用命令对象(command),命令对象中调用了命令具体执行者(Receiver) 60 | ICommand command = new ConcreteCommand(new Receiver()); 61 | Invoker invoker = new Invoker(command); 62 | invoker.call(); 63 | } 64 | } 65 | ``` 66 | 67 | ## 3 优缺点 68 | 69 | 优点: 70 | 71 | - 降低系统的耦合度。命令模式能将调用操作的对象与实现该操作的对象解耦。 72 | - 增加或删除命令非常方便。采用命令模式增加与删除命令不会影响其他类,它满足“开闭原则”,对扩展比较灵活。 73 | - 可以实现宏命令。命令模式可以与组合模式结合,将多个命令装配成一个组合命令,即宏命令。 74 | - 方便实现 Undo 和 Redo 操作。命令模式可以与后面介绍的备忘录模式结合,实现命令的撤销与恢复。 75 | 76 | 缺点: 77 | 78 | - 使用命令模式可能会导致某些系统有过多的具体命令类。 79 | - 系统结构更加复杂。 -------------------------------------------------------------------------------- /设计模式/021.行为型模式_观察者模式.md: -------------------------------------------------------------------------------- 1 | ## 1 概述 2 | 3 | 又被称为**发布-订阅**(Publish/Subscribe)模式,它定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态变化时,会通知所有的观察者对象,使他们能够自动更新自己。 4 | 5 | 在观察者模式中有如下角色: 6 | 7 | - Subject:抽象主题(抽象被观察者),抽象主题角色把所有观察者对象保存在一个集合里,每个主题都可以有任意数量的观察者,抽象主题提供一个接口,可以增加和删除观察者对象。 8 | - ConcreteSubject:具体主题(具体被观察者),该角色将有关状态存入具体观察者对象,在具体主题的内部状态发生改变时,给所有注册过的观察者发送通知。 9 | - Observer:抽象观察者,是观察者的抽象类,它定义了一个更新接口,使得在得到主题更改通知时更新自己。 10 | - ConcrereObserver:具体观察者,实现抽象观察者定义的更新接口,以便在得到主题更改通知时更新自身的状态。 11 | 12 | ## 2 例子 13 | 14 | 订阅新闻,新闻有更新,订阅者就会收到通知。 15 | 16 | ```java 17 | //观察者 18 | public interface Observer { 19 | void update(String msg); 20 | } 21 | //具体观察者 22 | public class User implements Observer { 23 | private String name; 24 | 25 | public User(String name) { 26 | this.name = name; 27 | } 28 | 29 | @Override 30 | public void update(String msg) { 31 | System.out.println("尊敬的" + name + ":" + msg); 32 | } 33 | } 34 | 35 | //抽象被观察者 36 | public interface Subject { 37 | //增加订阅者 38 | void attach(Observer observer); 39 | 40 | //删除订阅者 41 | void detach(Observer observer); 42 | 43 | //通知订阅者更新消息 44 | void notify(String message); 45 | } 46 | 47 | //具体被观察者 48 | public class SubscriptionSubject implements Subject { 49 | 50 | private List users = new ArrayList<>(); 51 | 52 | @Override 53 | public void attach(Observer observer) { 54 | users.add(observer); 55 | } 56 | 57 | @Override 58 | public void detach(Observer observer) { 59 | users.remove(observer); 60 | } 61 | 62 | @Override 63 | public void notify(String message) { 64 | //通知给订阅者 65 | for (Observer observer : users) { 66 | observer.update(message); 67 | } 68 | } 69 | } 70 | 71 | //客户端 72 | public class TestClient { 73 | public static void main(String[] args) { 74 | final User aa = new User("AA"); 75 | final User bb = new User("BB"); 76 | 77 | final SubscriptionSubject subscriptionSubject = new SubscriptionSubject(); 78 | subscriptionSubject.attach(aa); 79 | subscriptionSubject.attach(bb); 80 | 81 | subscriptionSubject.notify("订阅更新了"); 82 | } 83 | } 84 | 85 | ``` 86 | 87 | ## 3 优缺点 88 | 89 | 优点: 90 | 91 | - 降低了目标与观察者之间的耦合关系,两者之间是抽象耦合关系。 92 | - 被观察者发送通知,所有注册的观察者都会收到信息 - 可以实现广播机制 93 | 94 | 缺点: 95 | 96 | - 如果观察者非常多的话,那么所有的观察者收到被观察者发送的通知会耗时 97 | - 如果被观察者有循环依赖的话,那么被观察者发送通知会使观察者循环调用,会导致系统崩溃 -------------------------------------------------------------------------------- /设计模式/023.行为型模式_迭代器模式.md: -------------------------------------------------------------------------------- 1 | ## 1 概述 2 | 3 | 提供一个对象来顺序访问聚合对象中的一系列数据,而不暴露聚合对象的内部表示。 4 | 5 | 迭代器模式主要包含以下角色: 6 | 7 | - 抽象聚合(Aggregate)角色:定义存储、添加、删除聚合元素以及创建迭代器对象的接口。 8 | - 具体聚合(ConcreteAggregate)角色:实现抽象聚合类,返回一个具体迭代器的实例。 9 | - 抽象迭代器(Iterator)角色:定义访问和遍历聚合元素的接口,通常包含 hasNext()、next() 等方法。 10 | - 具体迭代器(Concretelterator)角色:实现抽象迭代器接口中所定义的方法,完成对聚合对象的遍历,记录遍历的当前位置。 11 | 12 | ## 2 例子 13 | 14 | 定义一个可以存储学生对象的容器对象,将遍历该容器的功能交由迭代器实现。 15 | 16 | ```java 17 | public class Student { 18 | private String name; 19 | 20 | public Student(String name) { 21 | this.name = name; 22 | } 23 | 24 | public String getName() { 25 | return name; 26 | } 27 | 28 | public void setName(String name) { 29 | this.name = name; 30 | } 31 | 32 | @Override 33 | public String toString() { 34 | return "Student{" + 35 | "name='" + name + '\'' + 36 | '}'; 37 | } 38 | } 39 | 40 | //迭代器接口 41 | public interface StudentIterator { 42 | boolean hasNext(); 43 | 44 | Student next(); 45 | } 46 | 47 | //具体的迭代器类 48 | public class StudentIteratorImpl implements StudentIterator { 49 | private List list; 50 | private int position = 0; 51 | 52 | public StudentIteratorImpl(List list) { 53 | this.list = list; 54 | } 55 | 56 | @Override 57 | public boolean hasNext() { 58 | return position < list.size(); 59 | } 60 | 61 | @Override 62 | public Student next() { 63 | Student currentStudent = list.get(position); 64 | position++; 65 | return currentStudent; 66 | } 67 | } 68 | 69 | //定义抽象容器类,包含添加元素,删除元素,获取迭代器对象的方法 70 | public interface StudentAggregate { 71 | void addStudent(Student student); 72 | 73 | void removeStudent(Student student); 74 | 75 | StudentIterator getStudentIterator(); 76 | } 77 | 78 | //具体的容器类 79 | public class StudentAggregateImpl implements StudentAggregate { 80 | private List list = new ArrayList<>(); // 学生列表 81 | 82 | @Override 83 | public void addStudent(Student student) { 84 | this.list.add(student); 85 | } 86 | 87 | @Override 88 | public void removeStudent(Student student) { 89 | this.list.remove(student); 90 | } 91 | 92 | @Override 93 | public StudentIterator getStudentIterator() { 94 | return new StudentIteratorImpl(list); 95 | } 96 | } 97 | 98 | public class TestClient { 99 | public static void main(String[] args) { 100 | final StudentAggregateImpl aggregate = new StudentAggregateImpl(); 101 | aggregate.addStudent(new Student("AA")); 102 | aggregate.addStudent(new Student("BB")); 103 | 104 | final StudentIterator iterator = aggregate.getStudentIterator(); 105 | while (iterator.hasNext()) { 106 | System.out.println(iterator.next().toString()); 107 | } 108 | } 109 | } 110 | ``` 111 | 112 | ## 3 优缺点 113 | 114 | 优点: 115 | 116 | * 它支持以不同的方式**遍历一个聚合对象**。 117 | * 迭代器简化了聚合类。 118 | * 在同一个聚合上可以有多个遍历。 119 | * 在迭代器模式中,增加新的聚合类和迭代器类都很方便,无须修改原有代码。 120 | 121 | 缺点: 122 | 123 | * 由于迭代器模式将存储数据和遍历数据的职责分离,增加新的聚合类需要对应增加新的迭代器类,类的个数成对增加,这在一定程度上增加了系统的复杂性。 -------------------------------------------------------------------------------- /设计模式/024.行为型模式_访问者模式.md: -------------------------------------------------------------------------------- 1 | ## 1 概述 2 | 3 | 封装一些作用于某种数据结构中的各元素的操作,它可以在不改变这个数据结构的前提下定义作用于这些元素的新的操作,主要将**数据结构与数据操作分离**。 4 | 5 | 访问者模式包含以下主要角色: 6 | 7 | - 抽象访问者(Visitor)角色:定义了对每一个元素`(Element)`访问的行为,它的参数就是可以访问的元素,它的方法个数理论上来讲与元素类个数(Element的实现类个数)是一样的,从这点不难看出,访问者模式要求元素类的个数不能改变。 8 | - 具体访问者(ConcreteVisitor)角色:给出对每一个元素类访问时所产生的具体行为。 9 | - 抽象元素(Element)角色:定义了一个接受访问者的方法(`accept`),其意义是指,每一个元素都要可以被访问者访问。 10 | - 具体元素(ConcreteElement)角色: 提供接受访问方法的具体实现,而这个具体的实现,通常情况下是使用访问者提供的访问该元素类的方法。 11 | - 对象结构(Object Structure)角色:定义当中所提到的对象结构,对象结构是一个抽象表述,具体点可以理解为一个具有容器性质或者复合对象特性的类,它会含有一组元素(`Element`),并且可以迭代这些元素,供访问者访问。 12 | 13 | ## 2 例子 14 | 15 | 给宠物喂食,主人可以喂,其他人也可以喂。 16 | 17 | - 访问者角色:给宠物喂食的人 18 | - 具体访问者角色:主人、其他人 19 | - 抽象元素角色:动物抽象类 20 | - 具体元素角色:宠物狗、宠物猫 21 | - 结构对象角色:主人家 22 | 23 | ```java 24 | //创建抽象访问者接口 25 | public interface Person { 26 | void feed(Cat cat); 27 | void feed(Dog dog); 28 | } 29 | 30 | //创建不同的具体访问者角色(主人和其他人),都需要实现 Person接口 31 | public class Owner implements Person { 32 | 33 | @Override 34 | public void feed(Cat cat) { 35 | System.out.println("主人喂食猫"); 36 | } 37 | 38 | @Override 39 | public void feed(Dog dog) { 40 | System.out.println("主人喂食狗"); 41 | } 42 | } 43 | 44 | public class Someone implements Person { 45 | @Override 46 | public void feed(Cat cat) { 47 | System.out.println("其他人喂食猫"); 48 | } 49 | 50 | @Override 51 | public void feed(Dog dog) { 52 | System.out.println("其他人喂食狗"); 53 | } 54 | } 55 | 56 | //定义抽象节点 -- 宠物 57 | public interface Animal { 58 | void accept(Person person); 59 | } 60 | 61 | //定义实现Animal接口的 具体节点(元素) 62 | public class Dog implements Animal { 63 | 64 | @Override 65 | public void accept(Person person) { 66 | person.feed(this); 67 | System.out.println("好好吃,汪汪汪!!!"); 68 | } 69 | } 70 | 71 | public class Cat implements Animal { 72 | 73 | @Override 74 | public void accept(Person person) { 75 | person.feed(this); 76 | System.out.println("好好吃,喵喵喵!!!"); 77 | } 78 | } 79 | 80 | public class Home { 81 | private List nodeList = new ArrayList(); 82 | public void action(Person person) { 83 | for (Animal node : nodeList) { 84 | node.accept(person); 85 | } 86 | } 87 | //添加操作 88 | public void add(Animal animal) { 89 | nodeList.add(animal); 90 | } 91 | } 92 | 93 | public class TestClient { 94 | public static void main(String[] args) { 95 | Home home = new Home(); 96 | home.add(new Dog()); 97 | home.add(new Cat()); 98 | Owner owner = new Owner(); 99 | home.action(owner); 100 | Someone someone = new Someone(); 101 | home.action(someone); 102 | } 103 | } 104 | ``` 105 | 106 | 107 | 108 | ## 3 优缺点 109 | 110 | 优点: 111 | 112 | - 符合单一职责原则 113 | - 优秀的扩展性 114 | - 灵活性非常高 115 | 116 | 缺点: 117 | 118 | - 具体元素对访问者公布细节,也就是说访问者关注了其他类的内部细节,这是迪米特法则所不建议的 119 | - 具体元素变更比较困难 120 | - 违背了依赖倒转原则。访问者依赖的是具体元素,而不是抽象元素 -------------------------------------------------------------------------------- /设计模式/025.行为型模式_备忘录模式.md: -------------------------------------------------------------------------------- 1 | ## 1 概念 2 | 3 | 又叫**快照模式**,在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,以便以后当需要时能将该对象恢复到原先保存的状态。 4 | 5 | 备忘录模式的主要角色如下: 6 | 7 | - 发起人(Originator)角色:记录当前时刻的内部状态信息,提供创建备忘录和恢复备忘录数据的功能,实现其他业务功能,它可以访问备忘录里的所有信息。 8 | - 备忘录(Memento)角色:负责存储发起人的内部状态,在需要的时候提供这些内部状态给发起人。 9 | - 管理者(Caretaker)角色:对备忘录进行管理,提供保存与获取备忘录的功能,但其不能对备忘录的内容进行访问与修改。 10 | 11 | ## 2 例子 12 | 13 | 游戏存档。 14 | 15 | ```java 16 | //游戏 17 | public class GameRate { 18 | private int rate; //当前进度 19 | 20 | public int getRate() { 21 | return rate; 22 | } 23 | 24 | public void setRate(int rate) { 25 | this.rate = rate; 26 | } 27 | 28 | //保存进度 29 | public GameRateMemento save() { 30 | return new GameRateMemento(rate); 31 | } 32 | 33 | //恢复进度 34 | public void recoverState(GameRateMemento gameRateMemento) { 35 | this.rate = gameRateMemento.getRate(); 36 | } 37 | 38 | @Override 39 | public String toString() { 40 | return "GameRate{" + 41 | "rate=" + rate + 42 | '}'; 43 | } 44 | } 45 | 46 | //游戏进度存储类(备忘录类) 47 | public class GameRateMemento { 48 | private int rate; //进度 49 | 50 | public int getRate() { 51 | return rate; 52 | } 53 | 54 | public void setRate(int rate) { 55 | this.rate = rate; 56 | } 57 | 58 | public GameRateMemento(int rate) { 59 | this.rate = rate; 60 | } 61 | } 62 | 63 | //角色状态管理者类 64 | public class GameRateCaretaker { 65 | private GameRateMemento gameRateMemento; 66 | 67 | public GameRateMemento getGameRateMemento() { 68 | return gameRateMemento; 69 | } 70 | 71 | public void setGameRateMemento(GameRateMemento gameRateMemento) { 72 | this.gameRateMemento = gameRateMemento; 73 | } 74 | } 75 | 76 | public class TestClient { 77 | public static void main(String[] args) { 78 | final GameRate gameRate = new GameRate(); 79 | gameRate.setRate(50);//当前进度 50 80 | System.out.println(gameRate); 81 | 82 | //保存游戏进度 83 | final GameRateCaretaker gameRateCaretaker = new GameRateCaretaker(); 84 | gameRateCaretaker.setGameRateMemento(gameRate.save()); 85 | 86 | gameRate.setRate(70);//进行到 70 87 | System.out.println(gameRate); 88 | 89 | //回档 90 | gameRate.recoverState(gameRateCaretaker.getGameRateMemento()); 91 | System.out.println(gameRate); 92 | 93 | } 94 | } 95 | ``` 96 | 97 | ## 3 优缺点 98 | 99 | 优点: 100 | 101 | * 给用户提供了一种可以恢复状态的机制,可以使用户能够比较方便地回到某个历史的状态。 * 102 | * 实现了信息的封装,使得用户不需要关心状态的保存细节。 103 | 104 | 缺点: 105 | 106 | * 消耗资源。如果类的成员变量过多,势必会占用比较大的资源,而且每一次保存都会消耗一定的内存。 -------------------------------------------------------------------------------- /设计模式/026.行为型模式_解释器模式.md: -------------------------------------------------------------------------------- 1 | ## 1 概述 2 | 3 | 提供了**评估语言的语法或表达式的方式**,它属于行为型模式。这种模式实现了一个表达式接口,该接口解释一个特定的上下文。这种模式被用在 SQL 解析、符号处理引擎等。 4 | 5 | 解释器模式包含以下主要角色。 6 | 7 | - 抽象表达式(Abstract Expression)角色:定义解释器的接口,约定解释器的解释操作,主要包含解释方法 interpret()。 8 | - 终结符表达式(Terminal Expression)角色:是抽象表达式的子类,用来实现文法中与终结符相关的操作,文法中的每一个终结符都有一个具体终结表达式与之相对应。 9 | - 非终结符表达式(Nonterminal Expression)角色:也是抽象表达式的子类,用来实现文法中与非终结符相关的操作,文法中的每条规则都对应于一个非终结符表达式。 10 | - 环境(Context)角色:通常包含各个解释器需要的数据或是公共的功能,一般用来传递被所有解释器共享的数据,后面的解释器可以从这里获取这些值。 11 | - 客户端(Client):主要任务是将需要分析的句子或表达式转换成使用解释器对象描述的抽象语法树,然后调用解释器的解释方法,当然也可以通过环境角色间接访问解释器的解释方法。 12 | 13 | ## 2 例子 14 | 15 | 计算器 16 | 17 | ```java 18 | //创建一个表达式接口。 19 | public interface Expression { 20 | int interpreter(Context context);//一定会有解释方法 21 | } 22 | 23 | //抽象非终结符表达式 24 | public abstract class NonTerminalExpression implements Expression{ 25 | Expression e1,e2; 26 | public NonTerminalExpression(Expression e1, Expression e2){ 27 | this.e1 = e1; 28 | this.e2 = e2; 29 | } 30 | } 31 | 32 | //减法表达式实现类 33 | public class MinusOperation extends NonTerminalExpression { 34 | 35 | public MinusOperation(Expression e1, Expression e2) { 36 | super(e1, e2); 37 | } 38 | 39 | //将两个表达式相减 40 | @Override 41 | public int interpreter(Context context) { 42 | return this.e1.interpreter(context) - this.e2.interpreter(context); 43 | } 44 | } 45 | 46 | public class PlusOperation extends NonTerminalExpression { 47 | 48 | public PlusOperation(Expression e1, Expression e2) { 49 | super(e1, e2); 50 | } 51 | 52 | //将两个表达式相加 53 | @Override 54 | public int interpreter(Context context) { 55 | return this.e1.interpreter(context) + this.e2.interpreter(context); 56 | } 57 | } 58 | 59 | 60 | //终结符表达式(终结符表达式) 61 | public class TerminalExpression implements Expression{ 62 | String variable; 63 | public TerminalExpression(String variable){ 64 | this.variable = variable; 65 | } 66 | @Override 67 | public int interpreter(Context context) { 68 | return context.lookup(this); 69 | } 70 | } 71 | 72 | //下文类 73 | public class Context { 74 | private Map map = new HashMap<>(); 75 | //定义变量 76 | public void add(Expression s, Integer value){ 77 | map.put(s, value); 78 | } 79 | //将变量转换成数字 80 | public int lookup(Expression s){ 81 | return map.get(s); 82 | } 83 | } 84 | 85 | public class TestClient { 86 | public static void main(String[] args) { 87 | Context context = new Context(); 88 | TerminalExpression a = new TerminalExpression("a"); 89 | TerminalExpression b = new TerminalExpression("b"); 90 | TerminalExpression c = new TerminalExpression("c"); 91 | context.add(a, 4); 92 | context.add(b, 8); 93 | context.add(c, 2); 94 | System.out.println(new MinusOperation(new PlusOperation(a,b), c).interpreter(context)); 95 | } 96 | } 97 | ``` 98 | 99 | ## 3 优缺点 100 | 101 | 优点: 102 | 103 | * 可扩展性比较好,灵活。 104 | * 增加了新的解释表达式的方式。 105 | * 易于实现简单文法。 106 | 107 | 缺点: 108 | 109 | * 可利用场景比较少。 110 | * 对于复杂的文法比较难维护。 111 | * 解释器模式会引起类膨胀。 112 | * 解释器模式采用递归调用方法。 -------------------------------------------------------------------------------- /设计模式/027.模式对比.md: -------------------------------------------------------------------------------- 1 | ## 1 工厂方法模式 VS 建造者模式 2 | 3 | 工厂方法模式注重的是整体对象的创建方式;而建造者模式注重的是部件构建的过程,意在通过一步一步地精确构造创建出一个复杂的对象。 4 | 5 | 我们举个简单例子来说明两者的差异,如要制造一个超人,如果使用工厂方法模式,直接产生出来的就是一个力大无穷、能够飞翔、内裤外穿的超人;而如果使用建造者模式,则需要组装手、头、脚、躯干等部分,然后再把内裤外穿,于是一个超人就诞生了。 6 | 7 | ## 2 抽象工厂模式 VS 建造者模式 8 | 9 | 抽象工厂模式实现**对产品家族的创建,一个产品家族是这样的一系列产品**:具有不同分类维度的产品组合,采用抽象工厂模式则是不需要关心构建过程,只关心什么产品由什么工厂生产即可。 10 | 11 | 建造者模式则是要求按照指定的蓝图建造产品,它的主要目的是**通过组装零配件而产生一个新产品**。 12 | 13 | 如果将抽象工厂模式看成汽车配件生产工厂,生产一个产品族的产品,那么建造者模式就是一个汽车组装工厂,通过对部件的组装可以返回一辆完整的汽车。 14 | 15 | ## 3 三种代理的对比 16 | 17 | - jdk代理和CGLIB代理 18 | 19 | 使用CGLib实现动态代理,CGLib 底层采用 **ASM 字节码**生成框架,使用字节码技术生成代理类,在JDK1.6之前比使用Java反射效率要高。唯一需要注意的是,CGLib不能对声明为final的类或者方法进行代理,因为CGLib原理是动态生成被代理类的子类。 20 | 21 | 在JDK1.6、JDK1.7、JDK1.8逐步对JDK动态代理优化之后,在调用次数较少的情况下,JDK代理效率高于CGLib代理效率,只有当进行大量调用的时候,JDK1.6和JDK1.7比CGLib代理效率低一点,但是到JDK1.8的时候,JDK代理效率高于CGLib代理。所以如果有接口使用 JDK 动态代理,如果没有接口使用 CGLIB 代理。 22 | 23 | - 动态代理和静态代理 24 | 25 | 动态代理与静态代理相比较,最大的好处是接口中声明的所有方法都被转移到调用处理器一个集中的方法中处理(InvocationHandler.invoke)。这样,在接口方法数量比较多的时候,我们可以进行灵活处理,而不需要像静态代理那样每一个方法进行中转。 26 | 27 | 如果接口增加一个方法,静态代理模式除了所有实现类需要实现这个方法外,所有代理类也需要实现此方法。增加了代码维护的复杂度。而动态代理不会出现该问题 28 | 29 | ## 4 代理 VS 装饰者 30 | 31 | 静态代理和装饰者模式的区别: 32 | 33 | - 相同点: 34 | - 都要实现与目标类相同的业务接口 35 | - 在两个类中都要声明目标对象 36 | - 都可以在不修改目标类的前提下增强目标方法 37 | - 不同点: 38 | - 目的不同 装饰者是为了增强目标对象 静态代理是为了保护和隐藏目标对象 39 | - 获取目标对象构建的地方不同 装饰者是由外界传递进来,可以通过构造方法传递 静态代理是在代理类内部创建,以此来隐藏目标对 40 | 41 | ## 5 策略VS状态 42 | 43 | 策略模式:策略模式的客户端必须对所有的策略类相当了解,明确当前场景下各种策略的利弊,权衡在当前场景下应该使用哪种策略,也就是是说策略类对客户端是暴露的 44 | 45 | 状态模式:状态模式依赖于其状态的变化时其内部的行为发生变化,将动作委托到代表当前状态的对象,对外表现为类发生了变化。 46 | 47 | 策略模式是通过 Context 本身的决策来主动更替使用的strategy对象达到改变行为的目的,状态模式通过**状态转移**来被动的更改当前的State对象,状态的改变发生在运行时。 48 | 49 | 策略模式提前封装一组可以互相替代的算法族,根据需要动态的选择合适的一个来处理问题,而状态模式处理不同状态下, Context 对象行为不同的问题; 50 | 51 | ## 6 外观 VS 代理 VS 中介者 52 | 53 | **外观模式(Facade Pattern)** 54 | 定义一个外观类,外观类隐藏系统的复杂性,为客户端提供简化的方法和对现有系统类方法的委托调用。 55 | 例如:二手房交易的中介,属于外观模式。买房者通过中介可以简单地买到二手房,中介自己把联系房东看房砍价、过户、交税这些复杂的事情都搞定了。 56 | 57 | **代理模式(Proxy Pattern)** 58 | 用一个代理类代表另一个类的功能,但是不改变被代理类的功能。目的是控制对被代理类的访问。 59 | 60 | **中介者模式(Mediator Pattern)** 61 | 用一个中介对象来封装一系列的对象交互,中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。将各对象之间的网状结构分离为星型结构。 62 | 例如:MVC 框架,其中C(控制器)就是 M(模型)和 V(视图)的中介者。微信群是各群员之间的中介者。 -------------------------------------------------------------------------------- /音视频/001.音视频基本知识.md: -------------------------------------------------------------------------------- 1 | ## 1 视频编码 2 | 特定压缩技术,某种视频格式文件转换成另一种视频格式文件方式。 3 | * MPEG 4 | * H.26X 5 | 6 | ## 2 音频编码 7 | * AAC:有损压缩格式 8 | * MP3:音频压缩技术 9 | * AC3:有损音频编码格式 10 | 11 | ## 3 多媒体播放组件 12 | * MediaPlayer 13 | * MediaCodec 14 | * OMX 15 | * StateFright 16 | 17 | ## 4 常见的多媒体框架 18 | * VLC:Video LAN Client,自由、开源的跨平台多媒体播放器及框架 19 | * FFmpeg:多媒体解决方案 20 | * GStreamer:构建流媒体应用的开源多媒体框架 21 | 22 | ## 5 术语 23 | * 帧率:每秒显示帧数(fps、Hz) 24 | * 分辨率:图像大小和尺寸 25 | * 刷新率:屏幕每秒画面被刷新的次数(单位 Hz),达到 80 Hz 就不错。 26 | * 编码格式: 27 | * MPEG(MPEG-2、MPEG-4) 28 | * H.26X(H.263、H.264/AVC、H.2665/HEVC) 29 | 30 | * 封装格式:把编码后的音视频以吃得开格式封装到一个容器,封装格式有 MKV、AVI、TS。 31 | * 码率:比特率(文件大小 = 码率 \* 时长) 32 | * 画质与码率:画质与视频质量和码率、编码算法有关 33 | * DTS:标识读入内存中的比特流在什么时候开始送入解码器中进行解码(解码的时间) 34 | * PTS:用于度量解码后的视频帧什么时候被显示出来(显示的时间) 35 | * 颜色空间模型 36 | * YUV:编译true-color颜色空间(color space)的种类,Y'UV, YUV, YCbCr,YPbPr等专有名词都可以称为YUV,彼此有重叠。“Y”表示明亮度(Luminance或Luma),也就是灰阶值,“U”和“V”表示的则是色度(Chrominance或Chroma),作用是描述影像色彩及饱和度,用于指定像素的颜色 37 | * RGB:是通过对红(R)、绿(G)、蓝(B)三个颜色通道的变化以及它们相互之间的叠加来得到各式各样的颜色的,RGB即是代表红、绿、蓝三个通道的颜色,这个标准几乎包括了人类视力所能感知的所有颜色,是运用最广的颜色系统之一。 38 | 39 | * 视频帧 I、P、B 帧 40 | * I:关键帧,包含完整画面 41 | * P:差别帧,没有完整画面数据,只有与前一帧的画面差别的数据 42 | * B:双向差别帧,本帧与前后帧的差别 43 | 44 | * 音频帧 45 | * 对 PCM ,不需要帧 46 | * AMR 帧,每 20ms 为一帧 47 | * MP3 帧,包括采样率、比特率等参数。 48 | 49 | * 量化精度:单位 bit(比特) 越高越接近原音乐 50 | * 采样率:每秒音频采样点个数(8000/44 100 Hz),单位 Hz 51 | * 声道:指声音在录制或播放时在不同空间位置采集或回放的相互独立的音频信号,所以声道数也就是声音录制时的音源数量或回放时相应的扬声器数量 --------------------------------------------------------------------------------