├── .gitignore ├── 00开发辅助 ├── AS插件及配置.md ├── Android ADB 命令简明手册.md ├── Chrome 插件配置.md ├── Git 基础学习.md ├── Git 指令.md ├── Mac笔记本常用软件.md ├── Markdown简明语法.md ├── Python学习笔记.md ├── SQL 语法.md ├── Shell学习笔记.md ├── assets │ ├── git-cheat-sheet-v2-back.svg │ ├── git-cheat-sheet-v2-front.svg │ ├── git_command.png │ └── uml_class.png ├── 一张图简述UML类图.md ├── 架构特性列表.md └── 正则表达式.md ├── 01计算机基础 ├── assets │ ├── cs_computer_command.png │ ├── cs_computer_construct.png │ ├── cs_computer_construct_ssd.png │ └── cs_computer_layer.png ├── 操作系统 │ ├── 001概述.md │ ├── 002进程管理.md │ ├── 003内存管理.md │ ├── 004文件管理.md │ ├── 005设备管理.md │ ├── 006 链接.md │ ├── 007 IO管理.md │ ├── Linux.md │ └── assets │ │ ├── os_file_circle_directory.jpg │ │ ├── os_file_double_directory.jpg │ │ ├── os_file_multi_directory.jpg │ │ ├── os_file_sdcard.jpg │ │ ├── os_file_single_directory.jpg │ │ ├── os_io_cache.jpg │ │ ├── os_io_control.png │ │ ├── os_progress_schedule.png │ │ ├── os_progress_state_flow.png │ │ └── os_thread_category.png ├── 数据库系统原理.md ├── 网络 │ ├── 001网络概述.md │ ├── 002物理层.md │ ├── 003数据链路层.md │ ├── 004网络层.md │ ├── 005传输层.md │ ├── 006应用层.md │ ├── Cyc2018 │ │ ├── 计算机网络 - 传输层.md │ │ ├── 计算机网络 - 应用层.md │ │ ├── 计算机网络 - 概述.md │ │ ├── 计算机网络 - 物理层.md │ │ ├── 计算机网络 - 目录.md │ │ ├── 计算机网络 - 网络层.md │ │ └── 计算机网络 - 链路层.md │ ├── HTTP.md │ ├── Socket.md │ └── assets │ │ ├── net_aloha.png │ │ ├── net_change_mode.png │ │ ├── net_connect_control.png │ │ ├── net_danmo_guangxian.png │ │ ├── net_digital_model.png │ │ ├── net_dns_layerpng.png │ │ ├── net_domain_dns.png │ │ ├── net_duomo_guangxian.png │ │ ├── net_email_send_receive.png │ │ ├── net_email_system.png │ │ ├── net_encode_method.png │ │ ├── net_fast_restore.png │ │ ├── net_http_course.png │ │ ├── net_http_data_struct.png │ │ ├── net_osi_layer.png │ │ ├── net_p2p_mode.png │ │ ├── net_protocol.png │ │ ├── net_shuangjiaoxian.png │ │ ├── net_slow_speed.png │ │ ├── net_tcp_data.png │ │ ├── net_time_aloha.png │ │ ├── net_tongzhou_dianlan.png │ │ ├── net_udp_data.png │ │ └── net_www.png └── 计算机系统概述.md ├── 02Java及Kotlin ├── JVM面试题.md ├── Java 基础.md ├── Java 容器.md ├── Java 并发.md ├── Java 虚拟机.md ├── JavaIO.md ├── Java基础.md ├── Java容器.md ├── Java并发.md ├── Java线程池.md ├── Java网络编程面试题.md ├── Java虚拟机.md ├── Java面试题之多线程(一).md ├── Java面试题之多线程(三).md ├── Java面试题之多线程(二).md ├── Java面试题之多线程(四).md ├── assets │ ├── java_access_obj.png │ ├── java_cached_threadpool.png │ ├── java_cas_aba.png │ ├── java_checked_exception.png │ ├── java_class_loader.png │ ├── java_class_loader_category.png │ ├── java_collections.png │ ├── java_complier.png │ ├── java_concurrent_hashmap.png │ ├── java_concurrent_hashmap_tree.png │ ├── java_create_obj.png │ ├── java_fixed_threadpool.png │ ├── java_gc_copy.png │ ├── java_gc_mark.png │ ├── java_gc_mark_clear.png │ ├── java_gc_root.png │ ├── java_gcpng.png │ ├── java_hashmap_1.7.png │ ├── java_hashmap_1.8.png │ ├── java_io.png │ ├── java_io_channel.png │ ├── java_io_stream.png │ ├── java_jre.png │ ├── java_jvm.png │ ├── java_memeory_mode.png │ ├── java_memory_1.6.png │ ├── java_memory_1.8.png │ ├── java_queue_heap.png │ ├── java_schedule_threadpool.png │ ├── java_single_threadpool.png │ ├── java_thread_bad_lock.png │ ├── java_thread_lifecycle.png │ ├── java_thread_states.png │ ├── java_threadpool_desception.png │ ├── java_threadpool_executor.png │ ├── java_threadpool_flow.png │ ├── java_throwable.png │ └── java_unchecked_exception.png ├── jvm │ ├── 00_command_list.md │ ├── 01_bytecode_class.md │ ├── 02_bytecode_command.md │ ├── JVM-内存分配机制.md │ └── JVM-垃圾回收机制.md ├── 反射与动态代理.md ├── 异常体系.md ├── 泛型.md ├── 部分源码分析 │ ├── ArrayList源码分析.md │ ├── ConcurrentHashMap.md │ ├── CopyOnWriteArrayList.md │ ├── HashMap.md │ ├── LinkedHashMap源码分析.md │ ├── LinkedList源码分析.md │ └── PriorityQueue源码分析.md ├── 集合相关.md └── 面向对象.md ├── 03Android ├── ActivityManagerService.md ├── Activity启动过程.md ├── Android 中的 ClassLoader.md ├── Android中的冷门知识汇总.md ├── Android基础.md ├── Android开发者必须掌握的设计模式.md ├── Android性能优化.md ├── Android新特性.md ├── Android系统启动.md ├── Android系统架构.md ├── Android组件化架构.md ├── Apk打包流程.md ├── Binder机制.md ├── Bitmap.md ├── ContentProvider启动过程.md ├── Dalvik和ART.md ├── Handler.md ├── HandlerThread.md ├── Hook技术.md ├── IntentService.md ├── LayoutInflater.md ├── Service启动过程.md ├── WindowManagerService.md ├── assets │ ├── android_activity_backstack.png │ ├── android_activity_create.png │ ├── android_activity_launch_flow.png │ ├── android_activity_stack.png │ ├── android_activity_start_flow.png │ ├── android_activity_window_view.png │ ├── android_apk_package.png │ ├── android_apk_sign.png │ ├── android_apk_sign_check.png │ ├── android_apk_sign_v1.png │ ├── android_apk_sign_v2.png │ ├── android_apk_sign_v3.png │ ├── android_binder.png │ ├── android_context.png │ ├── android_eventbus.png │ ├── android_handler.png │ ├── android_handler_message.png │ ├── android_hook.png │ ├── android_hotfix_classloader_dex.png │ ├── android_hotfix_instant_run.png │ ├── android_leakcanary.png │ ├── android_module_arch.png │ ├── android_module_plugin_taobao.png │ ├── android_okhttp.png │ ├── android_progress_keep_alive.png │ ├── android_service_launch.png │ ├── android_service_lifecycle.png │ ├── android_stack_arch.png │ ├── android_system_boot.png │ └── android_window_manager.png ├── basic │ ├── 01_activity.md │ ├── 02_fragment.md │ ├── 03_service.md │ ├── 04_broadcast.md │ ├── 05_content_provider.md │ ├── 06_multiple_screen_support.md │ ├── 07_handler.md │ ├── 08_task_affinity.md │ ├── 09_signature.md │ ├── Android-Activity启动模式&IntentFilter匹配规则.md │ ├── Android-Android_Studio3升级指南.md │ ├── Android-v1&v2签名机制.md │ ├── Android-反编译指南.md │ ├── Android-屏幕适配全攻略.md │ ├── Android-性能优化-UI优化.md │ └── Android-性能优化-内存优化.md ├── framework │ ├── 01_system_start.md │ ├── 02_init_zygote.md │ ├── 03_system_server_01.md │ ├── 04_system_server_02.md │ ├── Android-Activity与Window与View之间的关系.md │ ├── Android-Activity启动过程.md │ ├── Android-Binder进程间通讯.md │ ├── Android-Handler消息机制.md │ ├── Android-IPC多进程.md │ ├── Android-PackageManagerService分析.md │ ├── Android-PowerManagerService-WakeLock.md │ ├── Android-PowerManagerService-亮屏.md │ ├── Android-PowerManagerService-启动.md │ ├── Android-PowerManagerService-灭屏.md │ ├── Android-Service启动过程.md │ ├── Android-SurfaceFlinger图形系统.md │ ├── Android-Windows环境下载源码.md │ └── Android-系统启动过程.md ├── other │ ├── Android-Dagger2.md │ └── Lottie动画开源库使用&源码分析.md ├── performance │ ├── 01_render.md │ ├── 02_compute.md │ ├── 03_memory.md │ ├── 04_battery.md │ ├── 05_network.md │ ├── 06_launch.md │ └── 07_apk.md ├── plugin │ ├── 01_reflection.md │ ├── 02_proxy.md │ ├── 03_hook.md │ └── 04_hook_ams.md ├── 事件分发.md ├── 广播启动过程.md ├── 应用程序进程启动过程.md ├── 源码分析 │ ├── ARouter.md │ ├── ButterKnife.md │ ├── Dagger2.md │ ├── EventBus.md │ ├── Glide.md │ ├── GreenDao.md │ ├── Leakcanary.md │ ├── Okhttp.md │ ├── Retrofit.md │ └── RxJava.md └── 策略与方案 │ ├── Android9.0非SDK接口限制.md │ ├── v1、v2、v3签名区别.md │ ├── 保活.md │ ├── 换肤方案.md │ ├── 插件化.md │ ├── 热修复.md │ └── 组件化.md ├── 04数据结构及算法 ├── Leetcode 题解 - 二分查找.md ├── Leetcode 题解 - 位运算.md ├── Leetcode 题解 - 分治.md ├── Leetcode 题解 - 动态规划.md ├── Leetcode 题解 - 双指针.md ├── Leetcode 题解 - 哈希表.md ├── Leetcode 题解 - 图.md ├── Leetcode 题解 - 字符串.md ├── Leetcode 题解 - 排序.md ├── Leetcode 题解 - 搜索.md ├── Leetcode 题解 - 数学.md ├── Leetcode 题解 - 数组与矩阵.md ├── Leetcode 题解 - 栈和队列.md ├── Leetcode 题解 - 树.md ├── Leetcode 题解 - 目录.md ├── Leetcode 题解 - 贪心思想.md ├── Leetcode 题解 - 链表.md ├── code │ ├── 10.1 斐波那契数列.md │ ├── 10.2 矩形覆盖.md │ ├── 10.3 跳台阶.md │ ├── 10.4 变态跳台阶.md │ ├── 11. 旋转数组的最小数字.md │ ├── 12. 矩阵中的路径.md │ ├── 13. 机器人的运动范围.md │ ├── 14. 剪绳子.md │ ├── 15. 二进制中 1 的个数.md │ ├── 16. 数值的整数次方.md │ ├── 17. 打印从 1 到最大的 n 位数.md │ ├── 18.1 在 O(1) 时间内删除链表节点.md │ ├── 18.2 删除链表中重复的结点.md │ ├── 19. 正则表达式匹配.md │ ├── 20. 表示数值的字符串.md │ ├── 21. 调整数组顺序使奇数位于偶数前面.md │ ├── 22. 链表中倒数第 K 个结点.md │ ├── 23. 链表中环的入口结点.md │ ├── 24. 反转链表.md │ ├── 25. 合并两个排序的链表.md │ ├── 26. 树的子结构.md │ ├── 27. 二叉树的镜像.md │ ├── 28. 对称的二叉树.md │ ├── 29. 顺时针打印矩阵.md │ ├── 3. 数组中重复的数字.md │ ├── 30. 包含 min 函数的栈.md │ ├── 31. 栈的压入、弹出序列.md │ ├── 32.1 从上往下打印二叉树.md │ ├── 32.2 把二叉树打印成多行.md │ ├── 32.3 按之字形顺序打印二叉树.md │ ├── 33. 二叉搜索树的后序遍历序列.md │ ├── 34. 二叉树中和为某一值的路径.md │ ├── 35. 复杂链表的复制.md │ ├── 36. 二叉搜索树与双向链表.md │ ├── 37. 序列化二叉树.md │ ├── 38. 字符串的排列.md │ ├── 39. 数组中出现次数超过一半的数字.md │ ├── 4. 二维数组中的查找.md │ ├── 40. 最小的 K 个数.md │ ├── 41.1 数据流中的中位数.md │ ├── 41.2 字符流中第一个不重复的字符.md │ ├── 42. 连续子数组的最大和.md │ ├── 43. 从 1 到 n 整数中 1 出现的次数.md │ ├── 44. 数字序列中的某一位数字.md │ ├── 45. 把数组排成最小的数.md │ ├── 46. 把数字翻译成字符串.md │ ├── 47. 礼物的最大价值.md │ ├── 48. 最长不含重复字符的子字符串.md │ ├── 49. 丑数.md │ ├── 5. 替换空格.md │ ├── 50. 第一个只出现一次的字符位置.md │ ├── 51. 数组中的逆序对.md │ ├── 52. 两个链表的第一个公共结点.md │ ├── 53. 数字在排序数组中出现的次数.md │ ├── 54. 二叉查找树的第 K 个结点.md │ ├── 55.1 二叉树的深度.md │ ├── 55.2 平衡二叉树.md │ ├── 56. 数组中只出现一次的数字.md │ ├── 57.1 和为 S 的两个数字.md │ ├── 57.2 和为 S 的连续正数序列.md │ ├── 58.1 翻转单词顺序列.md │ ├── 58.2 左旋转字符串.md │ ├── 59. 滑动窗口的最大值.md │ ├── 6. 从尾到头打印链表.md │ ├── 60. n 个骰子的点数.md │ ├── 61. 扑克牌顺子.md │ ├── 62. 圆圈中最后剩下的数.md │ ├── 63. 股票的最大利润.md │ ├── 64. 求 1+2+3+...+n.md │ ├── 65. 不用加减乘除做加法.md │ ├── 66. 构建乘积数组.md │ ├── 67. 把字符串转换成整数.md │ ├── 68. 树中两个节点的最低公共祖先.md │ ├── 7. 重建二叉树.md │ ├── 8. 二叉树的下一个结点.md │ └── 9. 用两个栈实现队列.md ├── 排序算法.md ├── 算法 - 其它.md ├── 算法 - 并查集.md ├── 算法 - 排序.md ├── 算法 - 栈和队列.md └── 算法 - 符号表.md ├── README.md ├── assets ├── Android开发.svg └── 编程进阶知识图谱.svg ├── doc ├── Android学习知识点.xmind ├── Android路线图.xmind ├── Git 指令.xmind └── 类图总括.mdj ├── 临时文件夹 ├── Android 13 媒体权限适配指南.md ├── Android WebView H5 秒开方案总结.md ├── Android 内存优化.md ├── Android 包体积优化.md ├── Android 网络优化.md ├── Android 网络优化1.md ├── Android 网络优化2.md ├── Android主流三方库源码分析(一、深入理解OKHttp源码).md ├── Android主流三方库源码分析(三、深入理解Glide源码).md ├── Android主流三方库源码分析(六、深入理解Leakcanary源码).md ├── Android开发.xmind ├── Android性能优化之内存优化.md ├── Android触摸事件传递机制.md ├── Coil 和 Glide 的 Bitmap 缓存复用机制.md ├── Gson 和 Kotlin Data Class 的避坑指南.md ├── IM开发相关问题.md ├── Interview.xmind ├── Java & Android 集合框架须知须会(1).md ├── Java & Android 集合框架须知须会(2).md ├── Java & Android 集合框架须知须会(3).md ├── Java 多线程开发(1)什么是多线程.md ├── Java 多线程开发(2)怎么实现多线程同步.md ├── Java 多线程开发(3)线程活性故障有哪些.md ├── Java 多线程开发(4)锁的分类有这么多.md ├── Java 多线程开发(5)超详细的 ThreadPoolExecutor 源码解析.md ├── img │ ├── batch_pull_offline_messages1.png │ ├── batch_pull_offline_messages2.png │ ├── im_optimize.png │ ├── im_problems.png │ ├── im_security.png │ ├── im_send_file.png │ ├── message_timeless.png │ ├── resend_message1.png │ ├── resend_message2.png │ ├── send_message_ack.png │ ├── send_message_process.png │ └── send_message_simple.png ├── notebook │ ├── ARouter加载过程 .png │ ├── App线程优化.png │ ├── Glide_load加载流程.png │ ├── Glide_with加载流程.png │ ├── Glide加载流程.png │ ├── NDK入门.png │ ├── android-stack.png │ ├── native_crash_log.png │ ├── 业务开发安全基础.png │ ├── 知识体系.png │ └── 计算机组成原理之概述篇.png ├── performence │ ├── APM.png │ ├── ASM3.0指南翻译.pdf │ ├── Android_P7架构师.png │ ├── Android架构师成长之路 .png │ ├── App绘制优化.png │ ├── AspectJ程序设计指南.pdf │ ├── LICENSE │ ├── README.md │ ├── algorithm_map.png │ ├── android-performance.png │ ├── app-release-unproguard-classshark-methods-count.png │ ├── app_bundle.png │ ├── applychanges.png │ ├── ci.png │ ├── class_vs_dex.png │ ├── dex.png │ ├── dex_with_debug_item.png │ ├── flutter_acrchitecture.png │ ├── flutter_performance_compare.png │ ├── flutter_ui_core.png │ ├── ftrace_architecture.jpg │ ├── graphic_arc.png │ ├── image_format_select.png │ ├── instant_run.png │ ├── jvm_dalivk.png │ ├── litho_mount_spec_lifecycle.png │ ├── litho_plan.png │ ├── litho_recycler.png │ ├── litho_sync.png │ ├── probe.jpg │ ├── profilo_get_java_stack.jpg │ ├── readerthread.png │ ├── traditional_develop.png │ ├── 全面了解性能优化.png │ ├── 启动器.png │ └── 大厂职级薪资表.jpeg ├── 一文读懂 Java 和 Kotlin 的泛型难点.md ├── 开源协议.png ├── 开源协议选择.png ├── 探究 Bitmap 的优化手段.md ├── 探究 Kotlin 的隐藏性能开销与避坑指南.md ├── 插件化.xmind ├── 攻击技术.md ├── 编程进阶知识图谱.xmind └── 聊聊 Context 的一些知识点.md ├── 设计模式 ├── CodePattern │ ├── 中介者模式.md │ ├── 享元模式.md │ ├── 代理模式.md │ ├── 单例模式.md │ ├── 原型模式.md │ ├── 命令模式.md │ ├── 备忘录模式.md │ ├── 外观模式.md │ ├── 建造者模式.md │ ├── 抽象工厂模式.md │ ├── 桥接模式.md │ ├── 模版模式.md │ ├── 状态模式.md │ ├── 空对象模式.md │ ├── 策略模式.md │ ├── 简单工厂模式.md │ ├── 组合模式.md │ ├── 装饰器模式.md │ ├── 观察者模式.md │ ├── 解释器模式.md │ ├── 访问者模式.md │ ├── 责任链模式.md │ ├── 过滤器模式.md │ ├── 迭代器模式.md │ ├── 适配器模式.md │ └── 面向对象思想.md ├── DesignPattern │ ├── 设计模式 - 单例.md │ ├── 设计模式 - 中介者.md │ ├── 设计模式 - 享元.md │ ├── 设计模式 - 代理.md │ ├── 设计模式 - 原型模式.md │ ├── 设计模式 - 命令.md │ ├── 设计模式 - 备忘录.md │ ├── 设计模式 - 外观.md │ ├── 设计模式 - 工厂方法.md │ ├── 设计模式 - 抽象工厂.md │ ├── 设计模式 - 桥接.md │ ├── 设计模式 - 模板方法.md │ ├── 设计模式 - 状态.md │ ├── 设计模式 - 生成器.md │ ├── 设计模式 - 空对象.md │ ├── 设计模式 - 策略.md │ ├── 设计模式 - 简单工厂.md │ ├── 设计模式 - 组合.md │ ├── 设计模式 - 装饰.md │ ├── 设计模式 - 观察者.md │ ├── 设计模式 - 解释器.md │ ├── 设计模式 - 访问者.md │ ├── 设计模式 - 责任链.md │ ├── 设计模式 - 迭代器.md │ ├── 设计模式 - 适配器.md │ └── 设计模式.md ├── 设计模式 Patterns.xmind ├── 设计模式 学习简述.md └── 设计模式UML类图.mdj └── 面试题库 ├── Android面试题.md ├── java面试题.md ├── 非技术性问题&HR问题汇总.md └── 高端技术面试题.md /.gitignore: -------------------------------------------------------------------------------- 1 | # 添加一些需要忽略git提交的文件或目录规则 2 | .DS_Store 3 | .obsidian 4 | 5 | -------------------------------------------------------------------------------- /00开发辅助/assets/git_command.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/00开发辅助/assets/git_command.png -------------------------------------------------------------------------------- /00开发辅助/assets/uml_class.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/00开发辅助/assets/uml_class.png -------------------------------------------------------------------------------- /00开发辅助/一张图简述UML类图.md: -------------------------------------------------------------------------------- 1 | ## 一张图简述UML类图 2 | 3 | > UML建模常用视图中,类图可算是最多的,初学UML的类图绘制,基于starUML工具,现简记如下 4 | 5 | #### 一、类图组件 6 | 7 | 1. 类、接口 8 | 9 | 类图中,类的表示如图所示,有三部分: 10 | 11 | - 类名称 12 | - 属性:格式为 `权限 名称:类型 [=默认值]` \[ ] 表示可选的意思 13 | - 函数:格式为 `权限 函数名(参数) :[ 返回类型 ]` 14 | 15 | 权限:`+、-、#、~`分别对应`public、private、protected、default` 16 | 17 | 接口,类似于类图的表示,名称上有`<>`这个标记。或者用 `圆圈⭕️`表示 18 | 19 | 2. 关系线 20 | 21 | - 继承,使用 `无尾 实线 空三角箭头` 22 | - 接口实现,使用`无尾 虚线 空三角箭头`,注,如用 `圆圈`表示接口,则只是一条实线表示实现关系 23 | - 关联,`无尾 实线 大于号箭头` 24 | - 依赖,`无尾 虚线 大于号箭头` 25 | - 聚合,`空心棱形 实线`,聚合关系,个体可独立 26 | - 组合,`实心棱形 实线`组合关系,组成部分不能独立 27 | 28 | ![uml 类图](./assets/uml_class.png) -------------------------------------------------------------------------------- /01计算机基础/assets/cs_computer_command.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/01计算机基础/assets/cs_computer_command.png -------------------------------------------------------------------------------- /01计算机基础/assets/cs_computer_construct.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/01计算机基础/assets/cs_computer_construct.png -------------------------------------------------------------------------------- /01计算机基础/assets/cs_computer_construct_ssd.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/01计算机基础/assets/cs_computer_construct_ssd.png -------------------------------------------------------------------------------- /01计算机基础/assets/cs_computer_layer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/01计算机基础/assets/cs_computer_layer.png -------------------------------------------------------------------------------- /01计算机基础/操作系统/004文件管理.md: -------------------------------------------------------------------------------- 1 | ## 文件管理 2 | 3 | ### 一、文件系统基础 4 | 5 | #### 1.1 文件的相关概念 6 | 7 | 文件是以计算机硬盘为载体的,存储在计算机上的信息集合,如文档、图片、程序等。 8 | 9 | 文件的结构:数据项、记录、文件(有结构文件,无结构文件) 10 | 11 | 属性:名称、标识符、类型、位置、大小、保护、时间日期和用户标识 12 | 13 | 基本操作:创建、读写、重定位、删除、截断等 14 | 15 | #### 1.2 文件的逻辑结构 16 | 17 | - 无结构文件(流式文件),如文本文件; 18 | - 有结构文件(记录式文件):顺序文件、索引文件、索引顺序文件,如数据库 19 | 20 | #### 1.3 目录结构 21 | 22 | - 单级目录结构 23 | 24 | os_file_single_directory 25 | 26 | - 两级目录结构 27 | 28 | ![os_file_double_directory](./assets/os_file_double_directory.jpg) 29 | 30 | - 多级目录结构 31 | 32 | ![os_file_multi_directory](./assets/os_file_multi_directory.jpg) 33 | 34 | - 无环图目录结构 35 | 36 | os_file_circle_directory 37 | 38 | 39 | 40 | #### 1.4 文件共享 41 | 42 | 保护不同的用户对文件有不同的操作权限 43 | 44 | - 基于索引节点的共享文件(硬链接) 45 | - 利用符号实现文件共享(软连接):只是将文件路径链接共享到共享者的目录下。 46 | - 文件保护:口令、文件加密、访问权限控制 47 | 48 | ### 二、文件系统实现 49 | 50 | #### 2.1 文件层结构 51 | 52 | 1. 用户调用接口 53 | 2. 文件目录系统 54 | 3. 存储控制验证 55 | 4. 逻辑文件系统 56 | 5. 物理文件系统 57 | 6. 服务分配模块 58 | 7. 设备管理程序模块 59 | 60 | #### 2.2 目录实现 61 | 62 | 线性列表、哈希表 63 | 64 | #### 2.3 文件实现 65 | 66 | 文件分配方式:连续分配、链接分配、索引分配 67 | 68 | ### 三、磁盘组织与管理 69 | 70 | 磁盘:由表面涂有磁性物质的金属或塑料构成的圆形盘片,通过**磁头**导体线圈从磁盘存储数据。 71 | 72 | ![os_file_sdcard](./assets/os_file_sdcard.jpg) 73 | 74 | - 磁盘调度算法: 75 | - 先来先服务FCFS 76 | - 最短寻址时间优先SSTF 77 | - 扫描算法SCAN 78 | - 循环算法S- SCAN 79 | - 磁盘的管理 80 | - 磁盘初始化:对磁盘进行低级格式化和逻辑格式化 81 | - 引导快:存放自举程序 82 | - 坏块:对于损坏扇区的处理 -------------------------------------------------------------------------------- /01计算机基础/操作系统/005设备管理.md: -------------------------------------------------------------------------------- 1 | # 计算机操作系统 - 设备管理 2 | 3 | * [计算机操作系统 - 设备管理](#计算机操作系统---设备管理) 4 | * [磁盘结构](#磁盘结构) 5 | * [磁盘调度算法](#磁盘调度算法) 6 | * [1. 先来先服务](#1-先来先服务) 7 | * [2. 最短寻道时间优先](#2-最短寻道时间优先) 8 | * [3. 电梯算法](#3-电梯算法) 9 | 10 | 11 | 12 | ## 磁盘结构 13 | 14 | - 盘面(Platter):一个磁盘有多个盘面; 15 | - 磁道(Track):盘面上的圆形带状区域,一个盘面可以有多个磁道; 16 | - 扇区(Track Sector):磁道上的一个弧段,一个磁道可以有多个扇区,它是最小的物理储存单位,目前主要有 512 bytes 与 4 K 两种大小; 17 | - 磁头(Head):与盘面非常接近,能够将盘面上的磁场转换为电信号(读),或者将电信号转换为盘面的磁场(写); 18 | - 制动手臂(Actuator arm):用于在磁道之间移动磁头; 19 | - 主轴(Spindle):使整个盘面转动。 20 | 21 |

22 | 23 | ## 磁盘调度算法 24 | 25 | 读写一个磁盘块的时间的影响因素有: 26 | 27 | - 旋转时间(主轴转动盘面,使得磁头移动到适当的扇区上) 28 | - 寻道时间(制动手臂移动,使得磁头移动到适当的磁道上) 29 | - 实际的数据传输时间 30 | 31 | 其中,寻道时间最长,因此磁盘调度的主要目标是使磁盘的平均寻道时间最短。 32 | 33 | ### 1. 先来先服务 34 | 35 | > FCFS, First Come First Served 36 | 37 | 按照磁盘请求的顺序进行调度。 38 | 39 | 优点是公平和简单。缺点也很明显,因为未对寻道做任何优化,使平均寻道时间可能较长。 40 | 41 | ### 2. 最短寻道时间优先 42 | 43 | > SSTF, Shortest Seek Time First 44 | 45 | 优先调度与当前磁头所在磁道距离最近的磁道。 46 | 47 | 虽然平均寻道时间比较低,但是不够公平。如果新到达的磁道请求总是比一个在等待的磁道请求近,那么在等待的磁道请求会一直等待下去,也就是出现饥饿现象。具体来说,两端的磁道请求更容易出现饥饿现象。 48 | 49 |

50 | 51 | ### 3. 电梯算法 52 | 53 | > SCAN 54 | 55 | 电梯总是保持一个方向运行,直到该方向没有请求为止,然后改变运行方向。 56 | 57 | 电梯算法(扫描算法)和电梯的运行过程类似,总是按一个方向来进行磁盘调度,直到该方向上没有未完成的磁盘请求,然后改变方向。 58 | 59 | 因为考虑了移动方向,因此所有的磁盘请求都会被满足,解决了 SSTF 的饥饿问题。 60 | 61 |

62 | -------------------------------------------------------------------------------- /01计算机基础/操作系统/006 链接.md: -------------------------------------------------------------------------------- 1 | # 计算机操作系统 - 链接 2 | 3 | * [计算机操作系统 - 链接](#计算机操作系统---链接) 4 | * [编译系统](#编译系统) 5 | * [静态链接](#静态链接) 6 | * [目标文件](#目标文件) 7 | * [动态链接](#动态链接) 8 | 9 | 10 | 11 | ## 编译系统 12 | 13 | 14 | 以下是一个 hello.c 程序: 15 | 16 | ```c 17 | #include 18 | 19 | int main() 20 | { 21 | printf("hello, world\n"); 22 | return 0; 23 | } 24 | ``` 25 | 26 | 在 Unix 系统上,由编译器把源文件转换为目标文件。 27 | 28 | ```bash 29 | gcc -o hello hello.c 30 | ``` 31 | 32 | 这个过程大致如下: 33 | 34 |

35 | 36 | - 预处理阶段:处理以 # 开头的预处理命令; 37 | - 编译阶段:翻译成汇编文件; 38 | - 汇编阶段:将汇编文件翻译成可重定位目标文件; 39 | - 链接阶段:将可重定位目标文件和 printf.o 等单独预编译好的目标文件进行合并,得到最终的可执行目标文件。 40 | 41 | ## 静态链接 42 | 43 | 静态链接器以一组可重定位目标文件为输入,生成一个完全链接的可执行目标文件作为输出。链接器主要完成以下两个任务: 44 | 45 | - 符号解析:每个符号对应于一个函数、一个全局变量或一个静态变量,符号解析的目的是将每个符号引用与一个符号定义关联起来。 46 | - 重定位:链接器通过把每个符号定义与一个内存位置关联起来,然后修改所有对这些符号的引用,使得它们指向这个内存位置。 47 | 48 |

49 | 50 | ## 目标文件 51 | 52 | - 可执行目标文件:可以直接在内存中执行; 53 | - 可重定位目标文件:可与其它可重定位目标文件在链接阶段合并,创建一个可执行目标文件; 54 | - 共享目标文件:这是一种特殊的可重定位目标文件,可以在运行时被动态加载进内存并链接; 55 | 56 | ## 动态链接 57 | 58 | 静态库有以下两个问题: 59 | 60 | - 当静态库更新时那么整个程序都要重新进行链接; 61 | - 对于 printf 这种标准函数库,如果每个程序都要有代码,这会极大浪费资源。 62 | 63 | 共享库是为了解决静态库的这两个问题而设计的,在 Linux 系统中通常用 .so 后缀来表示,Windows 系统上它们被称为 DLL。它具有以下特点: 64 | 65 | - 在给定的文件系统中一个库只有一个文件,所有引用该库的可执行目标文件都共享这个文件,它不会被复制到引用它的可执行文件中; 66 | - 在内存中,一个共享库的 .text 节(已编译程序的机器代码)的一个副本可以被不同的正在运行的进程共享。 67 | 68 |

69 | -------------------------------------------------------------------------------- /01计算机基础/操作系统/007 IO管理.md: -------------------------------------------------------------------------------- 1 | ## IO管理 2 | 3 | ### 一、IO管理概述 4 | 5 | #### 1.1 I/O设备 6 | 7 | - 按照使用特性分类 8 | - 人机交互累外部设备,如打印机、显示器等 9 | - 存储设备,如磁盘、光盘等 10 | - 网络通信设备,如网络接口等 11 | - 按传输速率分类 12 | - 低速设备:键鼠 13 | - 中速设备:打印机、扫描仪等 14 | - 高速设备:磁带机、磁盘机等 15 | - 按信息交换单位分类 16 | - 块设备:以数据块为存储单位 17 | - 字符设备:传输单位为字符,如交互式终端机等 18 | 19 | #### 1.2 I/O控制方式 20 | 21 | ![os_io_control](./assets/os_io_control.png) 22 | 23 | - 程序直接控制方式:CPU和I/O设备串行工作,由用户程序直接控制主存或CPU和外设的信息传送。 24 | - 中断驱动方式:允许I/O设备主动打断CPU的运行并请求服务。 25 | - DMA方式(直接存储器存储):用窃取或挪用总线控制权,在设备和主存之间开辟直接数据交换通道,成批交换数据,不必CPU干预。 26 | - 通道控制方式:独立于CPU的专门负责输入输出的处理器,有自己的通道指令,指令有CPU启动,结束操作后想CPU发出中断信号。实现了CPU、通道和设备的并行操作,提高系统资源利用率。 27 | 28 | #### 1.3 I/O子系统的层次结构 29 | 30 | 1. 用户层I/O软件:实现与用户交互的接口 31 | 2. 设备独立性软件:实现用户程序与设备驱动器的统一结构、设备命令、设备保护以及分配释放 32 | 3. 设备驱动程序:与硬件直接相关,负责具体实现系统对设备发出的操作指令 33 | 4. 中断处理程序:用于处理中断相关事项 34 | 5. 硬件设备:包括设备自身和电子部件(控制器) 35 | 36 | ### 二、I/O核心子系统 37 | 38 | 主要提供IO调度、缓冲与高速缓存、设备分配与回收、假脱机、设备保护和差错处理 39 | 40 | 通过IO调度改善系统整体性能,使进程间公平共享设备访问,减少IO完成所需的平均等待时间 41 | 42 | - 高速缓存与缓冲区 43 | 44 | - 高速缓存在内存中分两种形式 45 | - 在内存中开辟独立的存储空间,大小固定 46 | - 把胃里用的内存空间作为一个缓冲池,供请求分页系统和磁盘IO共享 47 | 48 | - 缓冲区 49 | 50 | - 采用硬件缓冲器,成本高,较少用。 51 | - 采用内存缓冲区 52 | 53 | 1. 单缓存、双缓存、循环缓存、缓冲池 54 | 55 | ![os_io_cache](./assets/os_io_cache.jpg) 56 | 57 | - 设备分配与回收 58 | 59 | 充分发挥设备使用效率,避免进程死锁。设备分类:独占设备、共享、虚拟设备; 60 | 61 | - IO调度 62 | - 安全分配:为进程分配设备后则进程阻塞,完成后唤醒 63 | - 非安全分配:系统分配设备后,进程可继续执行,也可发出新的IO请求。同一进程可使用多个IO设备。 64 | - 假脱机技术:若设备被占用,先缓存数据,设备空闲后再传输到设备。 65 | 66 | -------------------------------------------------------------------------------- /01计算机基础/操作系统/assets/os_file_circle_directory.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/01计算机基础/操作系统/assets/os_file_circle_directory.jpg -------------------------------------------------------------------------------- /01计算机基础/操作系统/assets/os_file_double_directory.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/01计算机基础/操作系统/assets/os_file_double_directory.jpg -------------------------------------------------------------------------------- /01计算机基础/操作系统/assets/os_file_multi_directory.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/01计算机基础/操作系统/assets/os_file_multi_directory.jpg -------------------------------------------------------------------------------- /01计算机基础/操作系统/assets/os_file_sdcard.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/01计算机基础/操作系统/assets/os_file_sdcard.jpg -------------------------------------------------------------------------------- /01计算机基础/操作系统/assets/os_file_single_directory.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/01计算机基础/操作系统/assets/os_file_single_directory.jpg -------------------------------------------------------------------------------- /01计算机基础/操作系统/assets/os_io_cache.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/01计算机基础/操作系统/assets/os_io_cache.jpg -------------------------------------------------------------------------------- /01计算机基础/操作系统/assets/os_io_control.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/01计算机基础/操作系统/assets/os_io_control.png -------------------------------------------------------------------------------- /01计算机基础/操作系统/assets/os_progress_schedule.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/01计算机基础/操作系统/assets/os_progress_schedule.png -------------------------------------------------------------------------------- /01计算机基础/操作系统/assets/os_progress_state_flow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/01计算机基础/操作系统/assets/os_progress_state_flow.png -------------------------------------------------------------------------------- /01计算机基础/操作系统/assets/os_thread_category.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/01计算机基础/操作系统/assets/os_thread_category.png -------------------------------------------------------------------------------- /01计算机基础/网络/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 | ### -------------------------------------------------------------------------------- /01计算机基础/网络/Cyc2018/计算机网络 - 物理层.md: -------------------------------------------------------------------------------- 1 | # 计算机网络 - 物理层 2 | 3 | * [计算机网络 - 物理层](#计算机网络---物理层) 4 | * [通信方式](#通信方式) 5 | * [带通调制](#带通调制) 6 | 7 | 8 | 9 | ## 通信方式 10 | 11 | 根据信息在传输线上的传送方向,分为以下三种通信方式: 12 | 13 | - 单工通信:单向传输 14 | - 半双工通信:双向交替传输 15 | - 全双工通信:双向同时传输 16 | 17 | ## 带通调制 18 | 19 | 模拟信号是连续的信号,数字信号是离散的信号。带通调制把数字信号转换为模拟信号。 20 | 21 |

22 | 23 | -------------------------------------------------------------------------------- /01计算机基础/网络/Cyc2018/计算机网络 - 目录.md: -------------------------------------------------------------------------------- 1 | # 计算机网络 2 | 3 | - [概述](计算机网络%20-%20概述.md) 4 | - [物理层](计算机网络%20-%20物理层.md) 5 | - [链路层](计算机网络%20-%20链路层.md) 6 | - [网络层](计算机网络%20-%20网络层.md) 7 | - [传输层](计算机网络%20-%20传输层.md) 8 | - [应用层](计算机网络%20-%20应用层.md) 9 | 10 | ## 参考链接 11 | 12 | - 计算机网络, 谢希仁 13 | - JamesF.Kurose, KeithW.Ross, 库罗斯, 等. 计算机网络: 自顶向下方法 [M]. 机械工业出版社, 2014. 14 | - W.RichardStevens. TCP/IP 详解. 卷 1, 协议 [M]. 机械工业出版社, 2006. 15 | - [Active vs Passive FTP Mode: Which One is More Secure?](https://securitywing.com/active-vs-passive-ftp-mode/) 16 | - [Active and Passive FTP Transfers Defined - KB Article #1138](http://www.serv-u.com/kb/1138/active-and-passive-ftp-transfers-defined) 17 | - [Traceroute](https://zh.wikipedia.org/wiki/Traceroute) 18 | - [ping](https://zh.wikipedia.org/wiki/Ping) 19 | - [How DHCP works and DHCP Interview Questions and Answers](http://webcache.googleusercontent.com/search?q=cache:http://anandgiria.blogspot.com/2013/09/windows-dhcp-interview-questions-and.html) 20 | - [What is process of DORA in DHCP?](https://www.quora.com/What-is-process-of-DORA-in-DHCP) 21 | - [What is DHCP Server ?](https://tecadmin.net/what-is-dhcp-server/) 22 | - [Tackling emissions targets in Tokyo](http://www.climatechangenews.com/2011/html/university-tokyo.html) 23 | - [What does my ISP know when I use Tor?](http://www.climatechangenews.com/2011/html/university-tokyo.html) 24 | - [Technology-Computer Networking[1]-Computer Networks and the Internet](http://www.linyibin.cn/2017/02/12/technology-ComputerNetworking-Internet/) 25 | - [P2P 网络概述.](http://slidesplayer.com/slide/11616167/) 26 | - [Circuit Switching (a) Circuit switching. (b) Packet switching.](http://slideplayer.com/slide/5115386/) 27 | -------------------------------------------------------------------------------- /01计算机基础/网络/assets/net_aloha.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/01计算机基础/网络/assets/net_aloha.png -------------------------------------------------------------------------------- /01计算机基础/网络/assets/net_change_mode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/01计算机基础/网络/assets/net_change_mode.png -------------------------------------------------------------------------------- /01计算机基础/网络/assets/net_connect_control.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/01计算机基础/网络/assets/net_connect_control.png -------------------------------------------------------------------------------- /01计算机基础/网络/assets/net_danmo_guangxian.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/01计算机基础/网络/assets/net_danmo_guangxian.png -------------------------------------------------------------------------------- /01计算机基础/网络/assets/net_digital_model.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/01计算机基础/网络/assets/net_digital_model.png -------------------------------------------------------------------------------- /01计算机基础/网络/assets/net_dns_layerpng.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/01计算机基础/网络/assets/net_dns_layerpng.png -------------------------------------------------------------------------------- /01计算机基础/网络/assets/net_domain_dns.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/01计算机基础/网络/assets/net_domain_dns.png -------------------------------------------------------------------------------- /01计算机基础/网络/assets/net_duomo_guangxian.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/01计算机基础/网络/assets/net_duomo_guangxian.png -------------------------------------------------------------------------------- /01计算机基础/网络/assets/net_email_send_receive.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/01计算机基础/网络/assets/net_email_send_receive.png -------------------------------------------------------------------------------- /01计算机基础/网络/assets/net_email_system.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/01计算机基础/网络/assets/net_email_system.png -------------------------------------------------------------------------------- /01计算机基础/网络/assets/net_encode_method.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/01计算机基础/网络/assets/net_encode_method.png -------------------------------------------------------------------------------- /01计算机基础/网络/assets/net_fast_restore.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/01计算机基础/网络/assets/net_fast_restore.png -------------------------------------------------------------------------------- /01计算机基础/网络/assets/net_http_course.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/01计算机基础/网络/assets/net_http_course.png -------------------------------------------------------------------------------- /01计算机基础/网络/assets/net_http_data_struct.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/01计算机基础/网络/assets/net_http_data_struct.png -------------------------------------------------------------------------------- /01计算机基础/网络/assets/net_osi_layer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/01计算机基础/网络/assets/net_osi_layer.png -------------------------------------------------------------------------------- /01计算机基础/网络/assets/net_p2p_mode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/01计算机基础/网络/assets/net_p2p_mode.png -------------------------------------------------------------------------------- /01计算机基础/网络/assets/net_protocol.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/01计算机基础/网络/assets/net_protocol.png -------------------------------------------------------------------------------- /01计算机基础/网络/assets/net_shuangjiaoxian.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/01计算机基础/网络/assets/net_shuangjiaoxian.png -------------------------------------------------------------------------------- /01计算机基础/网络/assets/net_slow_speed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/01计算机基础/网络/assets/net_slow_speed.png -------------------------------------------------------------------------------- /01计算机基础/网络/assets/net_tcp_data.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/01计算机基础/网络/assets/net_tcp_data.png -------------------------------------------------------------------------------- /01计算机基础/网络/assets/net_time_aloha.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/01计算机基础/网络/assets/net_time_aloha.png -------------------------------------------------------------------------------- /01计算机基础/网络/assets/net_tongzhou_dianlan.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/01计算机基础/网络/assets/net_tongzhou_dianlan.png -------------------------------------------------------------------------------- /01计算机基础/网络/assets/net_udp_data.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/01计算机基础/网络/assets/net_udp_data.png -------------------------------------------------------------------------------- /01计算机基础/网络/assets/net_www.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/01计算机基础/网络/assets/net_www.png -------------------------------------------------------------------------------- /02Java及Kotlin/assets/java_access_obj.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/02Java及Kotlin/assets/java_access_obj.png -------------------------------------------------------------------------------- /02Java及Kotlin/assets/java_cached_threadpool.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/02Java及Kotlin/assets/java_cached_threadpool.png -------------------------------------------------------------------------------- /02Java及Kotlin/assets/java_cas_aba.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/02Java及Kotlin/assets/java_cas_aba.png -------------------------------------------------------------------------------- /02Java及Kotlin/assets/java_checked_exception.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/02Java及Kotlin/assets/java_checked_exception.png -------------------------------------------------------------------------------- /02Java及Kotlin/assets/java_class_loader.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/02Java及Kotlin/assets/java_class_loader.png -------------------------------------------------------------------------------- /02Java及Kotlin/assets/java_class_loader_category.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/02Java及Kotlin/assets/java_class_loader_category.png -------------------------------------------------------------------------------- /02Java及Kotlin/assets/java_collections.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/02Java及Kotlin/assets/java_collections.png -------------------------------------------------------------------------------- /02Java及Kotlin/assets/java_complier.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/02Java及Kotlin/assets/java_complier.png -------------------------------------------------------------------------------- /02Java及Kotlin/assets/java_concurrent_hashmap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/02Java及Kotlin/assets/java_concurrent_hashmap.png -------------------------------------------------------------------------------- /02Java及Kotlin/assets/java_concurrent_hashmap_tree.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/02Java及Kotlin/assets/java_concurrent_hashmap_tree.png -------------------------------------------------------------------------------- /02Java及Kotlin/assets/java_create_obj.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/02Java及Kotlin/assets/java_create_obj.png -------------------------------------------------------------------------------- /02Java及Kotlin/assets/java_fixed_threadpool.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/02Java及Kotlin/assets/java_fixed_threadpool.png -------------------------------------------------------------------------------- /02Java及Kotlin/assets/java_gc_copy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/02Java及Kotlin/assets/java_gc_copy.png -------------------------------------------------------------------------------- /02Java及Kotlin/assets/java_gc_mark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/02Java及Kotlin/assets/java_gc_mark.png -------------------------------------------------------------------------------- /02Java及Kotlin/assets/java_gc_mark_clear.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/02Java及Kotlin/assets/java_gc_mark_clear.png -------------------------------------------------------------------------------- /02Java及Kotlin/assets/java_gc_root.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/02Java及Kotlin/assets/java_gc_root.png -------------------------------------------------------------------------------- /02Java及Kotlin/assets/java_gcpng.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/02Java及Kotlin/assets/java_gcpng.png -------------------------------------------------------------------------------- /02Java及Kotlin/assets/java_hashmap_1.7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/02Java及Kotlin/assets/java_hashmap_1.7.png -------------------------------------------------------------------------------- /02Java及Kotlin/assets/java_hashmap_1.8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/02Java及Kotlin/assets/java_hashmap_1.8.png -------------------------------------------------------------------------------- /02Java及Kotlin/assets/java_io.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/02Java及Kotlin/assets/java_io.png -------------------------------------------------------------------------------- /02Java及Kotlin/assets/java_io_channel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/02Java及Kotlin/assets/java_io_channel.png -------------------------------------------------------------------------------- /02Java及Kotlin/assets/java_io_stream.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/02Java及Kotlin/assets/java_io_stream.png -------------------------------------------------------------------------------- /02Java及Kotlin/assets/java_jre.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/02Java及Kotlin/assets/java_jre.png -------------------------------------------------------------------------------- /02Java及Kotlin/assets/java_jvm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/02Java及Kotlin/assets/java_jvm.png -------------------------------------------------------------------------------- /02Java及Kotlin/assets/java_memeory_mode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/02Java及Kotlin/assets/java_memeory_mode.png -------------------------------------------------------------------------------- /02Java及Kotlin/assets/java_memory_1.6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/02Java及Kotlin/assets/java_memory_1.6.png -------------------------------------------------------------------------------- /02Java及Kotlin/assets/java_memory_1.8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/02Java及Kotlin/assets/java_memory_1.8.png -------------------------------------------------------------------------------- /02Java及Kotlin/assets/java_queue_heap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/02Java及Kotlin/assets/java_queue_heap.png -------------------------------------------------------------------------------- /02Java及Kotlin/assets/java_schedule_threadpool.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/02Java及Kotlin/assets/java_schedule_threadpool.png -------------------------------------------------------------------------------- /02Java及Kotlin/assets/java_single_threadpool.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/02Java及Kotlin/assets/java_single_threadpool.png -------------------------------------------------------------------------------- /02Java及Kotlin/assets/java_thread_bad_lock.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/02Java及Kotlin/assets/java_thread_bad_lock.png -------------------------------------------------------------------------------- /02Java及Kotlin/assets/java_thread_lifecycle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/02Java及Kotlin/assets/java_thread_lifecycle.png -------------------------------------------------------------------------------- /02Java及Kotlin/assets/java_thread_states.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/02Java及Kotlin/assets/java_thread_states.png -------------------------------------------------------------------------------- /02Java及Kotlin/assets/java_threadpool_desception.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/02Java及Kotlin/assets/java_threadpool_desception.png -------------------------------------------------------------------------------- /02Java及Kotlin/assets/java_threadpool_executor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/02Java及Kotlin/assets/java_threadpool_executor.png -------------------------------------------------------------------------------- /02Java及Kotlin/assets/java_threadpool_flow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/02Java及Kotlin/assets/java_threadpool_flow.png -------------------------------------------------------------------------------- /02Java及Kotlin/assets/java_throwable.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/02Java及Kotlin/assets/java_throwable.png -------------------------------------------------------------------------------- /02Java及Kotlin/assets/java_unchecked_exception.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/02Java及Kotlin/assets/java_unchecked_exception.png -------------------------------------------------------------------------------- /02Java及Kotlin/异常体系.md: -------------------------------------------------------------------------------- 1 | #### 1 分类 2 | 3 | * Error: JVM 无法处理的错误 4 | * Exception: 5 | * **受检异常** :需要用 try…catch… 语句捕获并进行处理,并且可以从异常中恢复 6 | * **非受检异常** :是程序运行时错误,例如空指针异常。 7 | 8 | ![Java异常分类](./assets/java_throwable.png) 9 | 10 | #### 2 异常处理 11 | 12 | * Error(错误):一般表示代码运行时 JVM 出现问题。比如 NoClassDefFoundError 等。比如说当jvm耗完可用内存时,将出现 OutOfMemoryError。此类错误发生时,JVM将终止线程。 13 | 14 | * 非受检异常:将由系统自动抛出,应用本身可以选择处理或者忽略该异常。 15 | 16 | * 受检异常:进行捕获或者抛出该方法之外交给上层处理。要么使用 try-catch 捕获,要么 throws 该异常。 17 | 18 | #### 3 常见的受检异常 19 | 20 | ![image-20221105212952742](./assets/java_checked_exception.png) 21 | 22 | #### 4 常见非受检异常 23 | 24 | ![image-20221105213031755](./assets/java_unchecked_exception.png) -------------------------------------------------------------------------------- /02Java及Kotlin/部分源码分析/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 | -------------------------------------------------------------------------------- /03Android/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 | -------------------------------------------------------------------------------- /03Android/Android系统启动.md: -------------------------------------------------------------------------------- 1 | ## 1 Android 系统启动流程 2 | 3 | ![image-20221107155613637](./assets/android_system_boot.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 启动后会将已安装应用的快捷图标显示到界面上。 -------------------------------------------------------------------------------- /03Android/Apk打包流程.md: -------------------------------------------------------------------------------- 1 | ## 1 APK 打包过程 2 | 3 | ![image-20221107155746087](./assets/android_apk_package.png) 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 | * apkbuilder 工具打包到最终的 .apk 文件中 22 | 23 | * 对APK文件进行签名 24 | 25 | * 对签名后的 APK 文件进行对齐处理(正式包) 26 | 27 | * 对 APK 进行对齐处理,用到的工具是 zipalign -------------------------------------------------------------------------------- /03Android/assets/android_activity_backstack.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/03Android/assets/android_activity_backstack.png -------------------------------------------------------------------------------- /03Android/assets/android_activity_create.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/03Android/assets/android_activity_create.png -------------------------------------------------------------------------------- /03Android/assets/android_activity_launch_flow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/03Android/assets/android_activity_launch_flow.png -------------------------------------------------------------------------------- /03Android/assets/android_activity_stack.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/03Android/assets/android_activity_stack.png -------------------------------------------------------------------------------- /03Android/assets/android_activity_start_flow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/03Android/assets/android_activity_start_flow.png -------------------------------------------------------------------------------- /03Android/assets/android_activity_window_view.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/03Android/assets/android_activity_window_view.png -------------------------------------------------------------------------------- /03Android/assets/android_apk_package.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/03Android/assets/android_apk_package.png -------------------------------------------------------------------------------- /03Android/assets/android_apk_sign.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/03Android/assets/android_apk_sign.png -------------------------------------------------------------------------------- /03Android/assets/android_apk_sign_check.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/03Android/assets/android_apk_sign_check.png -------------------------------------------------------------------------------- /03Android/assets/android_apk_sign_v1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/03Android/assets/android_apk_sign_v1.png -------------------------------------------------------------------------------- /03Android/assets/android_apk_sign_v2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/03Android/assets/android_apk_sign_v2.png -------------------------------------------------------------------------------- /03Android/assets/android_apk_sign_v3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/03Android/assets/android_apk_sign_v3.png -------------------------------------------------------------------------------- /03Android/assets/android_binder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/03Android/assets/android_binder.png -------------------------------------------------------------------------------- /03Android/assets/android_context.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/03Android/assets/android_context.png -------------------------------------------------------------------------------- /03Android/assets/android_eventbus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/03Android/assets/android_eventbus.png -------------------------------------------------------------------------------- /03Android/assets/android_handler.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/03Android/assets/android_handler.png -------------------------------------------------------------------------------- /03Android/assets/android_handler_message.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/03Android/assets/android_handler_message.png -------------------------------------------------------------------------------- /03Android/assets/android_hook.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/03Android/assets/android_hook.png -------------------------------------------------------------------------------- /03Android/assets/android_hotfix_classloader_dex.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/03Android/assets/android_hotfix_classloader_dex.png -------------------------------------------------------------------------------- /03Android/assets/android_hotfix_instant_run.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/03Android/assets/android_hotfix_instant_run.png -------------------------------------------------------------------------------- /03Android/assets/android_leakcanary.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/03Android/assets/android_leakcanary.png -------------------------------------------------------------------------------- /03Android/assets/android_module_arch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/03Android/assets/android_module_arch.png -------------------------------------------------------------------------------- /03Android/assets/android_module_plugin_taobao.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/03Android/assets/android_module_plugin_taobao.png -------------------------------------------------------------------------------- /03Android/assets/android_okhttp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/03Android/assets/android_okhttp.png -------------------------------------------------------------------------------- /03Android/assets/android_progress_keep_alive.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/03Android/assets/android_progress_keep_alive.png -------------------------------------------------------------------------------- /03Android/assets/android_service_launch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/03Android/assets/android_service_launch.png -------------------------------------------------------------------------------- /03Android/assets/android_service_lifecycle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/03Android/assets/android_service_lifecycle.png -------------------------------------------------------------------------------- /03Android/assets/android_stack_arch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/03Android/assets/android_stack_arch.png -------------------------------------------------------------------------------- /03Android/assets/android_system_boot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/03Android/assets/android_system_boot.png -------------------------------------------------------------------------------- /03Android/assets/android_window_manager.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/03Android/assets/android_window_manager.png -------------------------------------------------------------------------------- /03Android/basic/Android-反编译指南.md: -------------------------------------------------------------------------------- 1 | # Android - 反编译指南 2 | 3 | 4 | ## 反编译源码 5 | ### 1. 使用 dex2jar 6 | 7 | 作用:将 apk 反编译成 java 源码(classes.dex 转化成 jar 文件) 8 | 9 | dex2jar 下载:https://sourceforge.net/projects/dex2jar 10 | 11 | 下载最新的 dex2jar 并解压 12 | 13 | ### 2. 解压 apk 安装包,将 classes.dex 复制 dex2jar 目录下,执行下面命令 14 | 15 | ```C 16 | d2j-dex2jar classes.dex 17 | ``` 18 | Win10 最新 PowerShell 窗口尝试下面命令: 19 | 20 | ```C 21 | .\d2j-dex2jar.bat .\classes.dex 22 | ``` 23 | 24 | ### 3. 得到 classes-dex2jar.jar 使用 jd-gui.exe 打开 25 | 26 | 作用:查看 APK 中 classes.dex 转化成出的 jar 文件,即源码文件 27 | 28 | dex2jar 下载:http://jd.benow.ca/ 29 | 30 | 31 | 32 | ## 反编译资源文件 33 | ### 1. 使用 apktool 34 | 作用:资源文件获取,可以提取出图片文件和布局文件进行使用查看 35 | 36 | apktool 下载:https://bitbucket.org/iBotPeaches/apktool/downloads/ 37 | 38 | 下载最新的 apktool 并解压 39 | ### 2. 将 apk 安装包复制到 apktool 目录下,执行命令 40 | 41 | ```C 42 | java -jar apktool.jar d -f xxx.apk -o res 43 | ``` 44 | 45 | > 注意:apktool.bat 与 apktool.jar 文件名为 apktool 46 | 47 | ## 我的公众号 48 | 49 | 欢迎你「扫一扫」下面的二维码,关注我的公众号,可以接受最新的文章推送,有丰厚的抽奖活动和福利等着你哦!😍 50 | 51 | 52 | 53 | 如果你有什么疑问或者问题,可以 [点击这里](https://github.com/jeanboydev/Android-ReadTheFuckingSourceCode/issues) 提交 issue,也可以发邮件给我 [jeanboy@foxmail.com](mailto:jeanboy@foxmail.com)。 54 | 55 | 同时欢迎你 [![Android技术进阶:386463747](https://camo.githubusercontent.com/615c9901677f501582b6057efc9396b3ed27dc29/687474703a2f2f7075622e69647171696d672e636f6d2f7770612f696d616765732f67726f75702e706e67)](http://shang.qq.com/wpa/qunwpa?idkey=0b505511df9ead28ec678df4eeb7a1a8f994ea8b75f2c10412b57e667d81b50d) 来一起交流学习,群里有很多大牛和学习资料,相信一定能帮助到你! 56 | 57 | -------------------------------------------------------------------------------- /03Android/策略与方案/插件化.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## 1 简介 4 | 5 | 插件化技术主要用于解决应用越来越庞大以及**功能模块的解耦**,解决以下的问题: 6 | 7 | - 业务复杂,模块耦合 8 | - 应用的接入 9 | - 65536 限制,内存占用大 10 | 11 | ## 2 插件化的思想 12 | 13 | ![image-20221107143909656](../assets/android_module_plugin_taobao.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 | ![image-20221107144012061](../assets/android_activity_start_flow.png) 49 | 50 | **普通 Activity 启动过程:** 51 | 52 | ![image-20221107144049514](../assets/android_activity_create.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 | -------------------------------------------------------------------------------- /04数据结构及算法/Leetcode 题解 - 目录.md: -------------------------------------------------------------------------------- 1 | # Leetcode 题解 2 | 3 | ## 前言 4 | 5 | 本文从 Leetcode 中精选大概 200 左右的题目,去除了某些繁杂但是没有多少算法思想的题目,同时保留了面试中经常被问到的经典题目。 6 | 7 | ## 算法思想 8 | 9 | - [双指针](Leetcode%20题解%20-%20双指针.md) 10 | - [排序](Leetcode%20题解%20-%20排序.md) 11 | - [贪心思想](Leetcode%20题解%20-%20贪心思想.md) 12 | - [二分查找](Leetcode%20题解%20-%20二分查找.md) 13 | - [分治](Leetcode%20题解%20-%20分治.md) 14 | - [搜索](Leetcode%20题解%20-%20搜索.md) 15 | - [动态规划](Leetcode%20题解%20-%20动态规划.md) 16 | - [数学](Leetcode%20题解%20-%20数学.md) 17 | 18 | ## 数据结构相关 19 | 20 | - [链表](Leetcode%20题解%20-%20链表.md) 21 | - [树](Leetcode%20题解%20-%20树.md) 22 | - [栈和队列](Leetcode%20题解%20-%20栈和队列.md) 23 | - [哈希表](Leetcode%20题解%20-%20哈希表.md) 24 | - [字符串](Leetcode%20题解%20-%20字符串.md) 25 | - [数组与矩阵](Leetcode%20题解%20-%20数组与矩阵.md) 26 | - [图](Leetcode%20题解%20-%20图.md) 27 | - [位运算](Leetcode%20题解%20-%20位运算.md) 28 | 29 | ## 参考资料 30 | 31 | - Leetcode 32 | - Weiss M A, 冯舜玺. 数据结构与算法分析——C 语言描述[J]. 2004. 33 | - Sedgewick R. Algorithms[M]. Pearson Education India, 1988. 34 | - 何海涛, 软件工程师. 剑指 Offer: 名企面试官精讲典型编程题[M]. 电子工业出版社, 2014. 35 | - 《编程之美》小组. 编程之美[M]. 电子工业出版社, 2008. 36 | - 左程云. 程序员代码面试指南[M]. 电子工业出版社, 2015. 37 | -------------------------------------------------------------------------------- /04数据结构及算法/code/10.1 斐波那契数列.md: -------------------------------------------------------------------------------- 1 | # 10.1 斐波那契数列 2 | 3 | ## 题目链接 4 | 5 | [牛客网](https://www.nowcoder.com/practice/c6c7742f5ba7442aada113136ddea0c3?tpId=13&tqId=11160&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) 6 | 7 | ## 题目描述 8 | 9 | 求斐波那契数列的第 n 项,n \<= 39。 10 | 11 | 12 | 13 |

14 | 15 | ## 解题思路 16 | 17 | 如果使用递归求解,会重复计算一些子问题。例如,计算 f(4) 需要计算 f(3) 和 f(2),计算 f(3) 需要计算 f(2) 和 f(1),可以看到 f(2) 被重复计算了。 18 | 19 |

20 | 21 | 递归是将一个问题划分成多个子问题求解,动态规划也是如此,但是动态规划会把子问题的解缓存起来,从而避免重复求解子问题。 22 | 23 | ```java 24 | public int Fibonacci(int n) { 25 | if (n <= 1) 26 | return n; 27 | int[] fib = new int[n + 1]; 28 | fib[1] = 1; 29 | for (int i = 2; i <= n; i++) 30 | fib[i] = fib[i - 1] + fib[i - 2]; 31 | return fib[n]; 32 | } 33 | ``` 34 | 35 | 考虑到第 i 项只与第 i-1 和第 i-2 项有关,因此只需要存储前两项的值就能求解第 i 项,从而将空间复杂度由 O(N) 降低为 O(1)。 36 | 37 | ```java 38 | public int Fibonacci(int n) { 39 | if (n <= 1) 40 | return n; 41 | int pre2 = 0, pre1 = 1; 42 | int fib = 0; 43 | for (int i = 2; i <= n; i++) { 44 | fib = pre2 + pre1; 45 | pre2 = pre1; 46 | pre1 = fib; 47 | } 48 | return fib; 49 | } 50 | ``` 51 | 52 | 由于待求解的 n 小于 40,因此可以将前 40 项的结果先进行计算,之后就能以 O(1) 时间复杂度得到第 n 项的值。 53 | 54 | ```java 55 | public class Solution { 56 | 57 | private int[] fib = new int[40]; 58 | 59 | public Solution() { 60 | fib[1] = 1; 61 | for (int i = 2; i < fib.length; i++) 62 | fib[i] = fib[i - 1] + fib[i - 2]; 63 | } 64 | 65 | public int Fibonacci(int n) { 66 | return fib[n]; 67 | } 68 | } 69 | ``` 70 | -------------------------------------------------------------------------------- /04数据结构及算法/code/10.2 矩形覆盖.md: -------------------------------------------------------------------------------- 1 | # 10.2 矩形覆盖 2 | 3 | ## 题目链接 4 | 5 | [牛客网](https://www.nowcoder.com/practice/72a5a919508a4251859fb2cfb987a0e6?tpId=13&tqId=11163&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) 6 | 7 | ## 题目描述 8 | 9 | 我们可以用 2\*1 的小矩形横着或者竖着去覆盖更大的矩形。请问用 n 个 2\*1 的小矩形无重叠地覆盖一个 2\*n 的大矩形,总共有多少种方法? 10 | 11 |

12 | 13 | ## 解题思路 14 | 15 | 当 n 为 1 时,只有一种覆盖方法: 16 | 17 |

18 | 19 | 当 n 为 2 时,有两种覆盖方法: 20 | 21 |

22 | 23 | 要覆盖 2\*n 的大矩形,可以先覆盖 2\*1 的矩形,再覆盖 2\*(n-1) 的矩形;或者先覆盖 2\*2 的矩形,再覆盖 2\*(n-2) 的矩形。而覆盖 2\*(n-1) 和 2\*(n-2) 的矩形可以看成子问题。该问题的递推公式如下: 24 | 25 | 26 | 27 |

28 | 29 | ```java 30 | public int rectCover(int n) { 31 | if (n <= 2) 32 | return n; 33 | int pre2 = 1, pre1 = 2; 34 | int result = 0; 35 | for (int i = 3; i <= n; i++) { 36 | result = pre2 + pre1; 37 | pre2 = pre1; 38 | pre1 = result; 39 | } 40 | return result; 41 | } 42 | ``` 43 | -------------------------------------------------------------------------------- /04数据结构及算法/code/10.3 跳台阶.md: -------------------------------------------------------------------------------- 1 | # 10.3 跳台阶 2 | 3 | ## 题目链接 4 | 5 | [牛客网](https://www.nowcoder.com/practice/8c82a5b80378478f9484d87d1c5f12a4?tpId=13&tqId=11161&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) 6 | 7 | ## 题目描述 8 | 9 | 一只青蛙一次可以跳上 1 级台阶,也可以跳上 2 级。求该青蛙跳上一个 n 级的台阶总共有多少种跳法。 10 | 11 |

12 | 13 | ## 解题思路 14 | 15 | 当 n = 1 时,只有一种跳法: 16 | 17 |

18 | 19 | 当 n = 2 时,有两种跳法: 20 | 21 |

22 | 23 | 跳 n 阶台阶,可以先跳 1 阶台阶,再跳 n-1 阶台阶;或者先跳 2 阶台阶,再跳 n-2 阶台阶。而 n-1 和 n-2 阶台阶的跳法可以看成子问题,该问题的递推公式为: 24 | 25 |

26 | 27 | ```java 28 | public int JumpFloor(int n) { 29 | if (n <= 2) 30 | return n; 31 | int pre2 = 1, pre1 = 2; 32 | int result = 0; 33 | for (int i = 2; i < n; i++) { 34 | result = pre2 + pre1; 35 | pre2 = pre1; 36 | pre1 = result; 37 | } 38 | return result; 39 | } 40 | ``` 41 | -------------------------------------------------------------------------------- /04数据结构及算法/code/10.4 变态跳台阶.md: -------------------------------------------------------------------------------- 1 | # 10.4 变态跳台阶 2 | 3 | ## 题目链接 4 | 5 | [牛客网](https://www.nowcoder.com/practice/22243d016f6b47f2a6928b4313c85387?tpId=13&tqId=11162&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) 6 | 7 | ## 题目描述 8 | 9 | 一只青蛙一次可以跳上 1 级台阶,也可以跳上 2 级... 它也可以跳上 n 级。求该青蛙跳上一个 n 级的台阶总共有多少种跳法。 10 | 11 |

12 | 13 | ## 解题思路 14 | 15 | ### 动态规划 16 | 17 | ```java 18 | public int jumpFloorII(int target) { 19 | int[] dp = new int[target]; 20 | Arrays.fill(dp, 1); 21 | for (int i = 1; i < target; i++) 22 | for (int j = 0; j < i; j++) 23 | dp[i] += dp[j]; 24 | return dp[target - 1]; 25 | } 26 | ``` 27 | 28 | ### 数学推导 29 | 30 | 跳上 n-1 级台阶,可以从 n-2 级跳 1 级上去,也可以从 n-3 级跳 2 级上去...,那么 31 | 32 | ``` 33 | f(n-1) = f(n-2) + f(n-3) + ... + f(0) 34 | ``` 35 | 36 | 同样,跳上 n 级台阶,可以从 n-1 级跳 1 级上去,也可以从 n-2 级跳 2 级上去... ,那么 37 | 38 | ``` 39 | f(n) = f(n-1) + f(n-2) + ... + f(0) 40 | ``` 41 | 42 | 综上可得 43 | 44 | ``` 45 | f(n) - f(n-1) = f(n-1) 46 | ``` 47 | 48 | 即 49 | 50 | ``` 51 | f(n) = 2*f(n-1) 52 | ``` 53 | 54 | 所以 f(n) 是一个等比数列 55 | 56 | ```source-java 57 | public int JumpFloorII(int target) { 58 | return (int) Math.pow(2, target - 1); 59 | } 60 | ``` 61 | -------------------------------------------------------------------------------- /04数据结构及算法/code/11. 旋转数组的最小数字.md: -------------------------------------------------------------------------------- 1 | # 11. 旋转数组的最小数字 2 | 3 | ## 题目链接 4 | 5 | [牛客网](https://www.nowcoder.com/practice/9f3231a991af4f55b95579b44b7a01ba?tpId=13&tqId=11159&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) 6 | 7 | ## 题目描述 8 | 9 | 把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。输入一个非递减排序的数组的一个旋转,输出旋转数组的最小元素。 10 | 11 |

12 | 13 | ## 解题思路 14 | 15 | 将旋转数组对半分可以得到一个包含最小元素的新旋转数组,以及一个非递减排序的数组。新的旋转数组的长度是原数组的一半,从而将问题规模减少了一半,这种折半性质的算法的时间复杂度为 O(log2N)。 16 | 17 |

18 | 19 | 此时问题的关键在于确定对半分得到的两个数组哪一个是旋转数组,哪一个是非递减数组。我们很容易知道非递减数组的第一个元素一定小于等于最后一个元素。 20 | 21 | 通过修改二分查找算法进行求解(l 代表 low,m 代表 mid,h 代表 high): 22 | 23 | - 当 nums[m] \<= nums[h] 时,表示 [m, h] 区间内的数组是非递减数组,[l, m] 区间内的数组是旋转数组,此时令 h = m; 24 | - 否则 [m + 1, h] 区间内的数组是旋转数组,令 l = m + 1。 25 | 26 | ```java 27 | public int minNumberInRotateArray(int[] nums) { 28 | if (nums.length == 0) 29 | return 0; 30 | int l = 0, h = nums.length - 1; 31 | while (l < h) { 32 | int m = l + (h - l) / 2; 33 | if (nums[m] <= nums[h]) 34 | h = m; 35 | else 36 | l = m + 1; 37 | } 38 | return nums[l]; 39 | } 40 | ``` 41 | 42 | 如果数组元素允许重复,会出现一个特殊的情况:nums[l] == nums[m] == nums[h],此时无法确定解在哪个区间,需要切换到顺序查找。例如对于数组 {1,1,1,0,1},l、m 和 h 指向的数都为 1,此时无法知道最小数字 0 在哪个区间。 43 | 44 | ```java 45 | public int minNumberInRotateArray(int[] nums) { 46 | if (nums.length == 0) 47 | return 0; 48 | int l = 0, h = nums.length - 1; 49 | while (l < h) { 50 | int m = l + (h - l) / 2; 51 | if (nums[l] == nums[m] && nums[m] == nums[h]) 52 | return minNumber(nums, l, h); 53 | else if (nums[m] <= nums[h]) 54 | h = m; 55 | else 56 | l = m + 1; 57 | } 58 | return nums[l]; 59 | } 60 | 61 | private int minNumber(int[] nums, int l, int h) { 62 | for (int i = l; i < h; i++) 63 | if (nums[i] > nums[i + 1]) 64 | return nums[i + 1]; 65 | return nums[l]; 66 | } 67 | ``` 68 | -------------------------------------------------------------------------------- /04数据结构及算法/code/13. 机器人的运动范围.md: -------------------------------------------------------------------------------- 1 | # 13. 机器人的运动范围 2 | 3 | [牛客网](https://www.nowcoder.com/practice/6e5207314b5241fb83f2329e89fdecc8?tpId=13&tqId=11219&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) 4 | 5 | ## 题目描述 6 | 7 | 地上有一个 m 行和 n 列的方格。一个机器人从坐标 (0, 0) 的格子开始移动,每一次只能向左右上下四个方向移动一格,但是不能进入行坐标和列坐标的数位之和大于 k 的格子。 8 | 9 | 例如,当 k 为 18 时,机器人能够进入方格 (35,37),因为 3+5+3+7=18。但是,它不能进入方格 (35,38),因为 3+5+3+8=19。请问该机器人能够达到多少个格子? 10 | 11 | ## 解题思路 12 | 13 | 使用深度优先搜索(Depth First Search,DFS)方法进行求解。回溯是深度优先搜索的一种特例,它在一次搜索过程中需要设置一些本次搜索过程的局部状态,并在本次搜索结束之后清除状态。而普通的深度优先搜索并不需要使用这些局部状态,虽然还是有可能设置一些全局状态。 14 | 15 | ```java 16 | private static final int[][] next = {{0, -1}, {0, 1}, {-1, 0}, {1, 0}}; 17 | private int cnt = 0; 18 | private int rows; 19 | private int cols; 20 | private int threshold; 21 | private int[][] digitSum; 22 | 23 | public int movingCount(int threshold, int rows, int cols) { 24 | this.rows = rows; 25 | this.cols = cols; 26 | this.threshold = threshold; 27 | initDigitSum(); 28 | boolean[][] marked = new boolean[rows][cols]; 29 | dfs(marked, 0, 0); 30 | return cnt; 31 | } 32 | 33 | private void dfs(boolean[][] marked, int r, int c) { 34 | if (r < 0 || r >= rows || c < 0 || c >= cols || marked[r][c]) 35 | return; 36 | marked[r][c] = true; 37 | if (this.digitSum[r][c] > this.threshold) 38 | return; 39 | cnt++; 40 | for (int[] n : next) 41 | dfs(marked, r + n[0], c + n[1]); 42 | } 43 | 44 | private void initDigitSum() { 45 | int[] digitSumOne = new int[Math.max(rows, cols)]; 46 | for (int i = 0; i < digitSumOne.length; i++) { 47 | int n = i; 48 | while (n > 0) { 49 | digitSumOne[i] += n % 10; 50 | n /= 10; 51 | } 52 | } 53 | this.digitSum = new int[rows][cols]; 54 | for (int i = 0; i < this.rows; i++) 55 | for (int j = 0; j < this.cols; j++) 56 | this.digitSum[i][j] = digitSumOne[i] + digitSumOne[j]; 57 | } 58 | ``` 59 | -------------------------------------------------------------------------------- /04数据结构及算法/code/14. 剪绳子.md: -------------------------------------------------------------------------------- 1 | # 14. 剪绳子 2 | 3 | ## 题目链接 4 | 5 | [牛客网](https://www.nowcoder.com/practice/57d85990ba5b440ab888fc72b0751bf8?tpId=13&tqId=33257&tab=answerKey&from=cyc_github) 6 | 7 | ## 题目描述 8 | 9 | 把一根绳子剪成多段,并且使得每段的长度乘积最大。 10 | 11 | ```html 12 | n = 2 13 | return 1 (2 = 1 + 1) 14 | 15 | n = 10 16 | return 36 (10 = 3 + 3 + 4) 17 | ``` 18 | 19 | ## 解题思路 20 | 21 | ### 贪心 22 | 23 | 尽可能得多剪长度为 3 的绳子,并且不允许有长度为 1 的绳子出现。如果出现了,就从已经切好长度为 3 的绳子中拿出一段与长度为 1 的绳子重新组合,把它们切成两段长度为 2 的绳子。以下为证明过程。 24 | 25 | 将绳子拆成 1 和 n-1,则 1(n-1)-n=-1\<0,即拆开后的乘积一定更小,所以不能出现长度为 1 的绳子。 26 | 27 | 将绳子拆成 2 和 n-2,则 2(n-2)-n = n-4,在 n\>=4 时这样拆开能得到的乘积会比不拆更大。 28 | 29 | 将绳子拆成 3 和 n-3,则 3(n-3)-n = 2n-9,在 n\>=5 时效果更好。 30 | 31 | 将绳子拆成 4 和 n-4,因为 4=2\*2,因此效果和拆成 2 一样。 32 | 33 | 将绳子拆成 5 和 n-5,因为 5=2+3,而 5\<2\*3,所以不能出现 5 的绳子,而是尽可能拆成 2 和 3。 34 | 35 | 将绳子拆成 6 和 n-6,因为 6=3+3,而 6\<3\*3,所以不能出现 6 的绳子,而是拆成 3 和 3。这里 6 同样可以拆成 6=2+2+2,但是 3(n - 3) - 2(n - 2) = n - 5 \>= 0,在 n\>=5 的情况下将绳子拆成 3 比拆成 2 效果更好。 36 | 37 | 继续拆成更大的绳子可以发现都比拆成 2 和 3 的效果更差,因此我们只考虑将绳子拆成 2 和 3,并且优先拆成 3,当拆到绳子长度 n 等于 4 时,也就是出现 3+1,此时只能拆成 2+2。 38 | 39 | ```java 40 | public int cutRope(int n) { 41 | if (n < 2) 42 | return 0; 43 | if (n == 2) 44 | return 1; 45 | if (n == 3) 46 | return 2; 47 | int timesOf3 = n / 3; 48 | if (n - timesOf3 * 3 == 1) 49 | timesOf3--; 50 | int timesOf2 = (n - timesOf3 * 3) / 2; 51 | return (int) (Math.pow(3, timesOf3)) * (int) (Math.pow(2, timesOf2)); 52 | } 53 | ``` 54 | 55 | ### 动态规划 56 | 57 | ```java 58 | public int cutRope(int n) { 59 | int[] dp = new int[n + 1]; 60 | dp[1] = 1; 61 | for (int i = 2; i <= n; i++) 62 | for (int j = 1; j < i; j++) 63 | dp[i] = Math.max(dp[i], Math.max(j * (i - j), dp[j] * (i - j))); 64 | return dp[n]; 65 | } 66 | ``` 67 | 68 | -------------------------------------------------------------------------------- /04数据结构及算法/code/15. 二进制中 1 的个数.md: -------------------------------------------------------------------------------- 1 | # 15. 二进制中 1 的个数 2 | 3 | ## 题目链接 4 | 5 | [牛客网](https://www.nowcoder.com/practice/8ee967e43c2c4ec193b040ea7fbb10b8?tpId=13&tqId=11164&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) 6 | 7 | ## 题目描述 8 | 9 | 输入一个整数,输出该数二进制表示中 1 的个数。 10 | 11 | ### 解题思路 12 | 13 | n&(n-1) 位运算可以将 n 的位级表示中最低的那一位 1 设置为 0。不断将 1 设置为 0,直到 n 为 0。时间复杂度:O(M),其中 M 表示 1 的个数。 14 | 15 |

16 | 17 | 18 | ```java 19 | public int NumberOf1(int n) { 20 | int cnt = 0; 21 | while (n != 0) { 22 | cnt++; 23 | n &= (n - 1); 24 | } 25 | return cnt; 26 | } 27 | ``` 28 | -------------------------------------------------------------------------------- /04数据结构及算法/code/16. 数值的整数次方.md: -------------------------------------------------------------------------------- 1 | # 16. 数值的整数次方 2 | 3 | ## 题目链接 4 | 5 | [牛客网](https://www.nowcoder.com/practice/1a834e5e3e1a4b7ba251417554e07c00?tpId=13&tqId=11165&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) 6 | 7 | ## 题目描述 8 | 9 | 给定一个 double 类型的浮点数 x和 int 类型的整数 n,求 x 的 n 次方。 10 | 11 | ## 解题思路 12 | 13 | 14 | 15 | 最直观的解法是将 x 重复乘 n 次,x\*x\*x...\*x,那么时间复杂度为 O(N)。因为乘法是可交换的,所以可以将上述操作拆开成两半 (x\*x..\*x)\* (x\*x..\*x),两半的计算是一样的,因此只需要计算一次。而且对于新拆开的计算,又可以继续拆开。这就是分治思想,将原问题的规模拆成多个规模较小的子问题,最后子问题的解合并起来。 16 | 17 | 本题中子问题是 xn/2,在将子问题合并时将子问题的解乘于自身相乘即可。但如果 n 不为偶数,那么拆成两半还会剩下一个 x,在将子问题合并时还需要需要多乘于一个 x。 18 | 19 | 20 | 21 |

22 | 23 | 24 | 因为 (x\*x)n/2 可以通过递归求解,并且每次递归 n 都减小一半,因此整个算法的时间复杂度为 O(logN)。 25 | 26 | ```java 27 | public double Power(double x, int n) { 28 | boolean isNegative = false; 29 | if (n < 0) { 30 | n = -n; 31 | isNegative = true; 32 | } 33 | double res = pow(x, n); 34 | return isNegative ? 1 / res : res; 35 | } 36 | 37 | private double pow(double x, int n) { 38 | if (n == 0) return 1; 39 | if (n == 1) return x; 40 | double res = pow(x, n / 2); 41 | res = res * res; 42 | if (n % 2 != 0) res *= x; 43 | return res; 44 | } 45 | ``` 46 | 47 | -------------------------------------------------------------------------------- /04数据结构及算法/code/17. 打印从 1 到最大的 n 位数.md: -------------------------------------------------------------------------------- 1 | # 17. 打印从 1 到最大的 n 位数 2 | 3 | ## 题目描述 4 | 5 | 输入数字 n,按顺序打印出从 1 到最大的 n 位十进制数。比如输入 3,则打印出 1、2、3 一直到最大的 3 位数即 999。 6 | 7 | ## 解题思路 8 | 9 | 由于 n 可能会非常大,因此不能直接用 int 表示数字,而是用 char 数组进行存储。 10 | 11 | 使用回溯法得到所有的数。 12 | 13 | ```java 14 | public void print1ToMaxOfNDigits(int n) { 15 | if (n <= 0) 16 | return; 17 | char[] number = new char[n]; 18 | print1ToMaxOfNDigits(number, 0); 19 | } 20 | 21 | private void print1ToMaxOfNDigits(char[] number, int digit) { 22 | if (digit == number.length) { 23 | printNumber(number); 24 | return; 25 | } 26 | for (int i = 0; i < 10; i++) { 27 | number[digit] = (char) (i + '0'); 28 | print1ToMaxOfNDigits(number, digit + 1); 29 | } 30 | } 31 | 32 | private void printNumber(char[] number) { 33 | int index = 0; 34 | while (index < number.length && number[index] == '0') 35 | index++; 36 | while (index < number.length) 37 | System.out.print(number[index++]); 38 | System.out.println(); 39 | } 40 | ``` 41 | -------------------------------------------------------------------------------- /04数据结构及算法/code/18.1 在 O(1) 时间内删除链表节点.md: -------------------------------------------------------------------------------- 1 | # 18.1 在 O(1) 时间内删除链表节点 2 | 3 | ## 解题思路 4 | 5 | ① 如果该节点不是尾节点,那么可以直接将下一个节点的值赋给该节点,然后令该节点指向下下个节点,再删除下一个节点,时间复杂度为 O(1)。 6 | 7 |

8 | 9 | ② 否则,就需要先遍历链表,找到节点的前一个节点,然后让前一个节点指向 null,时间复杂度为 O(N)。 10 | 11 |

12 | 13 | 综上,如果进行 N 次操作,那么大约需要操作节点的次数为 N-1+N=2N-1,其中 N-1 表示 N-1 个不是尾节点的每个节点以 O(1) 的时间复杂度操作节点的总次数,N 表示 1 个尾节点以 O(N) 的时间复杂度操作节点的总次数。(2N-1)/N \~ 2,因此该算法的平均时间复杂度为 O(1)。 14 | 15 | ```java 16 | public ListNode deleteNode(ListNode head, ListNode tobeDelete) { 17 | if (head == null || tobeDelete == null) 18 | return null; 19 | if (tobeDelete.next != null) { 20 | // 要删除的节点不是尾节点 21 | ListNode next = tobeDelete.next; 22 | tobeDelete.val = next.val; 23 | tobeDelete.next = next.next; 24 | } else { 25 | if (head == tobeDelete) 26 | // 只有一个节点 27 | head = null; 28 | else { 29 | ListNode cur = head; 30 | while (cur.next != tobeDelete) 31 | cur = cur.next; 32 | cur.next = null; 33 | } 34 | } 35 | return head; 36 | } 37 | ``` 38 | -------------------------------------------------------------------------------- /04数据结构及算法/code/18.2 删除链表中重复的结点.md: -------------------------------------------------------------------------------- 1 | # 18.2 删除链表中重复的结点 2 | 3 | [牛客网](https://www.nowcoder.com/practice/fc533c45b73a41b0b44ccba763f866ef?tpId=13&tqId=11209&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) 4 | 5 | ## 题目描述 6 | 7 |

8 | 9 | ## 解题描述 10 | 11 | ```java 12 | public ListNode deleteDuplication(ListNode pHead) { 13 | if (pHead == null || pHead.next == null) 14 | return pHead; 15 | ListNode next = pHead.next; 16 | if (pHead.val == next.val) { 17 | while (next != null && pHead.val == next.val) 18 | next = next.next; 19 | return deleteDuplication(next); 20 | } else { 21 | pHead.next = deleteDuplication(pHead.next); 22 | return pHead; 23 | } 24 | } 25 | ``` 26 | -------------------------------------------------------------------------------- /04数据结构及算法/code/19. 正则表达式匹配.md: -------------------------------------------------------------------------------- 1 | # 19. 正则表达式匹配 2 | 3 | [牛客网](https://www.nowcoder.com/practice/28970c15befb4ff3a264189087b99ad4?tpId=13&tqId=11205&tab=answerKey&from=cyc_github) 4 | 5 | ## 题目描述 6 | 7 | 请实现一个函数用来匹配包括 '.' 和 '\*' 的正则表达式。模式中的字符 '.' 表示任意一个字符,而 '\*' 表示它前面的字符可以出现任意次(包含 0 次)。 8 | 9 | 在本题中,匹配是指字符串的所有字符匹配整个模式。例如,字符串 "aaa" 与模式 "a.a" 和 "ab\*ac\*a" 匹配,但是与 "aa.a" 和 "ab\*a" 均不匹配。 10 | 11 | ## 解题思路 12 | 13 | 应该注意到,'.' 是用来当做一个任意字符,而 '\*' 是用来重复前面的字符。这两个的作用不同,不能把 '.' 的作用和 '\*' 进行类比,从而把它当成重复前面字符一次。 14 | 15 | ```java 16 | public boolean match(String str, String pattern) { 17 | 18 | int m = str.length(), n = pattern.length(); 19 | boolean[][] dp = new boolean[m + 1][n + 1]; 20 | 21 | dp[0][0] = true; 22 | for (int i = 1; i <= n; i++) 23 | if (pattern.charAt(i - 1) == '*') 24 | dp[0][i] = dp[0][i - 2]; 25 | 26 | for (int i = 1; i <= m; i++) 27 | for (int j = 1; j <= n; j++) 28 | if (str.charAt(i - 1) == pattern.charAt(j - 1) || pattern.charAt(j - 1) == '.') 29 | dp[i][j] = dp[i - 1][j - 1]; 30 | else if (pattern.charAt(j - 1) == '*') 31 | if (pattern.charAt(j - 2) == str.charAt(i - 1) || pattern.charAt(j - 2) == '.') { 32 | dp[i][j] |= dp[i][j - 1]; // a* counts as single a 33 | dp[i][j] |= dp[i - 1][j]; // a* counts as multiple a 34 | dp[i][j] |= dp[i][j - 2]; // a* counts as empty 35 | } else 36 | dp[i][j] = dp[i][j - 2]; // a* only counts as empty 37 | 38 | return dp[m][n]; 39 | } 40 | ``` 41 | -------------------------------------------------------------------------------- /04数据结构及算法/code/20. 表示数值的字符串.md: -------------------------------------------------------------------------------- 1 | # 20. 表示数值的字符串 2 | 3 | [牛客网](https://www.nowcoder.com/practice/e69148f8528c4039ad89bb2546fd4ff8?tpId=13&tqId=11206&tab=answerKey&from=cyc_github) 4 | 5 | ## 题目描述 6 | 7 | ``` 8 | true 9 | 10 | "+100" 11 | "5e2" 12 | "-123" 13 | "3.1416" 14 | "-1E-16" 15 | ``` 16 | 17 | ``` 18 | false 19 | 20 | "12e" 21 | "1a3.14" 22 | "1.2.3" 23 | "+-5" 24 | "12e+4.3" 25 | ``` 26 | 27 | 28 | ## 解题思路 29 | 30 | 使用正则表达式进行匹配。 31 | 32 | ```html 33 | [] : 字符集合 34 | () : 分组 35 | ? : 重复 0 ~ 1 次 36 | + : 重复 1 ~ n 次 37 | * : 重复 0 ~ n 次 38 | . : 任意字符 39 | \\. : 转义后的 . 40 | \\d : 数字 41 | ``` 42 | 43 | ```java 44 | public boolean isNumeric (String str) { 45 | if (str == null || str.length() == 0) 46 | return false; 47 | return new String(str).matches("[+-]?\\d*(\\.\\d+)?([eE][+-]?\\d+)?"); 48 | } 49 | ``` 50 | -------------------------------------------------------------------------------- /04数据结构及算法/code/21. 调整数组顺序使奇数位于偶数前面.md: -------------------------------------------------------------------------------- 1 | # 21. 调整数组顺序使奇数位于偶数前面 2 | 3 | ## 题目链接 4 | 5 | [牛客网](https://www.nowcoder.com/practice/ef1f53ef31ca408cada5093c8780f44b?tpId=13&tqId=11166&tab=answerKey&from=cyc_github) 6 | 7 | ## 题目描述 8 | 9 | 需要保证奇数和奇数,偶数和偶数之间的相对位置不变,这和书本不太一样。例如对于 [1,2,3,4,5],调整后得到 [1,3,5,2,4],而不能是 {5,1,3,4,2} 这种相对位置改变的结果。 10 | 11 |

12 | 13 | ## 解题思路 14 | 15 | 方法一:创建一个新数组,时间复杂度 O(N),空间复杂度 O(N)。 16 | 17 | ```java 18 | public int[] reOrderArray (int[] nums) { 19 | // 奇数个数 20 | int oddCnt = 0; 21 | for (int x : nums) 22 | if (!isEven(x)) 23 | oddCnt++; 24 | int[] copy = nums.clone(); 25 | int i = 0, j = oddCnt; 26 | for (int num : copy) { 27 | if (num % 2 == 1) 28 | nums[i++] = num; 29 | else 30 | nums[j++] = num; 31 | } 32 | return nums; 33 | } 34 | 35 | private boolean isEven(int x) { 36 | return x % 2 == 0; 37 | } 38 | ``` 39 | 40 | 方法二:使用冒泡思想,每次都将当前偶数上浮到当前最右边。时间复杂度 O(N2),空间复杂度 O(1),时间换空间。 41 | 42 | ```java 43 | public int[] reOrderArray(int[] nums) { 44 | int N = nums.length; 45 | for (int i = N - 1; i > 0; i--) { 46 | for (int j = 0; j < i; j++) { 47 | if (isEven(nums[j]) && !isEven(nums[j + 1])) { 48 | swap(nums, j, j + 1); 49 | } 50 | } 51 | } 52 | return nums; 53 | } 54 | 55 | private boolean isEven(int x) { 56 | return x % 2 == 0; 57 | } 58 | 59 | private void swap(int[] nums, int i, int j) { 60 | int t = nums[i]; 61 | nums[i] = nums[j]; 62 | nums[j] = t; 63 | } 64 | ``` 65 | -------------------------------------------------------------------------------- /04数据结构及算法/code/22. 链表中倒数第 K 个结点.md: -------------------------------------------------------------------------------- 1 | # 22. 链表中倒数第 K 个结点 2 | 3 | [牛客网](https://www.nowcoder.com/practice/886370fe658f41b498d40fb34ae76ff9?tpId=13&tqId=11167&tab=answerKey&from=cyc_github) 4 | 5 | ## 解题思路 6 | 7 | 设链表的长度为 N。设置两个指针 P1 和 P2,先让 P1 移动 K 个节点,则还有 N - K 个节点可以移动。此时让 P1 和 P2 同时移动,可以知道当 P1 移动到链表结尾时,P2 移动到第 N - K 个节点处,该位置就是倒数第 K 个节点。 8 | 9 |

10 | 11 | ```java 12 | public ListNode FindKthToTail(ListNode head, int k) { 13 | if (head == null) 14 | return null; 15 | ListNode P1 = head; 16 | while (P1 != null && k-- > 0) 17 | P1 = P1.next; 18 | if (k > 0) 19 | return null; 20 | ListNode P2 = head; 21 | while (P1 != null) { 22 | P1 = P1.next; 23 | P2 = P2.next; 24 | } 25 | return P2; 26 | } 27 | ``` 28 | -------------------------------------------------------------------------------- /04数据结构及算法/code/23. 链表中环的入口结点.md: -------------------------------------------------------------------------------- 1 | # 23. 链表中环的入口结点 2 | 3 | [NowCoder](https://www.nowcoder.com/practice/253d2c59ec3e4bc68da16833f79a38e4?tpId=13&tqId=11208&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) 4 | 5 | ## 题目描述 6 | 7 | 一个链表中包含环,请找出该链表的环的入口结点。要求不能使用额外的空间。 8 | 9 | ## 解题思路 10 | 11 | 使用双指针,一个快指针 fast 每次移动两个节点,一个慢指针 slow 每次移动一个节点。因为存在环,所以两个指针必定相遇在环中的某个节点上。 12 | 13 | 假设环入口节点为 y1,相遇所在节点为 z1。 14 | 15 | 假设快指针 fast 在圈内绕了 N 圈,则总路径长度为 x+Ny+(N-1)z。z 为 (N-1) 倍是因为快慢指针最后已经在 z1 节点相遇了,后面就不需要再走了。 16 | 17 | 而慢指针 slow 总路径长度为 x+y。 18 | 19 | 因为快指针是慢指针的两倍,因此 x+Ny+(N-1)z = 2(x+y)。 20 | 21 | 我们要找的是环入口节点 y1,也可以看成寻找长度 x 的值,因此我们先将上面的等值分解为和 x 有关:x=(N-2)y+(N-1)z。 22 | 23 | 上面的等值没有很强的规律,但是我们可以发现 y+z 就是圆环的总长度,因此我们将上面的等式再分解:x=(N-2)(y+z)+z。这个等式左边是从起点x1 到环入口节点 y1 的长度,而右边是在圆环中走过 (N-2) 圈,再从相遇点 z1 再走过长度为 z 的长度。此时我们可以发现如果让两个指针同时从起点 x1 和相遇点 z1 开始,每次只走过一个距离,那么最后他们会在环入口节点相遇。 24 | 25 |

26 | 27 | ```java 28 | public ListNode EntryNodeOfLoop(ListNode pHead) { 29 | if (pHead == null || pHead.next == null) 30 | return null; 31 | ListNode slow = pHead, fast = pHead; 32 | do { 33 | fast = fast.next.next; 34 | slow = slow.next; 35 | } while (slow != fast); 36 | fast = pHead; 37 | while (slow != fast) { 38 | slow = slow.next; 39 | fast = fast.next; 40 | } 41 | return slow; 42 | } 43 | ``` 44 | -------------------------------------------------------------------------------- /04数据结构及算法/code/24. 反转链表.md: -------------------------------------------------------------------------------- 1 | # 24. 反转链表 2 | 3 | [NowCoder](https://www.nowcoder.com/practice/75e878df47f24fdc9dc3e400ec6058ca?tpId=13&tqId=11168&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) 4 | 5 | ## 解题思路 6 | 7 | ### 递归 8 | 9 | ```java 10 | public ListNode ReverseList(ListNode head) { 11 | if (head == null || head.next == null) 12 | return head; 13 | ListNode next = head.next; 14 | head.next = null; 15 | ListNode newHead = ReverseList(next); 16 | next.next = head; 17 | return newHead; 18 | } 19 | ``` 20 | 21 | ### 迭代 22 | 23 | 使用头插法。 24 | 25 | ```java 26 | public ListNode ReverseList(ListNode head) { 27 | ListNode newList = new ListNode(-1); 28 | while (head != null) { 29 | ListNode next = head.next; 30 | head.next = newList.next; 31 | newList.next = head; 32 | head = next; 33 | } 34 | return newList.next; 35 | } 36 | ``` 37 | -------------------------------------------------------------------------------- /04数据结构及算法/code/25. 合并两个排序的链表.md: -------------------------------------------------------------------------------- 1 | # 25. 合并两个排序的链表 2 | 3 | [NowCoder](https://www.nowcoder.com/practice/d8b6b4358f774294a89de2a6ac4d9337?tpId=13&tqId=11169&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) 4 | 5 | ## 题目描述 6 | 7 |

8 | 9 | ## 解题思路 10 | 11 | ### 递归 12 | 13 | ```java 14 | public ListNode Merge(ListNode list1, ListNode list2) { 15 | if (list1 == null) 16 | return list2; 17 | if (list2 == null) 18 | return list1; 19 | if (list1.val <= list2.val) { 20 | list1.next = Merge(list1.next, list2); 21 | return list1; 22 | } else { 23 | list2.next = Merge(list1, list2.next); 24 | return list2; 25 | } 26 | } 27 | ``` 28 | 29 | ### 迭代 30 | 31 | ```java 32 | public ListNode Merge(ListNode list1, ListNode list2) { 33 | ListNode head = new ListNode(-1); 34 | ListNode cur = head; 35 | while (list1 != null && list2 != null) { 36 | if (list1.val <= list2.val) { 37 | cur.next = list1; 38 | list1 = list1.next; 39 | } else { 40 | cur.next = list2; 41 | list2 = list2.next; 42 | } 43 | cur = cur.next; 44 | } 45 | if (list1 != null) 46 | cur.next = list1; 47 | if (list2 != null) 48 | cur.next = list2; 49 | return head.next; 50 | } 51 | ``` 52 | -------------------------------------------------------------------------------- /04数据结构及算法/code/26. 树的子结构.md: -------------------------------------------------------------------------------- 1 | # 26. 树的子结构 2 | 3 | ## 题目链接 4 | 5 | [牛客网](https://www.nowcoder.com/practice/6e196c44c7004d15b1610b9afca8bd88?tpId=13&tqId=11170&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) 6 | 7 | ## 题目描述 8 | 9 |

10 | 11 | ## 解题思路 12 | 13 | ```java 14 | public boolean HasSubtree(TreeNode root1, TreeNode root2) { 15 | if (root1 == null || root2 == null) 16 | return false; 17 | return isSubtreeWithRoot(root1, root2) || HasSubtree(root1.left, root2) || HasSubtree(root1.right, root2); 18 | } 19 | 20 | private boolean isSubtreeWithRoot(TreeNode root1, TreeNode root2) { 21 | if (root2 == null) 22 | return true; 23 | if (root1 == null) 24 | return false; 25 | if (root1.val != root2.val) 26 | return false; 27 | return isSubtreeWithRoot(root1.left, root2.left) && isSubtreeWithRoot(root1.right, root2.right); 28 | } 29 | ``` 30 | -------------------------------------------------------------------------------- /04数据结构及算法/code/27. 二叉树的镜像.md: -------------------------------------------------------------------------------- 1 | # 27. 二叉树的镜像 2 | 3 | [牛客网](https://www.nowcoder.com/practice/a9d0ecbacef9410ca97463e4a5c83be7?tpId=13&tqId=11171&tab=answerKey&from=cyc_github) 4 | 5 | ## 题目描述 6 | 7 |

8 | 9 | ## 解题思路 10 | 11 | ```java 12 | public TreeNode Mirror(TreeNode root) { 13 | if (root == null) 14 | return root; 15 | swap(root); 16 | Mirror(root.left); 17 | Mirror(root.right); 18 | return root; 19 | } 20 | 21 | private void swap(TreeNode root) { 22 | TreeNode t = root.left; 23 | root.left = root.right; 24 | root.right = t; 25 | } 26 | ``` 27 | -------------------------------------------------------------------------------- /04数据结构及算法/code/28. 对称的二叉树.md: -------------------------------------------------------------------------------- 1 | # 28. 对称的二叉树 2 | 3 | [NowCoder](https://www.nowcoder.com/practice/ff05d44dfdb04e1d83bdbdab320efbcb?tpId=13&tqId=11211&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) 4 | 5 | ## 题目描述 6 | 7 |

8 | 9 | ## 解题思路 10 | 11 | ```java 12 | boolean isSymmetrical(TreeNode pRoot) { 13 | if (pRoot == null) 14 | return true; 15 | return isSymmetrical(pRoot.left, pRoot.right); 16 | } 17 | 18 | boolean isSymmetrical(TreeNode t1, TreeNode t2) { 19 | if (t1 == null && t2 == null) 20 | return true; 21 | if (t1 == null || t2 == null) 22 | return false; 23 | if (t1.val != t2.val) 24 | return false; 25 | return isSymmetrical(t1.left, t2.right) && isSymmetrical(t1.right, t2.left); 26 | } 27 | ``` 28 | -------------------------------------------------------------------------------- /04数据结构及算法/code/29. 顺时针打印矩阵.md: -------------------------------------------------------------------------------- 1 | # 29. 顺时针打印矩阵 2 | 3 | ## 题目链接 4 | 5 | [牛客网](https://www.nowcoder.com/practice/9b4c81a02cd34f76be2659fa0d54342a?tpId=13&tqId=11172&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) 6 | 7 | ## 题目描述 8 | 9 | 按顺时针的方向,从外到里打印矩阵的值。下图的矩阵打印结果为:1, 2, 3, 4, 8, 12, 16, 15, 14, 13, 9, 5, 6, 7, 11, 10 10 | 11 |

12 | 13 | 14 | 15 | ## 解题思路 16 | 17 | 一层一层从外到里打印,观察可知每一层打印都有相同的处理步骤,唯一不同的是上下左右的边界不同了。因此使用四个变量 r1, r2, c1, c2 分别存储上下左右边界值,从而定义当前最外层。打印当前最外层的顺序:从左到右打印最上一行-\>从上到下打印最右一行-\>从右到左打印最下一行-\>从下到上打印最左一行。应当注意只有在 r1 != r2 时才打印最下一行,也就是在当前最外层的行数大于 1 时才打印最下一行,这是因为当前最外层只有一行时,继续打印最下一行,会导致重复打印。打印最左一行也要做同样处理。 18 | 19 |

20 | 21 | ```java 22 | public ArrayList printMatrix(int[][] matrix) { 23 | ArrayList ret = new ArrayList<>(); 24 | int r1 = 0, r2 = matrix.length - 1, c1 = 0, c2 = matrix[0].length - 1; 25 | while (r1 <= r2 && c1 <= c2) { 26 | // 上 27 | for (int i = c1; i <= c2; i++) 28 | ret.add(matrix[r1][i]); 29 | // 右 30 | for (int i = r1 + 1; i <= r2; i++) 31 | ret.add(matrix[i][c2]); 32 | if (r1 != r2) 33 | // 下 34 | for (int i = c2 - 1; i >= c1; i--) 35 | ret.add(matrix[r2][i]); 36 | if (c1 != c2) 37 | // 左 38 | for (int i = r2 - 1; i > r1; i--) 39 | ret.add(matrix[i][c1]); 40 | r1++; r2--; c1++; c2--; 41 | } 42 | return ret; 43 | } 44 | ``` 45 | -------------------------------------------------------------------------------- /04数据结构及算法/code/3. 数组中重复的数字.md: -------------------------------------------------------------------------------- 1 | # 3. 数组中重复的数字 2 | 3 | ## 题目链接 4 | 5 | [牛客网](https://www.nowcoder.com/practice/6fe361ede7e54db1b84adc81d09d8524?tpId=13&tqId=11203&tab=answerKey&from=cyc_github) 6 | 7 | ## 题目描述 8 | 9 | 在一个长度为 n 的数组里的所有数字都在 0 到 n-1 的范围内。数组中某些数字是重复的,但不知道有几个数字是重复的,也不知道每个数字重复几次。请找出数组中任意一个重复的数字。 10 | 11 | ```html 12 | Input: 13 | {2, 3, 1, 0, 2, 5} 14 | 15 | Output: 16 | 2 17 | ``` 18 | 19 | ## 解题思路 20 | 21 | 要求时间复杂度 O(N),空间复杂度 O(1)。因此不能使用排序的方法,也不能使用额外的标记数组。 22 | 23 | 对于这种数组元素在 [0, n-1] 范围内的问题,可以将值为 i 的元素调整到第 i 个位置上进行求解。在调整过程中,如果第 i 位置上已经有一个值为 i 的元素,就可以知道 i 值重复。 24 | 25 | 以 (2, 3, 1, 0, 2, 5) 为例,遍历到位置 4 时,该位置上的数为 2,但是第 2 个位置上已经有一个 2 的值了,因此可以知道 2 重复: 26 | 27 |

28 | 29 | 30 | ```java 31 | public int duplicate(int[] nums) { 32 | for (int i = 0; i < nums.length; i++) { 33 | while (nums[i] != i) { 34 | if (nums[i] == nums[nums[i]]) { 35 | return nums[i]; 36 | } 37 | swap(nums, i, nums[i]); 38 | } 39 | swap(nums, i, nums[i]); 40 | } 41 | return -1; 42 | } 43 | 44 | private void swap(int[] nums, int i, int j) { 45 | int t = nums[i]; 46 | nums[i] = nums[j]; 47 | nums[j] = t; 48 | } 49 | 50 | ``` 51 | 52 | -------------------------------------------------------------------------------- /04数据结构及算法/code/30. 包含 min 函数的栈.md: -------------------------------------------------------------------------------- 1 | # 30. 包含 min 函数的栈 2 | 3 | ## 题目链接 4 | 5 | [牛客网](https://www.nowcoder.com/practice/4c776177d2c04c2494f2555c9fcc1e49?tpId=13&tqId=11173&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) 6 | 7 | ## 题目描述 8 | 9 | 实现一个包含 min() 函数的栈,该方法返回当前栈中最小的值。 10 | 11 | ## 解题思路 12 | 13 | 使用一个额外的 minStack,栈顶元素为当前栈中最小的值。在对栈进行 push 入栈和 pop 出栈操作时,同样需要对 minStack 进行入栈出栈操作,从而使 minStack 栈顶元素一直为当前栈中最小的值。在进行 push 操作时,需要比较入栈元素和当前栈中最小值,将值较小的元素 push 到 minStack 中。 14 | 15 |

16 | 17 | ```java 18 | private Stack dataStack = new Stack<>(); 19 | private Stack minStack = new Stack<>(); 20 | 21 | public void push(int node) { 22 | dataStack.push(node); 23 | minStack.push(minStack.isEmpty() ? node : Math.min(minStack.peek(), node)); 24 | } 25 | 26 | public void pop() { 27 | dataStack.pop(); 28 | minStack.pop(); 29 | } 30 | 31 | public int top() { 32 | return dataStack.peek(); 33 | } 34 | 35 | public int min() { 36 | return minStack.peek(); 37 | } 38 | ``` 39 | -------------------------------------------------------------------------------- /04数据结构及算法/code/31. 栈的压入、弹出序列.md: -------------------------------------------------------------------------------- 1 | # 31. 栈的压入、弹出序列 2 | 3 | ## 题目链接 4 | 5 | [牛客网](https://www.nowcoder.com/practice/d77d11405cc7470d82554cb392585106?tpId=13&tqId=11174&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) 6 | 7 | ## 题目描述 8 | 9 | 输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否为该栈的弹出顺序。假设压入栈的所有数字均不相等。 10 | 11 | 例如序列 1,2,3,4,5 是某栈的压入顺序,序列 4,5,3,2,1 是该压栈序列对应的一个弹出序列,但 4,3,5,1,2 就不可能是该压栈序列的弹出序列。 12 | 13 | ## 解题思路 14 | 15 | 使用一个栈来模拟压入弹出操作。每次入栈一个元素后,都要判断一下栈顶元素是不是当前出栈序列 popSequence 的第一个元素,如果是的话则执行出栈操作并将 popSequence 往后移一位,继续进行判断。 16 | 17 | ```java 18 | public boolean IsPopOrder(int[] pushSequence, int[] popSequence) { 19 | int n = pushSequence.length; 20 | Stack stack = new Stack<>(); 21 | for (int pushIndex = 0, popIndex = 0; pushIndex < n; pushIndex++) { 22 | stack.push(pushSequence[pushIndex]); 23 | while (popIndex < n && !stack.isEmpty() 24 | && stack.peek() == popSequence[popIndex]) { 25 | stack.pop(); 26 | popIndex++; 27 | } 28 | } 29 | return stack.isEmpty(); 30 | } 31 | ``` 32 | 33 | -------------------------------------------------------------------------------- /04数据结构及算法/code/32.1 从上往下打印二叉树.md: -------------------------------------------------------------------------------- 1 | # 32.1 从上往下打印二叉树 2 | 3 | [NowCoder](https://www.nowcoder.com/practice/7fe2212963db4790b57431d9ed259701?tpId=13&tqId=11175&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) 4 | 5 | ## 题目描述 6 | 7 | 从上往下打印出二叉树的每个节点,同层节点从左至右打印。 8 | 9 | 例如,以下二叉树层次遍历的结果为:1,2,3,4,5,6,7 10 | 11 |

12 | 13 | ## 解题思路 14 | 15 | 使用队列来进行层次遍历。 16 | 17 | 不需要使用两个队列分别存储当前层的节点和下一层的节点,因为在开始遍历一层的节点时,当前队列中的节点数就是当前层的节点数,只要控制遍历这么多节点数,就能保证这次遍历的都是当前层的节点。 18 | 19 | ```java 20 | public ArrayList PrintFromTopToBottom(TreeNode root) { 21 | Queue queue = new LinkedList<>(); 22 | ArrayList ret = new ArrayList<>(); 23 | queue.add(root); 24 | while (!queue.isEmpty()) { 25 | int cnt = queue.size(); 26 | while (cnt-- > 0) { 27 | TreeNode t = queue.poll(); 28 | if (t == null) 29 | continue; 30 | ret.add(t.val); 31 | queue.add(t.left); 32 | queue.add(t.right); 33 | } 34 | } 35 | return ret; 36 | } 37 | ``` 38 | -------------------------------------------------------------------------------- /04数据结构及算法/code/32.2 把二叉树打印成多行.md: -------------------------------------------------------------------------------- 1 | # 32.2 把二叉树打印成多行 2 | 3 | [NowCoder](https://www.nowcoder.com/practice/445c44d982d04483b04a54f298796288?tpId=13&tqId=11213&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) 4 | 5 | ## 题目描述 6 | 7 | 和上题几乎一样。 8 | 9 | ## 解题思路 10 | 11 | ```java 12 | ArrayList> Print(TreeNode pRoot) { 13 | ArrayList> ret = new ArrayList<>(); 14 | Queue queue = new LinkedList<>(); 15 | queue.add(pRoot); 16 | while (!queue.isEmpty()) { 17 | ArrayList list = new ArrayList<>(); 18 | int cnt = queue.size(); 19 | while (cnt-- > 0) { 20 | TreeNode node = queue.poll(); 21 | if (node == null) 22 | continue; 23 | list.add(node.val); 24 | queue.add(node.left); 25 | queue.add(node.right); 26 | } 27 | if (list.size() != 0) 28 | ret.add(list); 29 | } 30 | return ret; 31 | } 32 | ``` 33 | -------------------------------------------------------------------------------- /04数据结构及算法/code/32.3 按之字形顺序打印二叉树.md: -------------------------------------------------------------------------------- 1 | # 32.3 按之字形顺序打印二叉树 2 | 3 | [NowCoder](https://www.nowcoder.com/practice/91b69814117f4e8097390d107d2efbe0?tpId=13&tqId=11212&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) 4 | 5 | ## 题目描述 6 | 7 | 请实现一个函数按照之字形打印二叉树,即第一行按照从左到右的顺序打印,第二层按照从右至左的顺序打印,第三行按照从左到右的顺序打印,其他行以此类推。 8 | 9 | ## 解题思路 10 | 11 | ```java 12 | public ArrayList> Print(TreeNode pRoot) { 13 | ArrayList> ret = new ArrayList<>(); 14 | Queue queue = new LinkedList<>(); 15 | queue.add(pRoot); 16 | boolean reverse = false; 17 | while (!queue.isEmpty()) { 18 | ArrayList list = new ArrayList<>(); 19 | int cnt = queue.size(); 20 | while (cnt-- > 0) { 21 | TreeNode node = queue.poll(); 22 | if (node == null) 23 | continue; 24 | list.add(node.val); 25 | queue.add(node.left); 26 | queue.add(node.right); 27 | } 28 | if (reverse) 29 | Collections.reverse(list); 30 | reverse = !reverse; 31 | if (list.size() != 0) 32 | ret.add(list); 33 | } 34 | return ret; 35 | } 36 | ``` 37 | -------------------------------------------------------------------------------- /04数据结构及算法/code/33. 二叉搜索树的后序遍历序列.md: -------------------------------------------------------------------------------- 1 | # 33. 二叉搜索树的后序遍历序列 2 | 3 | [NowCoder](https://www.nowcoder.com/practice/a861533d45854474ac791d90e447bafd?tpId=13&tqId=11176&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) 4 | 5 | ## 题目描述 6 | 7 | 输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。假设输入的数组的任意两个数字都互不相同。 8 | 9 | 例如,下图是后序遍历序列 1,3,2 所对应的二叉搜索树。 10 | 11 |

12 | 13 | ## 解题思路 14 | 15 | ```java 16 | public boolean VerifySquenceOfBST(int[] sequence) { 17 | if (sequence == null || sequence.length == 0) 18 | return false; 19 | return verify(sequence, 0, sequence.length - 1); 20 | } 21 | 22 | private boolean verify(int[] sequence, int first, int last) { 23 | if (last - first <= 1) 24 | return true; 25 | int rootVal = sequence[last]; 26 | int cutIndex = first; 27 | while (cutIndex < last && sequence[cutIndex] <= rootVal) 28 | cutIndex++; 29 | for (int i = cutIndex; i < last; i++) 30 | if (sequence[i] < rootVal) 31 | return false; 32 | return verify(sequence, first, cutIndex - 1) && verify(sequence, cutIndex, last - 1); 33 | } 34 | ``` 35 | -------------------------------------------------------------------------------- /04数据结构及算法/code/34. 二叉树中和为某一值的路径.md: -------------------------------------------------------------------------------- 1 | # 34. 二叉树中和为某一值的路径 2 | 3 | [NowCoder](https://www.nowcoder.com/practice/b736e784e3e34731af99065031301bca?tpId=13&tqId=11177&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) 4 | 5 | ## 题目描述 6 | 7 | 输入一颗二叉树和一个整数,打印出二叉树中结点值的和为输入整数的所有路径。路径定义为从树的根结点开始往下一直到叶结点所经过的结点形成一条路径。 8 | 9 | 下图的二叉树有两条和为 22 的路径:10, 5, 7 和 10, 12 10 | 11 |

12 | 13 | ## 解题思路 14 | 15 | ```java 16 | private ArrayList> ret = new ArrayList<>(); 17 | 18 | public ArrayList> FindPath(TreeNode root, int target) { 19 | backtracking(root, target, new ArrayList<>()); 20 | return ret; 21 | } 22 | 23 | private void backtracking(TreeNode node, int target, ArrayList path) { 24 | if (node == null) 25 | return; 26 | path.add(node.val); 27 | target -= node.val; 28 | if (target == 0 && node.left == null && node.right == null) { 29 | ret.add(new ArrayList<>(path)); 30 | } else { 31 | backtracking(node.left, target, path); 32 | backtracking(node.right, target, path); 33 | } 34 | path.remove(path.size() - 1); 35 | } 36 | ``` 37 | -------------------------------------------------------------------------------- /04数据结构及算法/code/35. 复杂链表的复制.md: -------------------------------------------------------------------------------- 1 | # 35. 复杂链表的复制 2 | 3 | [NowCoder](https://www.nowcoder.com/practice/f836b2c43afc4b35ad6adc41ec941dba?tpId=13&tqId=11178&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) 4 | 5 | ## 题目描述 6 | 7 | 输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的 head。 8 | 9 | ```java 10 | public class RandomListNode { 11 | int label; 12 | RandomListNode next = null; 13 | RandomListNode random = null; 14 | 15 | RandomListNode(int label) { 16 | this.label = label; 17 | } 18 | } 19 | ``` 20 | 21 |

22 | 23 | ## 解题思路 24 | 25 | 第一步,在每个节点的后面插入复制的节点。 26 | 27 |

28 | 29 | 第二步,对复制节点的 random 链接进行赋值。 30 | 31 |

32 | 33 | 第三步,拆分。 34 | 35 |

36 | 37 | ```java 38 | public RandomListNode Clone(RandomListNode pHead) { 39 | if (pHead == null) 40 | return null; 41 | // 插入新节点 42 | RandomListNode cur = pHead; 43 | while (cur != null) { 44 | RandomListNode clone = new RandomListNode(cur.label); 45 | clone.next = cur.next; 46 | cur.next = clone; 47 | cur = clone.next; 48 | } 49 | // 建立 random 链接 50 | cur = pHead; 51 | while (cur != null) { 52 | RandomListNode clone = cur.next; 53 | if (cur.random != null) 54 | clone.random = cur.random.next; 55 | cur = clone.next; 56 | } 57 | // 拆分 58 | cur = pHead; 59 | RandomListNode pCloneHead = pHead.next; 60 | while (cur.next != null) { 61 | RandomListNode next = cur.next; 62 | cur.next = next.next; 63 | cur = next; 64 | } 65 | return pCloneHead; 66 | } 67 | ``` 68 | -------------------------------------------------------------------------------- /04数据结构及算法/code/36. 二叉搜索树与双向链表.md: -------------------------------------------------------------------------------- 1 | # 36. 二叉搜索树与双向链表 2 | 3 | [NowCoder](https://www.nowcoder.com/practice/947f6eb80d944a84850b0538bf0ec3a5?tpId=13&tqId=11179&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) 4 | 5 | ## 题目描述 6 | 7 | 输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向。 8 | 9 |

10 | 11 | ## 解题思路 12 | 13 | ```java 14 | private TreeNode pre = null; 15 | private TreeNode head = null; 16 | 17 | public TreeNode Convert(TreeNode root) { 18 | inOrder(root); 19 | return head; 20 | } 21 | 22 | private void inOrder(TreeNode node) { 23 | if (node == null) 24 | return; 25 | inOrder(node.left); 26 | node.left = pre; 27 | if (pre != null) 28 | pre.right = node; 29 | pre = node; 30 | if (head == null) 31 | head = node; 32 | inOrder(node.right); 33 | } 34 | ``` 35 | -------------------------------------------------------------------------------- /04数据结构及算法/code/37. 序列化二叉树.md: -------------------------------------------------------------------------------- 1 | # 37. 序列化二叉树 2 | 3 | [NowCoder](https://www.nowcoder.com/practice/cf7e25aa97c04cc1a68c8f040e71fb84?tpId=13&tqId=11214&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) 4 | 5 | ## 题目描述 6 | 7 | 请实现两个函数,分别用来序列化和反序列化二叉树。 8 | 9 | ## 解题思路 10 | 11 | ```java 12 | private String deserializeStr; 13 | 14 | public String Serialize(TreeNode root) { 15 | if (root == null) 16 | return "#"; 17 | return root.val + " " + Serialize(root.left) + " " + Serialize(root.right); 18 | } 19 | 20 | public TreeNode Deserialize(String str) { 21 | deserializeStr = str; 22 | return Deserialize(); 23 | } 24 | 25 | private TreeNode Deserialize() { 26 | if (deserializeStr.length() == 0) 27 | return null; 28 | int index = deserializeStr.indexOf(" "); 29 | String node = index == -1 ? deserializeStr : deserializeStr.substring(0, index); 30 | deserializeStr = index == -1 ? "" : deserializeStr.substring(index + 1); 31 | if (node.equals("#")) 32 | return null; 33 | int val = Integer.valueOf(node); 34 | TreeNode t = new TreeNode(val); 35 | t.left = Deserialize(); 36 | t.right = Deserialize(); 37 | return t; 38 | } 39 | ``` 40 | -------------------------------------------------------------------------------- /04数据结构及算法/code/38. 字符串的排列.md: -------------------------------------------------------------------------------- 1 | # 38. 字符串的排列 2 | 3 | [NowCoder](https://www.nowcoder.com/practice/fe6b651b66ae47d7acce78ffdd9a96c7?tpId=13&tqId=11180&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) 4 | 5 | ## 题目描述 6 | 7 | 输入一个字符串,按字典序打印出该字符串中字符的所有排列。例如输入字符串 abc,则打印出由字符 a, b, c 所能排列出来的所有字符串 abc, acb, bac, bca, cab 和 cba。 8 | 9 | ## 解题思路 10 | 11 | ```java 12 | private ArrayList ret = new ArrayList<>(); 13 | 14 | public ArrayList Permutation(String str) { 15 | if (str.length() == 0) 16 | return ret; 17 | char[] chars = str.toCharArray(); 18 | Arrays.sort(chars); 19 | backtracking(chars, new boolean[chars.length], new StringBuilder()); 20 | return ret; 21 | } 22 | 23 | private void backtracking(char[] chars, boolean[] hasUsed, StringBuilder s) { 24 | if (s.length() == chars.length) { 25 | ret.add(s.toString()); 26 | return; 27 | } 28 | for (int i = 0; i < chars.length; i++) { 29 | if (hasUsed[i]) 30 | continue; 31 | if (i != 0 && chars[i] == chars[i - 1] && !hasUsed[i - 1]) /* 保证不重复 */ 32 | continue; 33 | hasUsed[i] = true; 34 | s.append(chars[i]); 35 | backtracking(chars, hasUsed, s); 36 | s.deleteCharAt(s.length() - 1); 37 | hasUsed[i] = false; 38 | } 39 | } 40 | ``` 41 | -------------------------------------------------------------------------------- /04数据结构及算法/code/39. 数组中出现次数超过一半的数字.md: -------------------------------------------------------------------------------- 1 | # 39. 数组中出现次数超过一半的数字 2 | 3 | [NowCoder](https://www.nowcoder.com/practice/e8a1b01a2df14cb2b228b30ee6a92163?tpId=13&tqId=11181&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) 4 | 5 | ## 解题思路 6 | 7 | 多数投票问题,可以利用 Boyer-Moore Majority Vote Algorithm 来解决这个问题,使得时间复杂度为 O(N)。 8 | 9 | 使用 cnt 来统计一个元素出现的次数,当遍历到的元素和统计元素相等时,令 cnt++,否则令 cnt--。如果前面查找了 i 个元素,且 cnt == 0,说明前 i 个元素没有 majority,或者有 majority,但是出现的次数少于 i / 2 ,因为如果多于 i / 2 的话 cnt 就一定不会为 0 。此时剩下的 n - i 个元素中,majority 的数目依然多于 (n - i) / 2,因此继续查找就能找出 majority。 10 | 11 | ```java 12 | public int MoreThanHalfNum_Solution(int[] nums) { 13 | int majority = nums[0]; 14 | for (int i = 1, cnt = 1; i < nums.length; i++) { 15 | cnt = nums[i] == majority ? cnt + 1 : cnt - 1; 16 | if (cnt == 0) { 17 | majority = nums[i]; 18 | cnt = 1; 19 | } 20 | } 21 | int cnt = 0; 22 | for (int val : nums) 23 | if (val == majority) 24 | cnt++; 25 | return cnt > nums.length / 2 ? majority : 0; 26 | } 27 | ``` 28 | -------------------------------------------------------------------------------- /04数据结构及算法/code/4. 二维数组中的查找.md: -------------------------------------------------------------------------------- 1 | # 4. 二维数组中的查找 2 | 3 | ## 题目链接 4 | 5 | [牛客网](https://www.nowcoder.com/practice/abc3fe2ce8e146608e868a70efebf62e?tpId=13&tqId=11154&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) 6 | 7 | ## 题目描述 8 | 9 | 给定一个二维数组,其每一行从左到右递增排序,从上到下也是递增排序。给定一个数,判断这个数是否在该二维数组中。 10 | 11 | ```html 12 | Consider the following matrix: 13 | [ 14 | [1, 4, 7, 11, 15], 15 | [2, 5, 8, 12, 19], 16 | [3, 6, 9, 16, 22], 17 | [10, 13, 14, 17, 24], 18 | [18, 21, 23, 26, 30] 19 | ] 20 | 21 | Given target = 5, return true. 22 | Given target = 20, return false. 23 | ``` 24 | 25 | ## 解题思路 26 | 27 | 要求时间复杂度 O(M + N),空间复杂度 O(1)。其中 M 为行数,N 为 列数。 28 | 29 | 该二维数组中的一个数,小于它的数一定在其左边,大于它的数一定在其下边。因此,从右上角开始查找,就可以根据 target 和当前元素的大小关系来快速地缩小查找区间,每次减少一行或者一列的元素。当前元素的查找区间为左下角的所有元素。 30 | 31 |

32 | 33 | ```java 34 | public boolean Find(int target, int[][] matrix) { 35 | if (matrix == null || matrix.length == 0 || matrix[0].length == 0) 36 | return false; 37 | int rows = matrix.length, cols = matrix[0].length; 38 | int r = 0, c = cols - 1; // 从右上角开始 39 | while (r <= rows - 1 && c >= 0) { 40 | if (target == matrix[r][c]) 41 | return true; 42 | else if (target > matrix[r][c]) 43 | r++; 44 | else 45 | c--; 46 | } 47 | return false; 48 | } 49 | ``` 50 | -------------------------------------------------------------------------------- /04数据结构及算法/code/41.1 数据流中的中位数.md: -------------------------------------------------------------------------------- 1 | # 41.1 数据流中的中位数 2 | 3 | ## 题目链接 4 | 5 | [牛客网](https://www.nowcoder.com/practice/9be0172896bd43948f8a32fb954e1be1?tpId=13&tqId=11216&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) 6 | 7 | ## 题目描述 8 | 9 | 如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值。如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值。 10 | 11 | ## 解题思路 12 | 13 | ```java 14 | /* 大顶堆,存储左半边元素 */ 15 | private PriorityQueue left = new PriorityQueue<>((o1, o2) -> o2 - o1); 16 | /* 小顶堆,存储右半边元素,并且右半边元素都大于左半边 */ 17 | private PriorityQueue right = new PriorityQueue<>(); 18 | /* 当前数据流读入的元素个数 */ 19 | private int N = 0; 20 | 21 | public void Insert(Integer val) { 22 | /* 插入要保证两个堆存于平衡状态 */ 23 | if (N % 2 == 0) { 24 | /* N 为偶数的情况下插入到右半边。 25 | * 因为右半边元素都要大于左半边,但是新插入的元素不一定比左半边元素来的大, 26 | * 因此需要先将元素插入左半边,然后利用左半边为大顶堆的特点,取出堆顶元素即为最大元素,此时插入右半边 */ 27 | left.add(val); 28 | right.add(left.poll()); 29 | } else { 30 | right.add(val); 31 | left.add(right.poll()); 32 | } 33 | N++; 34 | } 35 | 36 | public Double GetMedian() { 37 | if (N % 2 == 0) 38 | return (left.peek() + right.peek()) / 2.0; 39 | else 40 | return (double) right.peek(); 41 | } 42 | ``` 43 | -------------------------------------------------------------------------------- /04数据结构及算法/code/41.2 字符流中第一个不重复的字符.md: -------------------------------------------------------------------------------- 1 | # 41.2 字符流中第一个不重复的字符 2 | 3 | ## 题目描述 4 | 5 | [牛客网](https://www.nowcoder.com/practice/00de97733b8e4f97a3fb5c680ee10720?tpId=13&tqId=11207&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) 6 | 7 | ## 题目描述 8 | 9 | 请实现一个函数用来找出字符流中第一个只出现一次的字符。例如,当从字符流中只读出前两个字符 "go" 时,第一个只出现一次的字符是 "g"。当从该字符流中读出前六个字符“google" 时,第一个只出现一次的字符是 "l"。 10 | 11 | ## 解题思路 12 | 13 | 使用统计数组来统计每个字符出现的次数,本题涉及到的字符为都为 ASCII 码,因此使用一个大小为 128 的整型数组就能完成次数统计任务。 14 | 15 | 使用队列来存储到达的字符,并在每次有新的字符从字符流到达时移除队列头部那些出现次数不再是一次的元素。因为队列是先进先出顺序,因此队列头部的元素为第一次只出现一次的字符。 16 | 17 | ```java 18 | private int[] cnts = new int[128]; 19 | private Queue queue = new LinkedList<>(); 20 | 21 | public void Insert(char ch) { 22 | cnts[ch]++; 23 | queue.add(ch); 24 | while (!queue.isEmpty() && cnts[queue.peek()] > 1) 25 | queue.poll(); 26 | } 27 | 28 | public char FirstAppearingOnce() { 29 | return queue.isEmpty() ? '#' : queue.peek(); 30 | } 31 | ``` 32 | -------------------------------------------------------------------------------- /04数据结构及算法/code/42. 连续子数组的最大和.md: -------------------------------------------------------------------------------- 1 | # 42. 连续子数组的最大和 2 | 3 | [NowCoder](https://www.nowcoder.com/practice/459bd355da1549fa8a49e350bf3df484?tpId=13&tqId=11183&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) 4 | 5 | ## 题目描述 6 | 7 | {6, -3, -2, 7, -15, 1, 2, 2},连续子数组的最大和为 8(从第 0 个开始,到第 3 个为止)。 8 | 9 | ## 解题思路 10 | 11 | ```java 12 | public int FindGreatestSumOfSubArray(int[] nums) { 13 | if (nums == null || nums.length == 0) 14 | return 0; 15 | int greatestSum = Integer.MIN_VALUE; 16 | int sum = 0; 17 | for (int val : nums) { 18 | sum = sum <= 0 ? val : sum + val; 19 | greatestSum = Math.max(greatestSum, sum); 20 | } 21 | return greatestSum; 22 | } 23 | ``` 24 | 25 | -------------------------------------------------------------------------------- /04数据结构及算法/code/43. 从 1 到 n 整数中 1 出现的次数.md: -------------------------------------------------------------------------------- 1 | # 43. 从 1 到 n 整数中 1 出现的次数 2 | 3 | [NowCoder](https://www.nowcoder.com/practice/bd7f978302044eee894445e244c7eee6?tpId=13&tqId=11184&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) 4 | 5 | ## 解题思路 6 | 7 | ```java 8 | public int NumberOf1Between1AndN_Solution(int n) { 9 | int cnt = 0; 10 | for (int m = 1; m <= n; m *= 10) { 11 | int a = n / m, b = n % m; 12 | cnt += (a + 8) / 10 * m + (a % 10 == 1 ? b + 1 : 0); 13 | } 14 | return cnt; 15 | } 16 | ``` 17 | 18 | > [Leetcode : 233. Number of Digit One](https://leetcode.com/problems/number-of-digit-one/discuss/64381/4+-lines-O(log-n)-C++JavaPython) 19 | -------------------------------------------------------------------------------- /04数据结构及算法/code/44. 数字序列中的某一位数字.md: -------------------------------------------------------------------------------- 1 | # 44. 数字序列中的某一位数字 2 | 3 | ## 题目描述 4 | 5 | 数字以 0123456789101112131415... 的格式序列化到一个字符串中,求这个字符串的第 index 位。 6 | 7 | ## 解题思路 8 | 9 | ```java 10 | public int getDigitAtIndex(int index) { 11 | if (index < 0) 12 | return -1; 13 | int place = 1; // 1 表示个位,2 表示 十位... 14 | while (true) { 15 | int amount = getAmountOfPlace(place); 16 | int totalAmount = amount * place; 17 | if (index < totalAmount) 18 | return getDigitAtIndex(index, place); 19 | index -= totalAmount; 20 | place++; 21 | } 22 | } 23 | 24 | /** 25 | * place 位数的数字组成的字符串长度 26 | * 10, 90, 900, ... 27 | */ 28 | private int getAmountOfPlace(int place) { 29 | if (place == 1) 30 | return 10; 31 | return (int) Math.pow(10, place - 1) * 9; 32 | } 33 | 34 | /** 35 | * place 位数的起始数字 36 | * 0, 10, 100, ... 37 | */ 38 | private int getBeginNumberOfPlace(int place) { 39 | if (place == 1) 40 | return 0; 41 | return (int) Math.pow(10, place - 1); 42 | } 43 | 44 | /** 45 | * 在 place 位数组成的字符串中,第 index 个数 46 | */ 47 | private int getDigitAtIndex(int index, int place) { 48 | int beginNumber = getBeginNumberOfPlace(place); 49 | int shiftNumber = index / place; 50 | String number = (beginNumber + shiftNumber) + ""; 51 | int count = index % place; 52 | return number.charAt(count) - '0'; 53 | } 54 | ``` 55 | -------------------------------------------------------------------------------- /04数据结构及算法/code/45. 把数组排成最小的数.md: -------------------------------------------------------------------------------- 1 | # 45. 把数组排成最小的数 2 | 3 | ## 题目链接 4 | 5 | [牛客网](https://www.nowcoder.com/practice/8fecd3f8ba334add803bf2a06af1b993?tpId=13&tqId=11185&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) 6 | 7 | ## 题目描述 8 | 9 | 输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。例如输入数组 {3,32,321},则打印出这三个数字能排成的最小数字为 321323。 10 | 11 | ## 解题思路 12 | 13 | 可以看成是一个排序问题,在比较两个字符串 S1 和 S2 的大小时,应该比较的是 S1+S2 和 S2+S1 的大小,如果 S1+S2 \< S2+S1,那么应该把 S1 排在前面,否则应该把 S2 排在前面。 14 | 15 | ```java 16 | public String PrintMinNumber(int[] numbers) { 17 | if (numbers == null || numbers.length == 0) 18 | return ""; 19 | int n = numbers.length; 20 | String[] nums = new String[n]; 21 | for (int i = 0; i < n; i++) 22 | nums[i] = numbers[i] + ""; 23 | Arrays.sort(nums, (s1, s2) -> (s1 + s2).compareTo(s2 + s1)); 24 | String ret = ""; 25 | for (String str : nums) 26 | ret += str; 27 | return ret; 28 | } 29 | ``` 30 | -------------------------------------------------------------------------------- /04数据结构及算法/code/46. 把数字翻译成字符串.md: -------------------------------------------------------------------------------- 1 | # 46. 把数字翻译成字符串 2 | 3 | [Leetcode](https://leetcode.com/problems/decode-ways/description/) 4 | 5 | ## 题目描述 6 | 7 | 给定一个数字,按照如下规则翻译成字符串:1 翻译成“a”,2 翻译成“b”... 26 翻译成“z”。一个数字有多种翻译可能,例如 12258 一共有 5 种,分别是 abbeh,lbeh,aveh,abyh,lyh。实现一个函数,用来计算一个数字有多少种不同的翻译方法。 8 | 9 | ## 解题思路 10 | 11 | ```java 12 | public int numDecodings(String s) { 13 | if (s == null || s.length() == 0) 14 | return 0; 15 | int n = s.length(); 16 | int[] dp = new int[n + 1]; 17 | dp[0] = 1; 18 | dp[1] = s.charAt(0) == '0' ? 0 : 1; 19 | for (int i = 2; i <= n; i++) { 20 | int one = Integer.valueOf(s.substring(i - 1, i)); 21 | if (one != 0) 22 | dp[i] += dp[i - 1]; 23 | if (s.charAt(i - 2) == '0') 24 | continue; 25 | int two = Integer.valueOf(s.substring(i - 2, i)); 26 | if (two <= 26) 27 | dp[i] += dp[i - 2]; 28 | } 29 | return dp[n]; 30 | } 31 | ``` 32 | -------------------------------------------------------------------------------- /04数据结构及算法/code/47. 礼物的最大价值.md: -------------------------------------------------------------------------------- 1 | # 47. 礼物的最大价值 2 | 3 | [NowCoder](https://www.nowcoder.com/questionTerminal/72a99e28381a407991f2c96d8cb238ab) 4 | 5 | ## 题目描述 6 | 7 | 在一个 m\*n 的棋盘的每一个格都放有一个礼物,每个礼物都有一定价值(大于 0)。从左上角开始拿礼物,每次向右或向下移动一格,直到右下角结束。给定一个棋盘,求拿到礼物的最大价值。例如,对于如下棋盘 8 | 9 | ``` 10 | 1 10 3 8 11 | 12 2 9 6 12 | 5 7 4 11 13 | 3 7 16 5 14 | ``` 15 | 16 | 礼物的最大价值为 1+12+5+7+7+16+5=53。 17 | 18 | ## 解题思路 19 | 20 | 应该用动态规划求解,而不是深度优先搜索,深度优先搜索过于复杂,不是最优解。 21 | 22 | ```java 23 | public int getMost(int[][] values) { 24 | if (values == null || values.length == 0 || values[0].length == 0) 25 | return 0; 26 | int n = values[0].length; 27 | int[] dp = new int[n]; 28 | for (int[] value : values) { 29 | dp[0] += value[0]; 30 | for (int i = 1; i < n; i++) 31 | dp[i] = Math.max(dp[i], dp[i - 1]) + value[i]; 32 | } 33 | return dp[n - 1]; 34 | } 35 | ``` 36 | -------------------------------------------------------------------------------- /04数据结构及算法/code/48. 最长不含重复字符的子字符串.md: -------------------------------------------------------------------------------- 1 | # 48. 最长不含重复字符的子字符串 2 | 3 | ## 题目描述 4 | 5 | 输入一个字符串(只包含 a\~z 的字符),求其最长不含重复字符的子字符串的长度。例如对于 arabcacfr,最长不含重复字符的子字符串为 acfr,长度为 4。 6 | 7 | ## 解题思路 8 | 9 | ```java 10 | public int longestSubStringWithoutDuplication(String str) { 11 | int curLen = 0; 12 | int maxLen = 0; 13 | int[] preIndexs = new int[26]; 14 | Arrays.fill(preIndexs, -1); 15 | for (int curI = 0; curI < str.length(); curI++) { 16 | int c = str.charAt(curI) - 'a'; 17 | int preI = preIndexs[c]; 18 | if (preI == -1 || curI - preI > curLen) { 19 | curLen++; 20 | } else { 21 | maxLen = Math.max(maxLen, curLen); 22 | curLen = curI - preI; 23 | } 24 | preIndexs[c] = curI; 25 | } 26 | maxLen = Math.max(maxLen, curLen); 27 | return maxLen; 28 | } 29 | ``` 30 | -------------------------------------------------------------------------------- /04数据结构及算法/code/49. 丑数.md: -------------------------------------------------------------------------------- 1 | # 49. 丑数 2 | 3 | [NowCoder](https://www.nowcoder.com/practice/6aa9e04fc3794f68acf8778237ba065b?tpId=13&tqId=11186&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) 4 | 5 | ## 题目描述 6 | 7 | 把只包含因子 2、3 和 5 的数称作丑数(Ugly Number)。例如 6、8 都是丑数,但 14 不是,因为它包含因子 7。习惯上我们把 1 当做是第一个丑数。求按从小到大的顺序的第 N 个丑数。 8 | 9 | ## 解题思路 10 | 11 | ```java 12 | public int GetUglyNumber_Solution(int N) { 13 | if (N <= 6) 14 | return N; 15 | int i2 = 0, i3 = 0, i5 = 0; 16 | int[] dp = new int[N]; 17 | dp[0] = 1; 18 | for (int i = 1; i < N; i++) { 19 | int next2 = dp[i2] * 2, next3 = dp[i3] * 3, next5 = dp[i5] * 5; 20 | dp[i] = Math.min(next2, Math.min(next3, next5)); 21 | if (dp[i] == next2) 22 | i2++; 23 | if (dp[i] == next3) 24 | i3++; 25 | if (dp[i] == next5) 26 | i5++; 27 | } 28 | return dp[N - 1]; 29 | } 30 | ``` 31 | -------------------------------------------------------------------------------- /04数据结构及算法/code/5. 替换空格.md: -------------------------------------------------------------------------------- 1 | # 5. 替换空格 2 | 3 | ## 题目链接 4 | 5 | [牛客网](https://www.nowcoder.com/practice/0e26e5551f2b489b9f58bc83aa4b6c68?tpId=13&tqId=11155&tab=answerKey&from=cyc_github) 6 | 7 | ## 题目描述 8 | 9 | 10 | 将一个字符串中的空格替换成 "%20"。 11 | 12 | ```text 13 | Input: 14 | "A B" 15 | 16 | Output: 17 | "A%20B" 18 | ``` 19 | 20 | ## 解题思路 21 | 22 | ① 在字符串尾部填充任意字符,使得字符串的长度等于替换之后的长度。因为一个空格要替换成三个字符(%20),所以当遍历到一个空格时,需要在尾部填充两个任意字符。 23 | 24 | ② 令 P1 指向字符串原来的末尾位置,P2 指向字符串现在的末尾位置。P1 和 P2 从后向前遍历,当 P1 遍历到一个空格时,就需要令 P2 指向的位置依次填充 02%(注意是逆序的),否则就填充上 P1 指向字符的值。从后向前遍是为了在改变 P2 所指向的内容时,不会影响到 P1 遍历原来字符串的内容。 25 | 26 | ③ 当 P2 遇到 P1 时(P2 \<= P1),或者遍历结束(P1 \< 0),退出。 27 | 28 | 29 | 30 |

31 | 32 | ```java 33 | public String replaceSpace(StringBuffer str) { 34 | int P1 = str.length() - 1; 35 | for (int i = 0; i <= P1; i++) 36 | if (str.charAt(i) == ' ') 37 | str.append(" "); 38 | 39 | int P2 = str.length() - 1; 40 | while (P1 >= 0 && P2 > P1) { 41 | char c = str.charAt(P1--); 42 | if (c == ' ') { 43 | str.setCharAt(P2--, '0'); 44 | str.setCharAt(P2--, '2'); 45 | str.setCharAt(P2--, '%'); 46 | } else { 47 | str.setCharAt(P2--, c); 48 | } 49 | } 50 | return str.toString(); 51 | } 52 | ``` 53 | -------------------------------------------------------------------------------- /04数据结构及算法/code/50. 第一个只出现一次的字符位置.md: -------------------------------------------------------------------------------- 1 | # 50. 第一个只出现一次的字符位置 2 | 3 | ## 题目链接 4 | 5 | [牛客网](https://www.nowcoder.com/practice/1c82e8cf713b4bbeb2a5b31cf5b0417c?tpId=13&tqId=11187&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) 6 | 7 | ## 题目描述 8 | 9 | 在一个字符串中找到第一个只出现一次的字符,并返回它的位置。字符串只包含 ASCII 码字符。 10 | 11 | ``` 12 | Input: abacc 13 | Output: b 14 | ``` 15 | 16 | ## 解题思路 17 | 18 | 最直观的解法是使用 HashMap 对出现次数进行统计:字符做为 key,出现次数作为 value,遍历字符串每次都将 key 对应的 value 加 1。最后再遍历这个 HashMap 就可以找出出现次数为 1 的字符。 19 | 20 | 考虑到要统计的字符范围有限,也可以使用整型数组代替 HashMap。ASCII 码只有 128 个字符,因此可以使用长度为 128 的整型数组来存储每个字符出现的次数。 21 | 22 | ```java 23 | public int FirstNotRepeatingChar(String str) { 24 | int[] cnts = new int[128]; 25 | for (int i = 0; i < str.length(); i++) 26 | cnts[str.charAt(i)]++; 27 | for (int i = 0; i < str.length(); i++) 28 | if (cnts[str.charAt(i)] == 1) 29 | return i; 30 | return -1; 31 | } 32 | ``` 33 | 34 | 以上实现的空间复杂度还不是最优的。考虑到只需要找到只出现一次的字符,那么需要统计的次数信息只有 0,1,更大,使用两个比特位就能存储这些信息。 35 | 36 | ```java 37 | public int FirstNotRepeatingChar2(String str) { 38 | BitSet bs1 = new BitSet(128); 39 | BitSet bs2 = new BitSet(128); 40 | for (char c : str.toCharArray()) { 41 | if (!bs1.get(c) && !bs2.get(c)) 42 | bs1.set(c); // 0 0 -> 0 1 43 | else if (bs1.get(c) && !bs2.get(c)) 44 | bs2.set(c); // 0 1 -> 1 1 45 | } 46 | for (int i = 0; i < str.length(); i++) { 47 | char c = str.charAt(i); 48 | if (bs1.get(c) && !bs2.get(c)) // 0 1 49 | return i; 50 | } 51 | return -1; 52 | } 53 | ``` 54 | -------------------------------------------------------------------------------- /04数据结构及算法/code/51. 数组中的逆序对.md: -------------------------------------------------------------------------------- 1 | # 51. 数组中的逆序对 2 | 3 | [NowCoder](https://www.nowcoder.com/practice/96bd6684e04a44eb80e6a68efc0ec6c5?tpId=13&tqId=11188&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) 4 | 5 | ## 题目描述 6 | 7 | 在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数。 8 | 9 | ## 解题思路 10 | 11 | ```java 12 | private long cnt = 0; 13 | private int[] tmp; // 在这里声明辅助数组,而不是在 merge() 递归函数中声明 14 | 15 | public int InversePairs(int[] nums) { 16 | tmp = new int[nums.length]; 17 | mergeSort(nums, 0, nums.length - 1); 18 | return (int) (cnt % 1000000007); 19 | } 20 | 21 | private void mergeSort(int[] nums, int l, int h) { 22 | if (h - l < 1) 23 | return; 24 | int m = l + (h - l) / 2; 25 | mergeSort(nums, l, m); 26 | mergeSort(nums, m + 1, h); 27 | merge(nums, l, m, h); 28 | } 29 | 30 | private void merge(int[] nums, int l, int m, int h) { 31 | int i = l, j = m + 1, k = l; 32 | while (i <= m || j <= h) { 33 | if (i > m) 34 | tmp[k] = nums[j++]; 35 | else if (j > h) 36 | tmp[k] = nums[i++]; 37 | else if (nums[i] <= nums[j]) 38 | tmp[k] = nums[i++]; 39 | else { 40 | tmp[k] = nums[j++]; 41 | this.cnt += m - i + 1; // nums[i] > nums[j],说明 nums[i...mid] 都大于 nums[j] 42 | } 43 | k++; 44 | } 45 | for (k = l; k <= h; k++) 46 | nums[k] = tmp[k]; 47 | } 48 | ``` 49 | -------------------------------------------------------------------------------- /04数据结构及算法/code/52. 两个链表的第一个公共结点.md: -------------------------------------------------------------------------------- 1 | # 52. 两个链表的第一个公共结点 2 | 3 | [NowCoder](https://www.nowcoder.com/practice/6ab1d9a29e88450685099d45c9e31e46?tpId=13&tqId=11189&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) 4 | 5 | ## 题目描述 6 | 7 |

8 | 9 | ## 解题思路 10 | 11 | 设 A 的长度为 a + c,B 的长度为 b + c,其中 c 为尾部公共部分长度,可知 a + c + b = b + c + a。 12 | 13 | 当访问链表 A 的指针访问到链表尾部时,令它从链表 B 的头部重新开始访问链表 B;同样地,当访问链表 B 的指针访问到链表尾部时,令它从链表 A 的头部重新开始访问链表 A。这样就能控制访问 A 和 B 两个链表的指针能同时访问到交点。 14 | 15 | ```java 16 | public ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2) { 17 | ListNode l1 = pHead1, l2 = pHead2; 18 | while (l1 != l2) { 19 | l1 = (l1 == null) ? pHead2 : l1.next; 20 | l2 = (l2 == null) ? pHead1 : l2.next; 21 | } 22 | return l1; 23 | } 24 | ``` 25 | -------------------------------------------------------------------------------- /04数据结构及算法/code/53. 数字在排序数组中出现的次数.md: -------------------------------------------------------------------------------- 1 | # 53. 数字在排序数组中出现的次数 2 | 3 | ## 题目链接 4 | 5 | [牛客网](https://www.nowcoder.com/practice/70610bf967994b22bb1c26f9ae901fa2?tpId=13&tqId=11190&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) 6 | 7 | ## 题目描述 8 | 9 | ```html 10 | Input: 11 | nums = 1, 2, 3, 3, 3, 3, 4, 6 12 | K = 3 13 | 14 | Output: 15 | 4 16 | ``` 17 | 18 | ## 解题思路 19 | 20 | 只要能找出给定的数字 k 在有序数组第一个位置和最后一个位置,就能知道该数字出现的次数。 21 | 22 | 先考虑如何实现寻找数字在有序数组的第一个位置。正常的二分查找如下,在查找到给定元素 k 之后,立即返回当前索引下标。 23 | 24 | ```java 25 | public int binarySearch(int[] nums, int K) { 26 | int l = 0, h = nums.length - 1; 27 | while (l <= h) { 28 | int m = l + (h - l) / 2; 29 | if (nums[m] == K) { 30 | return m; 31 | } else if (nums[m] > K) { 32 | h = m - 1; 33 | } else { 34 | l = m + 1; 35 | } 36 | } 37 | return -1; 38 | } 39 | ``` 40 | 41 | 但是在查找第一个位置时,找到元素之后应该继续往前找。也就是当 nums[m]\>=k 时,在左区间继续查找,左区间应该包含 m 位置。 42 | 43 | ```java 44 | private int binarySearch(int[] nums, int K) { 45 | int l = 0, h = nums.length; 46 | while (l < h) { 47 | int m = l + (h - l) / 2; 48 | if (nums[m] >= K) 49 | h = m; 50 | else 51 | l = m + 1; 52 | } 53 | return l; 54 | } 55 | ``` 56 | 57 | 查找最后一个位置可以转换成寻找 k+1 的第一个位置,并再往前移动一个位置。 58 | 59 | ```java 60 | public int GetNumberOfK(int[] nums, int K) { 61 | int first = binarySearch(nums, K); 62 | int last = binarySearch(nums, K + 1); 63 | return (first == nums.length || nums[first] != K) ? 0 : last - first; 64 | } 65 | ``` 66 | 67 | 需要注意以上实现的查找第一个位置的 binarySearch 方法,h 的初始值为 nums.length,而不是 nums.length - 1。先看以下示例: 68 | 69 | ``` 70 | nums = [2,2], k = 2 71 | ``` 72 | 73 | 如果 h 的取值为 nums.length - 1,那么在查找最后一个位置时,binarySearch(nums, k + 1) - 1 = 1 - 1 = 0。这是因为 binarySearch 只会返回 [0, nums.length - 1] 范围的值,对于 binarySearch([2,2], 3) ,我们希望返回 3 插入 nums 中的位置,也就是数组最后一个位置再往后一个位置,即 nums.length。所以我们需要将 h 取值为 nums.length,从而使得 binarySearch 返回的区间更大,能够覆盖 k 大于 nums 最后一个元素的情况。 74 | -------------------------------------------------------------------------------- /04数据结构及算法/code/54. 二叉查找树的第 K 个结点.md: -------------------------------------------------------------------------------- 1 | # 54. 二叉查找树的第 K 个结点 2 | 3 | [NowCoder](https://www.nowcoder.com/practice/ef068f602dde4d28aab2b210e859150a?tpId=13&tqId=11215&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) 4 | 5 | ## 解题思路 6 | 7 | 利用二叉查找树中序遍历有序的特点。 8 | 9 | ```java 10 | private TreeNode ret; 11 | private int cnt = 0; 12 | 13 | public TreeNode KthNode(TreeNode pRoot, int k) { 14 | inOrder(pRoot, k); 15 | return ret; 16 | } 17 | 18 | private void inOrder(TreeNode root, int k) { 19 | if (root == null || cnt >= k) 20 | return; 21 | inOrder(root.left, k); 22 | cnt++; 23 | if (cnt == k) 24 | ret = root; 25 | inOrder(root.right, k); 26 | } 27 | ``` 28 | -------------------------------------------------------------------------------- /04数据结构及算法/code/55.1 二叉树的深度.md: -------------------------------------------------------------------------------- 1 | # 55.1 二叉树的深度 2 | 3 | [NowCoder](https://www.nowcoder.com/practice/435fb86331474282a3499955f0a41e8b?tpId=13&tqId=11191&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) 4 | 5 | ## 题目描述 6 | 7 | 从根结点到叶结点依次经过的结点(含根、叶结点)形成树的一条路径,最长路径的长度为树的深度。 8 | 9 |

10 | 11 | ## 解题思路 12 | 13 | ```java 14 | public int TreeDepth(TreeNode root) { 15 | return root == null ? 0 : 1 + Math.max(TreeDepth(root.left), TreeDepth(root.right)); 16 | } 17 | ``` 18 | -------------------------------------------------------------------------------- /04数据结构及算法/code/55.2 平衡二叉树.md: -------------------------------------------------------------------------------- 1 | # 55.2 平衡二叉树 2 | 3 | [NowCoder](https://www.nowcoder.com/practice/8b3b95850edb4115918ecebdf1b4d222?tpId=13&tqId=11192&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) 4 | 5 | ## 题目描述 6 | 7 | 平衡二叉树左右子树高度差不超过 1。 8 | 9 |

10 | 11 | ## 解题思路 12 | 13 | ```java 14 | private boolean isBalanced = true; 15 | 16 | public boolean IsBalanced_Solution(TreeNode root) { 17 | height(root); 18 | return isBalanced; 19 | } 20 | 21 | private int height(TreeNode root) { 22 | if (root == null || !isBalanced) 23 | return 0; 24 | int left = height(root.left); 25 | int right = height(root.right); 26 | if (Math.abs(left - right) > 1) 27 | isBalanced = false; 28 | return 1 + Math.max(left, right); 29 | } 30 | ``` 31 | -------------------------------------------------------------------------------- /04数据结构及算法/code/56. 数组中只出现一次的数字.md: -------------------------------------------------------------------------------- 1 | # 56. 数组中只出现一次的数字 2 | 3 | ## 题目链接 4 | 5 | [牛客网](https://www.nowcoder.com/practice/389fc1c3d3be4479a154f63f495abff8?tpId=13&tqId=11193&tab=answerKey&from=cyc_github) 6 | 7 | ## 题目描述 8 | 9 | 一个整型数组里除了两个数字之外,其他的数字都出现了两次,找出这两个数。 10 | 11 | ## 解题思路 12 | 13 | 两个相等的元素异或的结果为 0,而 0 与任意数 x 异或的结果都为 x。 14 | 15 | 对本题给的数组的所有元素执行异或操作,得到的是两个不存在重复的元素异或的结果。例如对于数组 [x,x,y,y,z,k],x^x^y^y^z^k = 0^y^y^z^k = y^y^z^k = 0^z^k = z^k。 16 | 17 | 两个不相等的元素在位级表示上一定会有所不同,因此这两个元素异或得到的结果 diff 一定不为 0。位运算 diff & -diff 能得到 diff 位级表示中最右侧为 1 的位,令 diff = diff & -diff。将 diff 作为区分两个元素的依据,一定有一个元素对 diff 进行异或的结果为 0,另一个结果非 0。设不相等的两个元素分别为 z 和 k,遍历数组所有元素,判断元素与 diff 的异或结果是否为 0,如果是的话将元素与 z 进行异或并赋值给 z,否则与 k 进行异或并赋值给 k。数组中相等的元素一定会同时与 z 或者与 k 进行异或操作,而不是一个与 z 进行异或,一个与 k 进行异或。而且这些相等的元素异或的结果为 0,因此最后 z 和 k 只是不相等的两个元素与 0 异或的结果,也就是不相等两个元素本身。 18 | 19 | 下面的解法中,num1 和 num2 数组的第一个元素是用来保持返回值的... 实际开发中不推荐这种返回值的方式。 20 | 21 | ```java 22 | public int[] FindNumsAppearOnce (int[] nums) { 23 | int[] res = new int[2]; 24 | int diff = 0; 25 | for (int num : nums) 26 | diff ^= num; 27 | diff &= -diff; 28 | for (int num : nums) { 29 | if ((num & diff) == 0) 30 | res[0] ^= num; 31 | else 32 | res[1] ^= num; 33 | } 34 | if (res[0] > res[1]) { 35 | swap(res); 36 | } 37 | return res; 38 | } 39 | 40 | private void swap(int[] nums) { 41 | int t = nums[0]; 42 | nums[0] = nums[1]; 43 | nums[1] = t; 44 | } 45 | ``` 46 | -------------------------------------------------------------------------------- /04数据结构及算法/code/57.1 和为 S 的两个数字.md: -------------------------------------------------------------------------------- 1 | # 57.1 和为 S 的两个数字 2 | 3 | ## 题目链接 4 | 5 | [牛客网](https://www.nowcoder.com/practice/390da4f7a00f44bea7c2f3d19491311b?tpId=13&tqId=11195&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) 6 | 7 | ## 题目描述 8 | 9 | 在有序数组中找出两个数,使得和为给定的数 S。如果有多对数字的和等于 S,输出两个数的乘积最小的。 10 | 11 | ## 解题思路 12 | 13 | 使用双指针,一个指针指向元素较小的值,一个指针指向元素较大的值。指向较小元素的指针从头向尾遍历,指向较大元素的指针从尾向头遍历。 14 | 15 | - 如果两个指针指向元素的和 sum == target,那么这两个元素即为所求。 16 | - 如果 sum \> target,移动较大的元素,使 sum 变小一些; 17 | - 如果 sum \< target,移动较小的元素,使 sum 变大一些。 18 | 19 | ```java 20 | public ArrayList FindNumbersWithSum(int[] nums, int target) { 21 | int i = 0, j = nums.length - 1; 22 | while (i < j) { 23 | int cur = nums[i] + array[j]; 24 | if (cur == target) 25 | return new ArrayList<>(Arrays.asList(nums[i], nums[j])); 26 | if (cur < target) 27 | i++; 28 | else 29 | j--; 30 | } 31 | return new ArrayList<>(); 32 | } 33 | ``` 34 | -------------------------------------------------------------------------------- /04数据结构及算法/code/57.2 和为 S 的连续正数序列.md: -------------------------------------------------------------------------------- 1 | # 57.2 和为 S 的连续正数序列 2 | 3 | ## 题目描述 4 | 5 | [牛客网](https://www.nowcoder.com/practice/c451a3fd84b64cb19485dad758a55ebe?tpId=13&tqId=11194&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) 6 | 7 | ## 题目描述 8 | 9 | 输出所有和为 S 的连续正数序列。例如和为 100 的连续序列有: 10 | 11 | ``` 12 | [9, 10, 11, 12, 13, 14, 15, 16] 13 | [18, 19, 20, 21, 22]。 14 | ``` 15 | 16 | ## 解题思路 17 | 18 | ```java 19 | public ArrayList> FindContinuousSequence(int sum) { 20 | ArrayList> ret = new ArrayList<>(); 21 | int start = 1, end = 2; 22 | int curSum = 3; 23 | while (end < sum) { 24 | if (curSum > sum) { 25 | curSum -= start; 26 | start++; 27 | } else if (curSum < sum) { 28 | end++; 29 | curSum += end; 30 | } else { 31 | ArrayList list = new ArrayList<>(); 32 | for (int i = start; i <= end; i++) 33 | list.add(i); 34 | ret.add(list); 35 | curSum -= start; 36 | start++; 37 | end++; 38 | curSum += end; 39 | } 40 | } 41 | return ret; 42 | } 43 | ``` 44 | -------------------------------------------------------------------------------- /04数据结构及算法/code/58.1 翻转单词顺序列.md: -------------------------------------------------------------------------------- 1 | # 58.1 翻转单词顺序列 2 | 3 | ## 题目描述 4 | 5 | [牛客网](https://www.nowcoder.com/practice/3194a4f4cf814f63919d0790578d51f3?tpId=13&tqId=11197&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) 6 | 7 | ## 题目描述 8 | 9 | ```html 10 | Input: 11 | "I am a student." 12 | 13 | Output: 14 | "student. a am I" 15 | ``` 16 | 17 | ## 解题思路 18 | 19 | 先翻转每个单词,再翻转整个字符串。 20 | 21 | 题目应该有一个隐含条件,就是不能用额外的空间。虽然 Java 的题目输入参数为 String 类型,需要先创建一个字符数组使得空间复杂度为 O(N),但是正确的参数类型应该和原书一样,为字符数组,并且只能使用该字符数组的空间。任何使用了额外空间的解法在面试时都会大打折扣,包括递归解法。 22 | 23 | ```java 24 | public String ReverseSentence(String str) { 25 | int n = str.length(); 26 | char[] chars = str.toCharArray(); 27 | int i = 0, j = 0; 28 | while (j <= n) { 29 | if (j == n || chars[j] == ' ') { 30 | reverse(chars, i, j - 1); 31 | i = j + 1; 32 | } 33 | j++; 34 | } 35 | reverse(chars, 0, n - 1); 36 | return new String(chars); 37 | } 38 | 39 | private void reverse(char[] c, int i, int j) { 40 | while (i < j) 41 | swap(c, i++, j--); 42 | } 43 | 44 | private void swap(char[] c, int i, int j) { 45 | char t = c[i]; 46 | c[i] = c[j]; 47 | c[j] = t; 48 | } 49 | ``` 50 | -------------------------------------------------------------------------------- /04数据结构及算法/code/58.2 左旋转字符串.md: -------------------------------------------------------------------------------- 1 | # 58.2 左旋转字符串 2 | 3 | ## 题目链接 4 | 5 | [牛客网](https://www.nowcoder.com/practice/12d959b108cb42b1ab72cef4d36af5ec?tpId=13&tqId=11196&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) 6 | 7 | ## 题目描述 8 | 9 | 将字符串 S 从第 K 位置分隔成两个子字符串,并交换这两个子字符串的位置。 10 | 11 | ```html 12 | Input: 13 | S="abcXYZdef" 14 | K=3 15 | 16 | Output: 17 | "XYZdefabc" 18 | ``` 19 | 20 | ## 解题思路 21 | 22 | 先将 "abc" 和 "XYZdef" 分别翻转,得到 "cbafedZYX",然后再把整个字符串翻转得到 "XYZdefabc"。 23 | 24 | ```java 25 | public String LeftRotateString(String str, int n) { 26 | if (n >= str.length()) 27 | return str; 28 | char[] chars = str.toCharArray(); 29 | reverse(chars, 0, n - 1); 30 | reverse(chars, n, chars.length - 1); 31 | reverse(chars, 0, chars.length - 1); 32 | return new String(chars); 33 | } 34 | 35 | private void reverse(char[] chars, int i, int j) { 36 | while (i < j) 37 | swap(chars, i++, j--); 38 | } 39 | 40 | private void swap(char[] chars, int i, int j) { 41 | char t = chars[i]; 42 | chars[i] = chars[j]; 43 | chars[j] = t; 44 | } 45 | ``` 46 | -------------------------------------------------------------------------------- /04数据结构及算法/code/59. 滑动窗口的最大值.md: -------------------------------------------------------------------------------- 1 | # 59. 滑动窗口的最大值 2 | 3 | ## 题目链接 4 | 5 | [牛客网](https://www.nowcoder.com/practice/1624bc35a45c42c0bc17d17fa0cba788?tpId=13&tqId=11217&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) 6 | 7 | ## 题目描述 8 | 9 | 给定一个数组和滑动窗口的大小,找出所有滑动窗口里数值的最大值。 10 | 11 | 例如,如果输入数组 {2, 3, 4, 2, 6, 2, 5, 1} 及滑动窗口的大小 3,那么一共存在 6 个滑动窗口,他们的最大值分别为 {4, 4, 6, 6, 6, 5}。 12 | 13 |

14 | 15 | ## 解题思路 16 | 17 | 维护一个大小为窗口大小的大顶堆,顶堆元素则为当前窗口的最大值。 18 | 19 | 假设窗口的大小为 M,数组的长度为 N。在窗口向右移动时,需要先在堆中删除离开窗口的元素,并将新到达的元素添加到堆中,这两个操作的时间复杂度都为 log2M,因此算法的时间复杂度为 O(Nlog2M),空间复杂度为 O(M)。 20 | 21 | ```java 22 | public ArrayList maxInWindows(int[] num, int size) { 23 | ArrayList ret = new ArrayList<>(); 24 | if (size > num.length || size < 1) 25 | return ret; 26 | PriorityQueue heap = new PriorityQueue<>((o1, o2) -> o2 - o1); /* 大顶堆 */ 27 | for (int i = 0; i < size; i++) 28 | heap.add(num[i]); 29 | ret.add(heap.peek()); 30 | for (int i = 0, j = i + size; j < num.length; i++, j++) { /* 维护一个大小为 size 的大顶堆 */ 31 | heap.remove(num[i]); 32 | heap.add(num[j]); 33 | ret.add(heap.peek()); 34 | } 35 | return ret; 36 | } 37 | ``` 38 | -------------------------------------------------------------------------------- /04数据结构及算法/code/60. n 个骰子的点数.md: -------------------------------------------------------------------------------- 1 | # 60. n 个骰子的点数 2 | 3 | ## 题目链接 4 | 5 | [Lintcode](https://www.lintcode.com/en/problem/dices-sum/) 6 | 7 | ## 题目描述 8 | 9 | 把 n 个骰子扔在地上,求点数和为 s 的概率。 10 | 11 |

12 | 13 | ## 解题思路 14 | 15 | ### 动态规划 16 | 17 | 使用一个二维数组 dp 存储点数出现的次数,其中 dp\[i]\[j] 表示前 i 个骰子产生点数 j 的次数。 18 | 19 | 空间复杂度:O(N2) 20 | 21 | ```java 22 | public List> dicesSum(int n) { 23 | final int face = 6; 24 | final int pointNum = face * n; 25 | long[][] dp = new long[n + 1][pointNum + 1]; 26 | 27 | for (int i = 1; i <= face; i++) 28 | dp[1][i] = 1; 29 | 30 | for (int i = 2; i <= n; i++) 31 | for (int j = i; j <= pointNum; j++) /* 使用 i 个骰子最小点数为 i */ 32 | for (int k = 1; k <= face && k <= j; k++) 33 | dp[i][j] += dp[i - 1][j - k]; 34 | 35 | final double totalNum = Math.pow(6, n); 36 | List> ret = new ArrayList<>(); 37 | for (int i = n; i <= pointNum; i++) 38 | ret.add(new AbstractMap.SimpleEntry<>(i, dp[n][i] / totalNum)); 39 | 40 | return ret; 41 | } 42 | ``` 43 | 44 | ### 动态规划 + 旋转数组 45 | 46 | 空间复杂度:O(N) 47 | 48 | ```java 49 | public List> dicesSum(int n) { 50 | final int face = 6; 51 | final int pointNum = face * n; 52 | long[][] dp = new long[2][pointNum + 1]; 53 | 54 | for (int i = 1; i <= face; i++) 55 | dp[0][i] = 1; 56 | 57 | int flag = 1; /* 旋转标记 */ 58 | for (int i = 2; i <= n; i++, flag = 1 - flag) { 59 | for (int j = 0; j <= pointNum; j++) 60 | dp[flag][j] = 0; /* 旋转数组清零 */ 61 | 62 | for (int j = i; j <= pointNum; j++) 63 | for (int k = 1; k <= face && k <= j; k++) 64 | dp[flag][j] += dp[1 - flag][j - k]; 65 | } 66 | 67 | final double totalNum = Math.pow(6, n); 68 | List> ret = new ArrayList<>(); 69 | for (int i = n; i <= pointNum; i++) 70 | ret.add(new AbstractMap.SimpleEntry<>(i, dp[1 - flag][i] / totalNum)); 71 | 72 | return ret; 73 | } 74 | ``` 75 | -------------------------------------------------------------------------------- /04数据结构及算法/code/61. 扑克牌顺子.md: -------------------------------------------------------------------------------- 1 | # 61. 扑克牌顺子 2 | 3 | ## 题目链接 4 | 5 | [NowCoder](https://www.nowcoder.com/practice/762836f4d43d43ca9deb273b3de8e1f4?tpId=13&tqId=11198&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) 6 | 7 | ## 题目描述 8 | 9 | 五张牌,其中大小鬼为癞子,牌面为 0。判断这五张牌是否能组成顺子。 10 | 11 |

12 | 13 | 14 | ## 解题思路 15 | 16 | ```java 17 | public boolean isContinuous(int[] nums) { 18 | 19 | if (nums.length < 5) 20 | return false; 21 | 22 | Arrays.sort(nums); 23 | 24 | // 统计癞子数量 25 | int cnt = 0; 26 | for (int num : nums) 27 | if (num == 0) 28 | cnt++; 29 | 30 | // 使用癞子去补全不连续的顺子 31 | for (int i = cnt; i < nums.length - 1; i++) { 32 | if (nums[i + 1] == nums[i]) 33 | return false; 34 | cnt -= nums[i + 1] - nums[i] - 1; 35 | } 36 | 37 | return cnt >= 0; 38 | } 39 | ``` 40 | -------------------------------------------------------------------------------- /04数据结构及算法/code/62. 圆圈中最后剩下的数.md: -------------------------------------------------------------------------------- 1 | # 62. 圆圈中最后剩下的数 2 | 3 | ## 题目链接 4 | 5 | [NowCoder](https://www.nowcoder.com/practice/f78a359491e64a50bce2d89cff857eb6?tpId=13&tqId=11199&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) 6 | 7 | ## 题目描述 8 | 9 | 让小朋友们围成一个大圈。然后,随机指定一个数 m,让编号为 0 的小朋友开始报数。每次喊到 m-1 的那个小朋友要出列唱首歌,然后可以在礼品箱中任意的挑选礼物,并且不再回到圈中,从他的下一个小朋友开始,继续 0...m-1 报数 .... 这样下去 .... 直到剩下最后一个小朋友,可以不用表演。 10 | 11 | ## 解题思路 12 | 13 | 约瑟夫环,圆圈长度为 n 的解可以看成长度为 n-1 的解再加上报数的长度 m。因为是圆圈,所以最后需要对 n 取余。 14 | 15 | ```java 16 | public int LastRemaining_Solution(int n, int m) { 17 | if (n == 0) /* 特殊输入的处理 */ 18 | return -1; 19 | if (n == 1) /* 递归返回条件 */ 20 | return 0; 21 | return (LastRemaining_Solution(n - 1, m) + m) % n; 22 | } 23 | ``` 24 | -------------------------------------------------------------------------------- /04数据结构及算法/code/63. 股票的最大利润.md: -------------------------------------------------------------------------------- 1 | # 63. 股票的最大利润 2 | 3 | ## 题目链接 4 | 5 | [Leetcode:121. Best Time to Buy and Sell Stock ](https://leetcode.com/problems/best-time-to-buy-and-sell-stock/description/) 6 | 7 | ## 题目描述 8 | 9 | 可以有一次买入和一次卖出,买入必须在前。求最大收益。 10 | 11 |

12 | 13 | ## 解题思路 14 | 15 | 使用贪心策略,假设第 i 轮进行卖出操作,买入操作价格应该在 i 之前并且价格最低。因此在遍历数组时记录当前最低的买入价格,并且尝试将每个位置都作为卖出价格,取收益最大的即可。 16 | 17 | ```java 18 | public int maxProfit(int[] prices) { 19 | if (prices == null || prices.length == 0) 20 | return 0; 21 | int soFarMin = prices[0]; 22 | int maxProfit = 0; 23 | for (int i = 1; i < prices.length; i++) { 24 | soFarMin = Math.min(soFarMin, prices[i]); 25 | maxProfit = Math.max(maxProfit, prices[i] - soFarMin); 26 | } 27 | return maxProfit; 28 | } 29 | ``` 30 | -------------------------------------------------------------------------------- /04数据结构及算法/code/64. 求 1+2+3+...+n.md: -------------------------------------------------------------------------------- 1 | # 64. 求 1+2+3+...+n 2 | 3 | ## 题目链接 4 | 5 | [NowCoder](https://www.nowcoder.com/practice/7a0da8fc483247ff8800059e12d7caf1?tpId=13&tqId=11200&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) 6 | 7 | ## 题目描述 8 | 9 | 要求不能使用乘除法、for、while、if、else、switch、case 等关键字及条件判断语句 A ? B : C。 10 | 11 | ## 解题思路 12 | 13 | 使用递归解法最重要的是指定返回条件,但是本题无法直接使用 if 语句来指定返回条件。 14 | 15 | 条件与 && 具有短路原则,即在第一个条件语句为 false 的情况下不会去执行第二个条件语句。利用这一特性,将递归的返回条件取非然后作为 && 的第一个条件语句,递归的主体转换为第二个条件语句,那么当递归的返回条件为 true 的情况下就不会执行递归的主体部分,递归返回。 16 | 17 | 本题的递归返回条件为 n \<= 0,取非后就是 n \> 0;递归的主体部分为 sum += Sum_Solution(n - 1),转换为条件语句后就是 (sum += Sum_Solution(n - 1)) \> 0。 18 | 19 | ```java 20 | public int Sum_Solution(int n) { 21 | int sum = n; 22 | boolean b = (n > 0) && ((sum += Sum_Solution(n - 1)) > 0); 23 | return sum; 24 | } 25 | ``` 26 | -------------------------------------------------------------------------------- /04数据结构及算法/code/65. 不用加减乘除做加法.md: -------------------------------------------------------------------------------- 1 | # 65. 不用加减乘除做加法 2 | 3 | ## 题目链接 4 | 5 | [NowCoder](https://www.nowcoder.com/practice/59ac416b4b944300b617d4f7f111b215?tpId=13&tqId=11201&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) 6 | 7 | ## 题目描述 8 | 9 | 写一个函数,求两个整数之和,要求不得使用 +、-、\*、/ 四则运算符号。 10 | 11 | ## 解题思路 12 | 13 | a ^ b 表示没有考虑进位的情况下两数的和,(a & b) \<\< 1 就是进位。 14 | 15 | 递归会终止的原因是 (a & b) \<\< 1 最右边会多一个 0,那么继续递归,进位最右边的 0 会慢慢增多,最后进位会变为 0,递归终止。 16 | 17 | ```java 18 | public int Add(int a, int b) { 19 | return b == 0 ? a : Add(a ^ b, (a & b) << 1); 20 | } 21 | ``` 22 | -------------------------------------------------------------------------------- /04数据结构及算法/code/66. 构建乘积数组.md: -------------------------------------------------------------------------------- 1 | # 66. 构建乘积数组 2 | 3 | ## 题目链接 4 | 5 | [NowCoder](https://www.nowcoder.com/practice/94a4d381a68b47b7a8bed86f2975db46?tpId=13&tqId=11204&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) 6 | 7 | ## 题目描述 8 | 9 | 给定一个数组 A[0, 1,..., n-1],请构建一个数组 B[0, 1,..., n-1],其中 B 中的元素 B[i]=A[0]\*A[1]\*...\*A[i-1]\*A[i+1]\*...\*A[n-1]。要求不能使用除法。 10 | 11 |

12 | 13 | 14 | ## 解题思路 15 | 16 | ```java 17 | public int[] multiply(int[] A) { 18 | int n = A.length; 19 | int[] B = new int[n]; 20 | for (int i = 0, product = 1; i < n; product *= A[i], i++) /* 从左往右累乘 */ 21 | B[i] = product; 22 | for (int i = n - 1, product = 1; i >= 0; product *= A[i], i--) /* 从右往左累乘 */ 23 | B[i] *= product; 24 | return B; 25 | } 26 | ``` 27 | -------------------------------------------------------------------------------- /04数据结构及算法/code/67. 把字符串转换成整数.md: -------------------------------------------------------------------------------- 1 | # 67. 把字符串转换成整数 2 | 3 | ## 题目链接 4 | 5 | [NowCoder](https://www.nowcoder.com/practice/1277c681251b4372bdef344468e4f26e?tpId=13&tqId=11202&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) 6 | 7 | ## 题目描述 8 | 9 | 将一个字符串转换成一个整数,字符串不是一个合法的数值则返回 0,要求不能使用字符串转换整数的库函数。 10 | 11 | ```html 12 | Iuput: 13 | +2147483647 14 | 1a33 15 | 16 | Output: 17 | 2147483647 18 | 0 19 | ``` 20 | 21 | ## 解题思路 22 | 23 | ```java 24 | public int StrToInt(String str) { 25 | if (str == null || str.length() == 0) 26 | return 0; 27 | boolean isNegative = str.charAt(0) == '-'; 28 | int ret = 0; 29 | for (int i = 0; i < str.length(); i++) { 30 | char c = str.charAt(i); 31 | if (i == 0 && (c == '+' || c == '-')) /* 符号判定 */ 32 | continue; 33 | if (c < '0' || c > '9') /* 非法输入 */ 34 | return 0; 35 | ret = ret * 10 + (c - '0'); 36 | } 37 | return isNegative ? -ret : ret; 38 | } 39 | ``` 40 | -------------------------------------------------------------------------------- /04数据结构及算法/code/68. 树中两个节点的最低公共祖先.md: -------------------------------------------------------------------------------- 1 | # 68. 树中两个节点的最低公共祖先 2 | 3 | 4 | ## 68.1 二叉查找树 5 | 6 | ### 题目链接 7 | 8 | [Leetcode : 235. Lowest Common Ancestor of a Binary Search Tree](https://leetcode.com/problems/lowest-common-ancestor-of-a-binary-search-tree/description/) 9 | 10 | ### 解题思路 11 | 12 | 在二叉查找树中,两个节点 p, q 的公共祖先 root 满足 root.val \>= p.val && root.val \<= q.val。 13 | 14 |

15 | 16 | ```java 17 | public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) { 18 | if (root == null) 19 | return root; 20 | if (root.val > p.val && root.val > q.val) 21 | return lowestCommonAncestor(root.left, p, q); 22 | if (root.val < p.val && root.val < q.val) 23 | return lowestCommonAncestor(root.right, p, q); 24 | return root; 25 | } 26 | ``` 27 | 28 | ## 68.2 普通二叉树 29 | 30 | ### 题目链接 31 | 32 | [Leetcode : 236. Lowest Common Ancestor of a Binary Tree](https://leetcode.com/problems/lowest-common-ancestor-of-a-binary-tree/description/) 33 | 34 | ### 解题思路 35 | 36 | 在左右子树中查找是否存在 p 或者 q,如果 p 和 q 分别在两个子树中,那么就说明根节点就是最低公共祖先。 37 | 38 |

39 | 40 | ```java 41 | public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) { 42 | if (root == null || root == p || root == q) 43 | return root; 44 | TreeNode left = lowestCommonAncestor(root.left, p, q); 45 | TreeNode right = lowestCommonAncestor(root.right, p, q); 46 | return left == null ? right : right == null ? left : root; 47 | } 48 | ``` 49 | -------------------------------------------------------------------------------- /04数据结构及算法/code/7. 重建二叉树.md: -------------------------------------------------------------------------------- 1 | # 7. 重建二叉树 2 | 3 | ## 题目链接 4 | 5 | [牛客网](https://www.nowcoder.com/practice/8a19cbe657394eeaac2f6ea9b0f6fcf6?tpId=13&tqId=11157&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) 6 | 7 | ## 题目描述 8 | 9 | 根据二叉树的前序遍历和中序遍历的结果,重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。 10 | 11 | 12 | 13 |

14 | 15 | ## 解题思路 16 | 17 | 前序遍历的第一个值为根节点的值,使用这个值将中序遍历结果分成两部分,左部分为树的左子树中序遍历结果,右部分为树的右子树中序遍历的结果。然后分别对左右子树递归地求解。 18 | 19 |

20 | 21 | ```java 22 | // 缓存中序遍历数组每个值对应的索引 23 | private Map indexForInOrders = new HashMap<>(); 24 | 25 | public TreeNode reConstructBinaryTree(int[] pre, int[] in) { 26 | for (int i = 0; i < in.length; i++) 27 | indexForInOrders.put(in[i], i); 28 | return reConstructBinaryTree(pre, 0, pre.length - 1, 0); 29 | } 30 | 31 | private TreeNode reConstructBinaryTree(int[] pre, int preL, int preR, int inL) { 32 | if (preL > preR) 33 | return null; 34 | TreeNode root = new TreeNode(pre[preL]); 35 | int inIndex = indexForInOrders.get(root.val); 36 | int leftTreeSize = inIndex - inL; 37 | root.left = reConstructBinaryTree(pre, preL + 1, preL + leftTreeSize, inL); 38 | root.right = reConstructBinaryTree(pre, preL + leftTreeSize + 1, preR, inL + leftTreeSize + 1); 39 | return root; 40 | } 41 | ``` 42 | -------------------------------------------------------------------------------- /04数据结构及算法/code/8. 二叉树的下一个结点.md: -------------------------------------------------------------------------------- 1 | # 8. 二叉树的下一个结点 2 | 3 | ## 题目链接 4 | 5 | [牛客网](https://www.nowcoder.com/practice/9023a0c988684a53960365b889ceaf5e?tpId=13&tqId=11210&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) 6 | 7 | ## 题目描述 8 | 9 | 给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点并且返回 。注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针。 10 | 11 | ```java 12 | public class TreeLinkNode { 13 | 14 | int val; 15 | TreeLinkNode left = null; 16 | TreeLinkNode right = null; 17 | TreeLinkNode next = null; // 指向父结点的指针 18 | 19 | TreeLinkNode(int val) { 20 | this.val = val; 21 | } 22 | } 23 | ``` 24 | 25 | ## 解题思路 26 | 27 | 我们先来回顾一下中序遍历的过程:先遍历树的左子树,再遍历根节点,最后再遍历右子树。所以最左节点是中序遍历的第一个节点。 28 | 29 | ```java 30 | void traverse(TreeNode root) { 31 | if (root == null) return; 32 | traverse(root.left); 33 | visit(root); 34 | traverse(root.right); 35 | } 36 | ``` 37 | 38 |

39 | 40 | 41 | 42 | ① 如果一个节点的右子树不为空,那么该节点的下一个节点是右子树的最左节点; 43 | 44 |

45 | 46 | ② 否则,向上找第一个左链接指向的树包含该节点的祖先节点。 47 | 48 |

49 | 50 | ```java 51 | public TreeLinkNode GetNext(TreeLinkNode pNode) { 52 | if (pNode.right != null) { 53 | TreeLinkNode node = pNode.right; 54 | while (node.left != null) 55 | node = node.left; 56 | return node; 57 | } else { 58 | while (pNode.next != null) { 59 | TreeLinkNode parent = pNode.next; 60 | if (parent.left == pNode) 61 | return parent; 62 | pNode = pNode.next; 63 | } 64 | } 65 | return null; 66 | } 67 | ``` 68 | -------------------------------------------------------------------------------- /04数据结构及算法/code/9. 用两个栈实现队列.md: -------------------------------------------------------------------------------- 1 | # 9. 用两个栈实现队列 2 | 3 | ## 题目链接 4 | 5 | [牛客网](https://www.nowcoder.com/practice/54275ddae22f475981afa2244dd448c6?tpId=13&tqId=11158&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking&from=cyc_github) 6 | 7 | ## 题目描述 8 | 9 | 用两个栈来实现一个队列,完成队列的 Push 和 Pop 操作。 10 | 11 | ## 解题思路 12 | 13 | in 栈用来处理入栈(push)操作,out 栈用来处理出栈(pop)操作。一个元素进入 in 栈之后,出栈的顺序被反转。当元素要出栈时,需要先进入 out 栈,此时元素出栈顺序再一次被反转,因此出栈顺序就和最开始入栈顺序是相同的,先进入的元素先退出,这就是队列的顺序。 14 | 15 |

16 | 17 | ```java 18 | Stack in = new Stack(); 19 | Stack out = new Stack(); 20 | 21 | public void push(int node) { 22 | in.push(node); 23 | } 24 | 25 | public int pop() throws Exception { 26 | if (out.isEmpty()) 27 | while (!in.isEmpty()) 28 | out.push(in.pop()); 29 | 30 | if (out.isEmpty()) 31 | throw new Exception("queue is empty"); 32 | 33 | return out.pop(); 34 | } 35 | ``` 36 | -------------------------------------------------------------------------------- /doc/Android学习知识点.xmind: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/doc/Android学习知识点.xmind -------------------------------------------------------------------------------- /doc/Android路线图.xmind: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/doc/Android路线图.xmind -------------------------------------------------------------------------------- /doc/Git 指令.xmind: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/doc/Git 指令.xmind -------------------------------------------------------------------------------- /临时文件夹/Android开发.xmind: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/临时文件夹/Android开发.xmind -------------------------------------------------------------------------------- /临时文件夹/Interview.xmind: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/临时文件夹/Interview.xmind -------------------------------------------------------------------------------- /临时文件夹/img/batch_pull_offline_messages1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/临时文件夹/img/batch_pull_offline_messages1.png -------------------------------------------------------------------------------- /临时文件夹/img/batch_pull_offline_messages2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/临时文件夹/img/batch_pull_offline_messages2.png -------------------------------------------------------------------------------- /临时文件夹/img/im_optimize.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/临时文件夹/img/im_optimize.png -------------------------------------------------------------------------------- /临时文件夹/img/im_problems.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/临时文件夹/img/im_problems.png -------------------------------------------------------------------------------- /临时文件夹/img/im_security.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/临时文件夹/img/im_security.png -------------------------------------------------------------------------------- /临时文件夹/img/im_send_file.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/临时文件夹/img/im_send_file.png -------------------------------------------------------------------------------- /临时文件夹/img/message_timeless.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/临时文件夹/img/message_timeless.png -------------------------------------------------------------------------------- /临时文件夹/img/resend_message1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/临时文件夹/img/resend_message1.png -------------------------------------------------------------------------------- /临时文件夹/img/resend_message2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/临时文件夹/img/resend_message2.png -------------------------------------------------------------------------------- /临时文件夹/img/send_message_ack.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/临时文件夹/img/send_message_ack.png -------------------------------------------------------------------------------- /临时文件夹/img/send_message_process.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/临时文件夹/img/send_message_process.png -------------------------------------------------------------------------------- /临时文件夹/img/send_message_simple.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/临时文件夹/img/send_message_simple.png -------------------------------------------------------------------------------- /临时文件夹/notebook/ARouter加载过程 .png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/临时文件夹/notebook/ARouter加载过程 .png -------------------------------------------------------------------------------- /临时文件夹/notebook/App线程优化.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/临时文件夹/notebook/App线程优化.png -------------------------------------------------------------------------------- /临时文件夹/notebook/Glide_load加载流程.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/临时文件夹/notebook/Glide_load加载流程.png -------------------------------------------------------------------------------- /临时文件夹/notebook/Glide_with加载流程.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/临时文件夹/notebook/Glide_with加载流程.png -------------------------------------------------------------------------------- /临时文件夹/notebook/Glide加载流程.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/临时文件夹/notebook/Glide加载流程.png -------------------------------------------------------------------------------- /临时文件夹/notebook/NDK入门.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/临时文件夹/notebook/NDK入门.png -------------------------------------------------------------------------------- /临时文件夹/notebook/android-stack.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/临时文件夹/notebook/android-stack.png -------------------------------------------------------------------------------- /临时文件夹/notebook/native_crash_log.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/临时文件夹/notebook/native_crash_log.png -------------------------------------------------------------------------------- /临时文件夹/notebook/业务开发安全基础.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/临时文件夹/notebook/业务开发安全基础.png -------------------------------------------------------------------------------- /临时文件夹/notebook/知识体系.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/临时文件夹/notebook/知识体系.png -------------------------------------------------------------------------------- /临时文件夹/notebook/计算机组成原理之概述篇.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/临时文件夹/notebook/计算机组成原理之概述篇.png -------------------------------------------------------------------------------- /临时文件夹/performence/APM.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/临时文件夹/performence/APM.png -------------------------------------------------------------------------------- /临时文件夹/performence/ASM3.0指南翻译.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/临时文件夹/performence/ASM3.0指南翻译.pdf -------------------------------------------------------------------------------- /临时文件夹/performence/Android_P7架构师.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/临时文件夹/performence/Android_P7架构师.png -------------------------------------------------------------------------------- /临时文件夹/performence/Android架构师成长之路 .png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/临时文件夹/performence/Android架构师成长之路 .png -------------------------------------------------------------------------------- /临时文件夹/performence/App绘制优化.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/临时文件夹/performence/App绘制优化.png -------------------------------------------------------------------------------- /临时文件夹/performence/AspectJ程序设计指南.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/临时文件夹/performence/AspectJ程序设计指南.pdf -------------------------------------------------------------------------------- /临时文件夹/performence/algorithm_map.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/临时文件夹/performence/algorithm_map.png -------------------------------------------------------------------------------- /临时文件夹/performence/android-performance.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/临时文件夹/performence/android-performance.png -------------------------------------------------------------------------------- /临时文件夹/performence/app-release-unproguard-classshark-methods-count.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/临时文件夹/performence/app-release-unproguard-classshark-methods-count.png -------------------------------------------------------------------------------- /临时文件夹/performence/app_bundle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/临时文件夹/performence/app_bundle.png -------------------------------------------------------------------------------- /临时文件夹/performence/applychanges.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/临时文件夹/performence/applychanges.png -------------------------------------------------------------------------------- /临时文件夹/performence/ci.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/临时文件夹/performence/ci.png -------------------------------------------------------------------------------- /临时文件夹/performence/class_vs_dex.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/临时文件夹/performence/class_vs_dex.png -------------------------------------------------------------------------------- /临时文件夹/performence/dex.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/临时文件夹/performence/dex.png -------------------------------------------------------------------------------- /临时文件夹/performence/dex_with_debug_item.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/临时文件夹/performence/dex_with_debug_item.png -------------------------------------------------------------------------------- /临时文件夹/performence/flutter_acrchitecture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/临时文件夹/performence/flutter_acrchitecture.png -------------------------------------------------------------------------------- /临时文件夹/performence/flutter_performance_compare.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/临时文件夹/performence/flutter_performance_compare.png -------------------------------------------------------------------------------- /临时文件夹/performence/flutter_ui_core.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/临时文件夹/performence/flutter_ui_core.png -------------------------------------------------------------------------------- /临时文件夹/performence/ftrace_architecture.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/临时文件夹/performence/ftrace_architecture.jpg -------------------------------------------------------------------------------- /临时文件夹/performence/graphic_arc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/临时文件夹/performence/graphic_arc.png -------------------------------------------------------------------------------- /临时文件夹/performence/image_format_select.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/临时文件夹/performence/image_format_select.png -------------------------------------------------------------------------------- /临时文件夹/performence/instant_run.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/临时文件夹/performence/instant_run.png -------------------------------------------------------------------------------- /临时文件夹/performence/jvm_dalivk.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/临时文件夹/performence/jvm_dalivk.png -------------------------------------------------------------------------------- /临时文件夹/performence/litho_mount_spec_lifecycle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/临时文件夹/performence/litho_mount_spec_lifecycle.png -------------------------------------------------------------------------------- /临时文件夹/performence/litho_plan.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/临时文件夹/performence/litho_plan.png -------------------------------------------------------------------------------- /临时文件夹/performence/litho_recycler.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/临时文件夹/performence/litho_recycler.png -------------------------------------------------------------------------------- /临时文件夹/performence/litho_sync.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/临时文件夹/performence/litho_sync.png -------------------------------------------------------------------------------- /临时文件夹/performence/probe.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/临时文件夹/performence/probe.jpg -------------------------------------------------------------------------------- /临时文件夹/performence/profilo_get_java_stack.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/临时文件夹/performence/profilo_get_java_stack.jpg -------------------------------------------------------------------------------- /临时文件夹/performence/readerthread.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/临时文件夹/performence/readerthread.png -------------------------------------------------------------------------------- /临时文件夹/performence/traditional_develop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/临时文件夹/performence/traditional_develop.png -------------------------------------------------------------------------------- /临时文件夹/performence/全面了解性能优化.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/临时文件夹/performence/全面了解性能优化.png -------------------------------------------------------------------------------- /临时文件夹/performence/启动器.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/临时文件夹/performence/启动器.png -------------------------------------------------------------------------------- /临时文件夹/performence/大厂职级薪资表.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/临时文件夹/performence/大厂职级薪资表.jpeg -------------------------------------------------------------------------------- /临时文件夹/开源协议.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/临时文件夹/开源协议.png -------------------------------------------------------------------------------- /临时文件夹/开源协议选择.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/临时文件夹/开源协议选择.png -------------------------------------------------------------------------------- /临时文件夹/插件化.xmind: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/临时文件夹/插件化.xmind -------------------------------------------------------------------------------- /临时文件夹/编程进阶知识图谱.xmind: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/临时文件夹/编程进阶知识图谱.xmind -------------------------------------------------------------------------------- /设计模式/CodePattern/中介者模式.md: -------------------------------------------------------------------------------- 1 | ## 中介者模式 Mediator 2 | 3 | > 提供中介类,用以降低多个对象与类之间的复杂通信 4 | 5 | - 中介类`ChatRoom` 6 | 7 | ```java 8 | public class ChatRoom{ 9 | public static void showMsg(User user,String msg){ 10 | //show user's msg 11 | } 12 | } 13 | ``` 14 | 15 | - 多个对象的类`User` 16 | 17 | ```java 18 | public class User{ 19 | private String name; 20 | 21 | public String getName() { 22 | return name; 23 | } 24 | 25 | public void setName(String name) { 26 | this.name = name; 27 | } 28 | 29 | public User(String name){ 30 | this.name = name; 31 | } 32 | //将消息 发送至 中介者,也即是聊天平台,使之对其他用户,通讯变得简单 33 | public void sendMessage(String message){ 34 | ChatRoom.showMessage(this,message); 35 | } 36 | } 37 | ``` 38 | 39 | - 演示 40 | 41 | ```java 42 | public class Demo{ 43 | public static void main(String[] args){ 44 | User a = new User("A"); 45 | User b = new User("B"); 46 | ... 47 | //公共聊天 48 | a.sendMessage("Hello everyOne"); 49 | b.sendMessage("HaHa"); 50 | } 51 | } 52 | ``` 53 | 54 | -------------------------------------------------------------------------------- /设计模式/CodePattern/享元模式.md: -------------------------------------------------------------------------------- 1 | ## 享元模式 Flyweight 2 | 3 | > 享元模式,用以减少对象创建的数量,存取复用。 4 | 5 | - `Shape` 6 | 7 | ```java 8 | public interface Shape{ 9 | void draw(); 10 | } 11 | ``` 12 | 13 | - `Circle` 14 | 15 | ```java 16 | public class Circle implements Shape{ 17 | private String color; 18 | private int x; 19 | private int y; 20 | private int radius; 21 | public Circle(String color){ 22 | this.color = color; 23 | } 24 | public void setX(int x){ 25 | this.x = x; 26 | } 27 | public void setY(int y){ 28 | this.y = y; 29 | } 30 | public void setRadiud(int radius){ 31 | this.radius = radius; 32 | } 33 | 34 | @override 35 | public void draw(){ 36 | //draw circle with x,y,radius,and color 37 | } 38 | } 39 | 40 | ``` 41 | 42 | - `ShapeFactory` 43 | 44 | ```java 45 | public class ShapeFactory{ 46 | private static final HashMap shapes = new HashMap(); 47 | public static Shape getCircle(String color){ 48 | Circle circle = shapes.get(color); 49 | if(circle==null){ 50 | circle = new Circle(color); 51 | shapes.put(color,circle); 52 | } 53 | return circle; 54 | } 55 | } 56 | ``` 57 | 58 | - 演示 59 | 60 | ```java 61 | public class Demo{ 62 | private static final String[] colors = {"Red","Yellow","Green","Pin"}; 63 | public static void main(String[] args){ 64 | for(int i=0;i<20;i++){ 65 | //draw many circle with random color use flyweight pattern 66 | } 67 | } 68 | } 69 | ``` 70 | 71 | -------------------------------------------------------------------------------- /设计模式/CodePattern/代理模式.md: -------------------------------------------------------------------------------- 1 | ## 代理模式 Proxy Pattern 2 | 3 | > 代理者代表真实对象接受访问。 4 | 5 | - `Image` 6 | 7 | ```java 8 | public interface Image{ 9 | void display(); 10 | } 11 | ``` 12 | 13 | - `RealImage` 14 | 15 | ```java 16 | public class RealImage implements Image{ 17 | private String fileName; 18 | public RealImage(String fileName){ 19 | this.fileName = fileName; 20 | loadImage(); 21 | } 22 | @override 23 | public void display(){ 24 | //show image 25 | } 26 | private void loadImage(){ 27 | //load image 28 | } 29 | } 30 | ``` 31 | 32 | - `ProxyImage` 33 | 34 | ```java 35 | public class ProxyImage implements Image{ 36 | private RealImage real; 37 | private String fileName; 38 | public ProxyImage(String fileName){ 39 | this.fileName = fileName; 40 | } 41 | 42 | @override 43 | public void display(){ 44 | if(real==null){ 45 | real = new RealImage(fileName); 46 | } 47 | real.display(); 48 | } 49 | } 50 | ``` 51 | 52 | - 演示 53 | 54 | ```java 55 | public class Demo{ 56 | public static void main(String[] args){ 57 | ProxyImage image = new ProxyImage("fileName"); 58 | image.display();//第一次,将会加载,loadImage 59 | // 60 | image.diaplsy();//这次,就会直接复用,而不用再次调用loadImage 61 | } 62 | } 63 | ``` 64 | 65 | -------------------------------------------------------------------------------- /设计模式/CodePattern/命令模式.md: -------------------------------------------------------------------------------- 1 | ## 命令模式 Command 2 | 3 | > 数据驱动型,请求以命令形式封装于对象中。传给调用对象。 4 | 5 | - 定义接口`Order` 6 | 7 | ```java 8 | public interface Order{ 9 | void execute(); 10 | } 11 | ``` 12 | 13 | - 请求类 14 | 15 | ```java 16 | public class Stock{ 17 | private String name="ABC"; 18 | private int quantity = 10; 19 | //模拟股票的 buy,sell操作 20 | public void buy(){ 21 | //buy some stock 22 | } 23 | public void sell(){ 24 | //sell some stock 25 | } 26 | } 27 | ``` 28 | 29 | - 封装实际的操作指令对象类 30 | 31 | 1. `BuyOrder` 32 | 33 | ```java 34 | public class BuyOrder implements Order{ 35 | private Stock abc;//持有的股票 36 | public BuyOrder(Stock stock){ 37 | abc = stock; 38 | } 39 | //指令的具体操作 40 | @override 41 | public void execute(){ 42 | abc.buy(); 43 | } 44 | } 45 | ``` 46 | 47 | 2. `SellOrder` 48 | 49 | ```java 50 | public class SellOrder implements Order{ 51 | private Stock abc; 52 | public SellOrder(Stock stock){ 53 | abc = stock; 54 | } 55 | @override 56 | public void execute(){ 57 | abc.sell(); 58 | } 59 | } 60 | ``` 61 | 62 | - 操盘手`Broker` 63 | 64 | ```java 65 | public class Broker{ 66 | private List orders = new ArrayList(); 67 | 68 | public void add(Order order){ 69 | orders.add(order); 70 | } 71 | //执行所有的指令 72 | public void run(){ 73 | for(Order od:orders){ 74 | od.execute(); 75 | } 76 | orders.clear(); 77 | } 78 | } 79 | ``` 80 | 81 | - 演示 82 | 83 | ```java 84 | public class Demo{ 85 | public static void main(String[] args){ 86 | Stock stock = new Stock(); 87 | BuyOrder buy = new BuyOrder(stock); 88 | SellOrder sell = new SellOrder(stock); 89 | 90 | Broker broker = new Broker(); 91 | broker.add(buy); 92 | broker.add(sell); 93 | //开始执行 94 | broker.run(); 95 | } 96 | } 97 | ``` 98 | 99 | 100 | 101 | -------------------------------------------------------------------------------- /设计模式/CodePattern/备忘录模式.md: -------------------------------------------------------------------------------- 1 | ## 备忘录模式 Memento 2 | 3 | > 保存对象某个状态,适时恢复 4 | 5 | - `Memento` 6 | 7 | ```java 8 | public class Memento{ 9 | private int state; 10 | public Memento(int state){ 11 | this.state = state; 12 | } 13 | public int getState(){ 14 | return state; 15 | } 16 | } 17 | ``` 18 | 19 | 20 | 21 | - `Originator`原始对象类 22 | 23 | ```java 24 | public class Originator{ 25 | private int state; 26 | public void setState(int state){ 27 | this.state = state; 28 | } 29 | public int getState(){ 30 | return state; 31 | } 32 | public Memento saveToMemento(){ 33 | return new Memento(state); 34 | } 35 | public void getStateFromMemento(Memento me){ 36 | this.state = me.getState();//此处,就是恢复对象的状态 37 | } 38 | } 39 | ``` 40 | 41 | - `CareTaker`操作控制类 42 | 43 | ```java 44 | public class CareTaker{ 45 | private List mList = new ArrayList(); 46 | public void add(Memento me){ 47 | mList.add(me); 48 | } 49 | public Memento get(int index){ 50 | mList.get(index); 51 | } 52 | } 53 | ``` 54 | 55 | - 演示 56 | 57 | ```java 58 | public class Demo{ 59 | public static void main(String[] args){ 60 | Originator orig = new Originator(); 61 | CareTaker taker = new CareTaker(); 62 | //开始状态 63 | orig.setState(2); 64 | orig.setState(3); 65 | //开启备忘录 66 | taker.add(orig.saveToMemento()); 67 | orig.setState(4); 68 | taker.add(orig.saveToMemento); 69 | orig.setState(5); 70 | //从备忘录恢复 71 | orig.getStateFromMemento(taker.get(0));//恢复第一个备份 72 | } 73 | } 74 | ``` 75 | 76 | -------------------------------------------------------------------------------- /设计模式/CodePattern/外观模式.md: -------------------------------------------------------------------------------- 1 | ## 外观模式 Facade 2 | 3 | > 用于隐藏系统内部的复杂性,对外表现的简单统一 4 | 5 | - `Shape` 6 | 7 | ```java 8 | public interface Shape{ 9 | void draw(); 10 | } 11 | ``` 12 | 13 | - `Rectange` 14 | 15 | ```java 16 | public class Rectange implements Shape{ 17 | @override 18 | public void draw(){ 19 | // draw a rect 20 | } 21 | } 22 | ``` 23 | 24 | - `Circle` 25 | 26 | ```java 27 | public class Circle implements Shape{ 28 | @override 29 | public void draw(){ 30 | //draw a circle 31 | } 32 | } 33 | ``` 34 | 35 | - `ShapeMaker`对外的统一管理者,外交接口,接待外部调用。 36 | 37 | ```java 38 | public class ShapeMaker{ 39 | private Shape circle; 40 | private Shape rect; 41 | public ShapeMaker(){ 42 | circle = new Circle(); 43 | rect = new Rectange(); 44 | } 45 | //统一对外的调用函数,如此省去了调用方分别调用太多的具体类。 46 | public void drawCircle(){ 47 | circle.draw(); 48 | } 49 | public void drawRect(){ 50 | rect.draw(); 51 | } 52 | } 53 | ``` 54 | 55 | - 演示 56 | 57 | ```java 58 | public class Demo{ 59 | public static void main(String[] args){ 60 | ShapeMaker maker = new ShapeMaker(); 61 | maker.drawCircle(); 62 | maker.drawRect(); 63 | } 64 | } 65 | ``` 66 | 67 | -------------------------------------------------------------------------------- /设计模式/CodePattern/桥接模式.md: -------------------------------------------------------------------------------- 1 | #### 桥接模式 Bridge 2 | 3 | > 桥接模式,是接口与抽象解耦,充当**桥梁**作用的接口。 4 | 5 | - 桥梁接口`ColorAPI`实现color与shape的桥接 6 | 7 | ```java 8 | public interface ColorAPI{ 9 | void fillColor(); 10 | } 11 | ``` 12 | 13 | - RedColor,GreenColor 14 | 15 | ```java 16 | public class RedColor implements ColorAPI{ 17 | @override 18 | public void fillColor(){ 19 | //fill Red color 20 | } 21 | } 22 | ``` 23 | 24 | ```java 25 | public class GreenColor implements ColorAPI{ 26 | @override 27 | public void fillColor(){ 28 | //fill Green color 29 | } 30 | } 31 | ``` 32 | 33 | 34 | - Shape`抽象类 35 | 36 | ```java 37 | public abstract class Shape{ 38 | protected ColorAPI colorApi; 39 | public Shape(ColorAPI color){ 40 | this.colorApi = color; 41 | } 42 | abstract void draw(); 43 | } 44 | ``` 45 | 46 | - `Square` 47 | 48 | ```java 49 | public class Square extends Shape{ 50 | private int a;//边长 51 | public Square(ColorAPI color,int a){ 52 | super(color); 53 | this.a = a; 54 | } 55 | 56 | @override 57 | public void draw(){ 58 | colorApi.fillColor(); 59 | //draw a square with color; 60 | } 61 | } 62 | ``` 63 | 64 | //演示 65 | 66 | - Demo 67 | 68 | ```java 69 | public class Demo{ 70 | public static void main(String[] args){ 71 | Shape redSquare = new Square(new RedColor(),12); 72 | redSquare.draw(); 73 | //绘制绿色四方形 74 | Shape green = new Square(new GreenColor(),36); 75 | green.draw(); 76 | } 77 | } 78 | ``` 79 | 80 | -------------------------------------------------------------------------------- /设计模式/CodePattern/模版模式.md: -------------------------------------------------------------------------------- 1 | ## 模版模式 Template 2 | 3 | > 在抽象类中公开定义算法逻辑与步骤,有子类具体实现。 4 | 5 | - 抽象类 游戏`Game` 6 | 7 | ```java 8 | public abstract class Game{ 9 | abstract void initialize(); 10 | abstract void start(); 11 | abstract void end(); 12 | //template 13 | public final void play(){ 14 | initialize(); 15 | start(); 16 | end(); 17 | } 18 | } 19 | ``` 20 | 21 | - 具体实现类`Football` 22 | 23 | ```java 24 | public class Football extends Game{ 25 | @override 26 | public void initialize(){ 27 | //football init 28 | } 29 | @override 30 | public void start(){ 31 | //football start 32 | } 33 | @override 34 | public void end(){ 35 | //football end 36 | } 37 | } 38 | ``` 39 | 40 | - 演示 41 | 42 | ```java 43 | public class Demo{ 44 | public static void main(String[] args){ 45 | Game game = new Football(); 46 | game.play(); 47 | //可以有多种Game的子类,其play的步骤将是一致的,但是具体内容确是差异化的。 48 | } 49 | } 50 | ``` 51 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /设计模式/CodePattern/状态模式.md: -------------------------------------------------------------------------------- 1 | ## 状态模式 State 2 | 3 | > 类的行为,基于其状态的变化而改变 4 | 5 | - 状态接口`State` 6 | 7 | ```java 8 | public interface State{ 9 | void action(Context context); 10 | } 11 | ``` 12 | 13 | 1. 实现类`StartState` 14 | 15 | ```java 16 | public class StartState implements State{ 17 | @override 18 | public void action(Context context){ 19 | //start state 20 | context.setState(this); 21 | } 22 | public String toString(){ 23 | return "this is start state"; 24 | } 25 | } 26 | ``` 27 | 28 | 2. `StopState` 29 | 30 | ```java 31 | public class StopState implements State{ 32 | @override 33 | public void action(Context context){ 34 | //stop state 35 | context.setState(this); 36 | } 37 | public String toString(){ 38 | return "this is stop state"; 39 | } 40 | } 41 | ``` 42 | 43 | - Context 44 | 45 | ```java 46 | public class Context { 47 | private State state; 48 | public Context(){ 49 | state = null; 50 | } 51 | public void setState(State state){ 52 | this.state = state; 53 | } 54 | public State getState(){ 55 | return state; 56 | } 57 | } 58 | ``` 59 | 60 | 61 | 62 | - 演示 63 | 64 | ```java 65 | public class Demo{ 66 | public static void main(String[] args){ 67 | Context cxt = new Context(); 68 | StartState start = new StartState(); 69 | start.action(cxt); 70 | //当前状态就是start 71 | StopState stop = new StopState(); 72 | stop.action(cxt); 73 | //当前状态,就成了stop状态。 74 | } 75 | } 76 | ``` 77 | 78 | -------------------------------------------------------------------------------- /设计模式/CodePattern/空对象模式.md: -------------------------------------------------------------------------------- 1 | ## 空对象模式 Null Object 2 | 3 | > 创建一个空对象,用于作为默认,取代null 4 | 5 | - `AbsImage` 6 | 7 | ```java 8 | public abstract class AbsImage{ 9 | protected String name; 10 | public abstract boolean isOK(); 11 | public abstract String getName(); 12 | } 13 | ``` 14 | 15 | 1. `PngImage` 16 | 17 | ```java 18 | public class RealImage extends AbsImage{ 19 | public RealImage(String name){ 20 | this.name = name; 21 | } 22 | @override 23 | public boolean isOK(){ 24 | return true; 25 | } 26 | @override 27 | public String getName(){ 28 | return name; 29 | } 30 | } 31 | ``` 32 | 33 | 2. `NullImage` 34 | 35 | ```java 36 | public class NullImage extends AbsImage{ 37 | @override 38 | public boolean isOK(){ 39 | return false; 40 | } 41 | @override 42 | public String getName(){ 43 | return "This is a Null Image"; 44 | } 45 | } 46 | ``` 47 | 48 | 3. `ImageFactory` 49 | 50 | ```java 51 | public class ImageFactory{ 52 | public static final names= {"png","jpg","jpeg","bmp"}; 53 | 54 | public static AbsImage getImage(String name){ 55 | if(names.contains(name)){ 56 | return new RealImage(name); 57 | } 58 | //如果没有,就返回默认的null对象 59 | return NullImage(); 60 | } 61 | } 62 | ``` 63 | 64 | 65 | - 演示 66 | 67 | ```java 68 | public class Demo{ 69 | public static void main(String[] args){ 70 | ImageFactory.getImage("png");//存在, 71 | ImageFactory.getImage("avi");//不存在,则返回的是NullImage对象。 72 | } 73 | } 74 | ``` 75 | 76 | 77 | 78 | -------------------------------------------------------------------------------- /设计模式/CodePattern/策略模式.md: -------------------------------------------------------------------------------- 1 | ## 策略模式 Strategy 2 | 3 | > 运行时,改变类的算法或行为逻辑 4 | 5 | - 定义策略接口`Strategy` 6 | 7 | ```java 8 | public interface Strategy{ 9 | int action(int num1,int num2); 10 | } 11 | ``` 12 | 13 | 1. 策略实现`Add` 14 | 15 | ```java 16 | public class Add implements Strategy{ 17 | @override 18 | public int action(int num1,int num2){ 19 | return num1+num2; 20 | } 21 | } 22 | ``` 23 | 24 | 2. `Sub` 25 | 26 | ```java 27 | public class Sub implements Strategy{ 28 | @override 29 | public int action(int num1,int num2){ 30 | return num1-num2; 31 | } 32 | } 33 | ``` 34 | 35 | - context类,策略管控 36 | 37 | ```java 38 | public class Context { 39 | private Strategy st; 40 | public Context(Strategy stra){ 41 | this.st = stra; 42 | } 43 | public void exeStrategy(int num1,int num2){ 44 | st.action(num1,num2); 45 | } 46 | } 47 | ``` 48 | 49 | - 演示 50 | 51 | ```java 52 | public class Demo{ 53 | public static void main(Strig[] args){ 54 | Context a = new Context(new Add()); 55 | a.exeStrategy(1,3);//执行一种策略 56 | Context b = new Context(new Sub()); 57 | b.exeStrategy(2,6);//又是一种策略 58 | } 59 | } 60 | ``` 61 | 62 | -------------------------------------------------------------------------------- /设计模式/CodePattern/简单工厂模式.md: -------------------------------------------------------------------------------- 1 | #### 简单工厂模式 SimpleFactory 2 | 3 | > *简单工厂模式,封装对象的创建,适用于**同类多批次**的对象创建* 4 | 5 | - Shape 6 | 7 | ```java 8 | public interface Shape{ 9 | void draw(); 10 | } 11 | ``` 12 | 13 | - 具体的图形类,实现`Shape`接口 14 | 15 | - Circle 16 | 17 | ```java 18 | public class Circle implements Shape{ 19 | @override 20 | public void draw(){ 21 | //draw a circle 22 | } 23 | } 24 | ``` 25 | 26 | - Rectangle 27 | 28 | ```java 29 | public class Rectangle implements Shape{ 30 | @override 31 | public void draw(){ 32 | //draw a rectangle 33 | } 34 | } 35 | ``` 36 | 37 | - Square 38 | 39 | ```java 40 | public class Square implements Shape{ 41 | @override 42 | public void draw(){ 43 | //draw a square 44 | } 45 | } 46 | ``` 47 | 48 | - 图形对象的简单工厂类 49 | 50 | ```java 51 | public class ShapeFactory{ 52 | public Shape getShape(String shape){ 53 | if(shape.equals("circle")){ 54 | return new Circle(); 55 | }else if(shape.equals("square")){ 56 | return new Square(); 57 | }else if(shape.equals("rect")){ 58 | return new Rectangle(); 59 | } 60 | } 61 | } 62 | ``` 63 | 64 | ***演示*** 65 | 66 | ```java 67 | public class Demo{ 68 | public static void main(String[] args){ 69 | ShapeFactory factory = new ShapeFactory(); 70 | Shape cirle = factory.getShape("circle"); 71 | circle.draw(); 72 | Shape square = factory.getShape("square"); 73 | square.draw(); 74 | ... 75 | } 76 | } 77 | ``` -------------------------------------------------------------------------------- /设计模式/CodePattern/组合模式.md: -------------------------------------------------------------------------------- 1 | #### 组合模式 Component 2 | 3 | > 又称部分整体模式,用于把一组相似的对象当作一个单一的对象 4 | 5 | - `Soldier`军人类,可以为军官,也可以是士官,或者列兵 6 | 7 | ```java 8 | public class Soldier{ 9 | private String name; 10 | private String dept; 11 | private int level; 12 | private List sub;//下属弟兄 13 | 14 | public Soldier(String name,String dept,int level){ 15 | this.name = name; 16 | this.dept = dept; 17 | this.level = level; 18 | sub = new ArrayList<>(); 19 | } 20 | public void add(Soldier s){ 21 | sub.add(s); 22 | } 23 | public void removed(Soldier s){ 24 | sub.remove(s); 25 | } 26 | 27 | public List getSub(){ 28 | return sub; 29 | } 30 | public String toString(){ 31 | return all string; 32 | } 33 | } 34 | ``` 35 | 36 | 37 | 38 | ###### 演示 39 | 40 | ```java 41 | public class Demo{ 42 | public static void main(String[] args){ 43 | //军长 44 | Soldier commander = new Soldier("A","FA",0); 45 | Soldier processer = new Soldier("G","FA",4); 46 | Soldier s1 = new Soldier("S1","FA",9); 47 | 48 | commander.add(processer); 49 | processer.add(s1); 50 | 51 | } 52 | } 53 | ``` 54 | 55 | -------------------------------------------------------------------------------- /设计模式/CodePattern/装饰器模式.md: -------------------------------------------------------------------------------- 1 | ## 装饰器模式 Decorator 2 | 3 | > 不改变现有对象内部结构的情况下,为之新增功能和特性 4 | 5 | - `Shape` 6 | 7 | ```java 8 | public interface Shape{ 9 | void draw(); 10 | } 11 | ``` 12 | 13 | - `Circle` 14 | 15 | ```java 16 | public class Circle implements Shape{ 17 | @override 18 | public void draw(){ 19 | //draw a circle 20 | } 21 | } 22 | ``` 23 | 24 | - `Rectange` 25 | 26 | ```java 27 | public class Rectange implements Shape{ 28 | @override 29 | public void draw(){ 30 | //draw a rect 31 | } 32 | } 33 | ``` 34 | 35 | - `ShapeDecorator` 36 | 37 | ```java 38 | public abstract class ShapeDecorator implements Shape { 39 | protected Shape decoratorShape; 40 | public ShapeDecorator(Shape shape){ 41 | this.decoratorShape = shape; 42 | } 43 | @override 44 | public void draw(){ 45 | decoratorShape.draw(); 46 | } 47 | } 48 | ``` 49 | 50 | - `RedDecorator` 51 | 52 | ```java 53 | public class RedDecorator extends ShapeDecorator{ 54 | public RedDecorator(Shape shape){ 55 | super(shape); 56 | } 57 | @override 58 | public void draw(){ 59 | decoratorShape.draw(); 60 | drawRed(decoratorShape); 61 | } 62 | private void drawRed(Shape shape){ 63 | //shape draw a red border 64 | } 65 | } 66 | ``` 67 | 68 | - 演示 69 | 70 | ```java 71 | public class Demo{ 72 | public static void main(String[] args){ 73 | Shape circle = new Circle(); 74 | Shape redCircle = new RedDecorator(circle); 75 | redCircle.draw();//这就是新增了原有对象的扩展功能和特性。 76 | } 77 | } 78 | ``` 79 | 80 | 81 | 82 | -------------------------------------------------------------------------------- /设计模式/CodePattern/观察者模式.md: -------------------------------------------------------------------------------- 1 | ## 观察者模式 Observer 2 | 3 | > 一对多只关系,一被修改,多会响应 4 | 5 | - 被观察者`Subject` 6 | 7 | ```java 8 | public class Subject{ 9 | private int state; 10 | private List observers = new ArrayList(); 11 | 12 | public void setState(int state){ 13 | this.state = state; 14 | //notify All 15 | notifyAll(); 16 | } 17 | public int getState(){ 18 | return state; 19 | } 20 | 21 | public void regist(Observer observer){ 22 | observers.add(observer); 23 | } 24 | 25 | public void notifyAll(){ 26 | for(Observer ob:observers){ 27 | ob.update(); 28 | } 29 | } 30 | } 31 | ``` 32 | 33 | - 观察者`Observer`抽象类,子类具体实现逻辑 34 | 35 | ```java 36 | public abstract class Observer{ 37 | protected Subject sub; 38 | public abstract void update(); 39 | } 40 | ``` 41 | 42 | ​ -子类继承`OneObserver` 43 | 44 | ```java 45 | public class OneObserver extends Observer{ 46 | public OneObserver(Subject sub){ 47 | this.sub = sub; 48 | sub.regist(this); 49 | } 50 | @override 51 | public void update(){ 52 | //update when notified 53 | } 54 | } 55 | ``` 56 | 57 | - 演示 58 | 59 | ```java 60 | public class Demo{ 61 | public static void main(String[] args){ 62 | Subject sub = new Subject(); 63 | Observer ob = new OneObserver(sub); 64 | //更新sub 65 | sub.setState(2);//如此,多有注册的Observer均能收到通知。 66 | } 67 | } 68 | ``` 69 | 70 | -------------------------------------------------------------------------------- /设计模式/CodePattern/解释器模式.md: -------------------------------------------------------------------------------- 1 | ## 解释器模式 Interpreter 2 | 3 | > 使用接口,解释特定上下文。 4 | 5 | - 创建表达式接口,及其实现类`Expression` 6 | 7 | ```java 8 | public interface Expression{ 9 | boolean interpret(String context); 10 | } 11 | ``` 12 | 13 | 1. `TerminalExpression` 14 | 15 | ```java 16 | public class TerminalExpression implements Expression{ 17 | private String data;//特定条件 18 | public TerminalExpression(String data){ 19 | this.data = data; 20 | } 21 | @override 22 | public boolean interpret(String context){ 23 | return context.contains(data);// 24 | } 25 | } 26 | ``` 27 | 28 | 2. `OrExpression` 29 | 30 | ```java 31 | private Expression expr1 = null; 32 | private Expression expr2 = null; 33 | 34 | public OrExpression(Expression expr1, Expression expr2) { 35 | this.expr1 = expr1; 36 | this.expr2 = expr2; 37 | } 38 | //条件匹配 39 | @Override 40 | public boolean interpret(String context) { 41 | return expr1.interpret(context) || expr2.interpret(context); 42 | } 43 | ``` 44 | 45 | - 演示 46 | 47 | ```java 48 | //有点类似过滤器模式, 49 | public class InterpreterPatternDemo { 50 | 51 | //规则:Robert 和 John 是男性 52 | public static Expression getMaleExpression(){ 53 | Expression robert = new TerminalExpression("Robert"); 54 | Expression john = new TerminalExpression("John"); 55 | return new OrExpression(robert, john); 56 | } 57 | 58 | public static void main(String[] args) { 59 | Expression isMale = getMaleExpression(); 60 | 61 | System.out.println("John is male? " + isMale.interpret("John")); 62 | } 63 | } 64 | ``` 65 | 66 | -------------------------------------------------------------------------------- /设计模式/CodePattern/访问者模式.md: -------------------------------------------------------------------------------- 1 | ## 访问者模式 Visitor 2 | 3 | > 创建访问者类,动态改变元素类的算法逻辑。 4 | 5 | - 创建元素的接口`Part` 6 | 7 | ```java 8 | public interface Part{ 9 | void accept(Visitor visitor); 10 | } 11 | ``` 12 | 13 | 1. `Keyboard` 14 | 15 | ```java 16 | public class Keyboard implements Part{ 17 | @override 18 | public void accept(Visitor visitor){ 19 | visitor.visit(this);//接受,并显示当前对象 20 | } 21 | } 22 | ``` 23 | 24 | 2. `Monitor` 25 | 26 | ```java 27 | public class Monitor implements Part{ 28 | @override 29 | public void accept (Visitor visitor){ 30 | visitor.visit(this); 31 | } 32 | } 33 | ``` 34 | 35 | 3. `Mouse` 类似 36 | 37 | 4. 综合`Computer`综合显示真个组成。 38 | 39 | ```java 40 | public class Computer implements Part{ 41 | Part parts; 42 | public Computer(){ 43 | parts = new Part[]{new Mouse(),new Monitor(),new Keyboard()}; 44 | } 45 | @override 46 | public void accept(Visitor visitor){ 47 | for(int i=0;i 为请求创建一条处理响应链。 4 | 5 | - 日志为例`AbsLogger` 6 | 7 | ```java 8 | public abstract class AbsLogger{ 9 | public static final int INFO = 1; 10 | public static final int DEBUG = 2; 11 | public static final int ERROR = 3; 12 | protected int level; 13 | protected AbsLogger nextLogger;//责任链中的下一环 14 | 15 | public void setNext(AbsLogger logger){ 16 | this.nextLogger = logger; 17 | } 18 | public void showMsg(int level ,String msg){ 19 | //日志log的向下兼容显示, 20 | if(this.level<=level){ 21 | write(msg); 22 | } 23 | //逐级显示 24 | if(nextLogger!=null){ 25 | nextLogger.showMsg(level,msg); 26 | } 27 | } 28 | 29 | abstract void write(String msg); 30 | } 31 | ``` 32 | 33 | ​ `InfoLogger` 34 | 35 | ```java 36 | public class InfoLogger extends AbsLogger{ 37 | public InfoLogger(int level){ 38 | this.level = level; 39 | } 40 | @override 41 | public void write(String msg){ 42 | //write msg as info level 43 | } 44 | } 45 | ``` 46 | 47 | ​ `ErrorLogger` & `DebugLogger`类似 48 | 49 | - 演示 50 | 51 | ```java 52 | public class Demo{ 53 | //先提供一个层级较高的logger 54 | private static AbsLogger getLogger(){ 55 | AbsLogger errorLogger = new ErrorLogger(); 56 | AbsLogger debugLogger = new DebugLogger(); 57 | AbsLogger infoLogger = new InfoLogger(); 58 | //串联向下的层级 59 | errorLogger.setNext(debugLogger); 60 | debugLogger.setNext(infoLogger); 61 | 62 | return errorLogger; 63 | } 64 | 65 | public static void main(String[] args){ 66 | AbsLogger logger = getLogger(); 67 | //分级显示log 68 | logger.showMsg(AbsLogger.INFO,"info log"); 69 | logger.showMsg(AbsLogger.ERROR,"Error log"); 70 | } 71 | } 72 | ``` 73 | 74 | 75 | 76 | -------------------------------------------------------------------------------- /设计模式/CodePattern/过滤器模式.md: -------------------------------------------------------------------------------- 1 | ## 过滤器模式 Filter/Criteria 2 | 3 | > 适配条件筛选数据 4 | 5 | - `Person` 6 | 7 | ```java 8 | public class Person{ 9 | private String name; 10 | private String gender; 11 | private String maritalStatus; 12 | 13 | public Person(String name,String gender,String maritalStatus){ 14 | this.name = name; 15 | this.gender = gender; 16 | this.maritalStatus = maritalStatus; 17 | } 18 | 19 | public String getName() { 20 | return name; 21 | } 22 | public String getGender() { 23 | return gender; 24 | } 25 | public String getMaritalStatus() { 26 | return maritalStatus; 27 | } 28 | } 29 | ``` 30 | 31 | - `Rule` 32 | 33 | ```java 34 | public interface Rule{ 35 | List matchData(List persons); 36 | } 37 | ``` 38 | 39 | - `MarriedRule` 40 | 41 | ```java 42 | public class MarriedRule implements Rule{ 43 | @override 44 | public List matchData(List persons){ 45 | // 匹配筛选出,已婚的数据 46 | } 47 | } 48 | ``` 49 | 50 | - `MaleRule` 51 | 52 | ```java 53 | public class MaleRule implements Rule{ 54 | @override 55 | public List matchData(List persons){ 56 | // 匹配筛选出,男士的数据 57 | } 58 | } 59 | ``` 60 | 61 | - 演示 62 | 63 | ```java 64 | public class Demo{ 65 | public static void main(String[] args){ 66 | List persons;//假设已经存在许多条数据 67 | Rule man = new MaleRule(); 68 | man.matchData(persons);//得到的返回结果,就是筛选后的, 69 | } 70 | } 71 | ``` 72 | 73 | 74 | 75 | -------------------------------------------------------------------------------- /设计模式/CodePattern/迭代器模式.md: -------------------------------------------------------------------------------- 1 | ## 迭代器模式 Iterator 2 | 3 | > 顺序访问集合对象的元素,而不关心其内部的实现 4 | 5 | - 创建容器,与迭代器接口 6 | 7 | 1. `Iterator` 8 | 9 | ```java 10 | public interface Iterator{ 11 | boolean hasNext(); 12 | Object next(); 13 | } 14 | ``` 15 | 16 | 2. `Container` 17 | 18 | ```java 19 | public interface Container{ 20 | Iterator getIterator(); 21 | } 22 | ``` 23 | 24 | - 实现类 25 | 26 | ```java 27 | public class NameSpace implements Container{ 28 | private String[] names = {"A","B","C","D"}; 29 | @override 30 | public Iterator getIterator(){ 31 | return new NameIterator(); 32 | } 33 | private class NameIterator implements Iterator{ 34 | int index; 35 | @override 36 | public boolean hasNext(){ 37 | return index
10 | 11 | ### Implementation 12 | 13 | ```java 14 | public abstract class Prototype { 15 | abstract Prototype myClone(); 16 | } 17 | ``` 18 | 19 | ```java 20 | public class ConcretePrototype extends Prototype { 21 | 22 | private String filed; 23 | 24 | public ConcretePrototype(String filed) { 25 | this.filed = filed; 26 | } 27 | 28 | @Override 29 | Prototype myClone() { 30 | return new ConcretePrototype(filed); 31 | } 32 | 33 | @Override 34 | public String toString() { 35 | return filed; 36 | } 37 | } 38 | ``` 39 | 40 | ```java 41 | public class Client { 42 | public static void main(String[] args) { 43 | Prototype prototype = new ConcretePrototype("abc"); 44 | Prototype clone = prototype.myClone(); 45 | System.out.println(clone.toString()); 46 | } 47 | } 48 | ``` 49 | 50 | ```html 51 | abc 52 | ``` 53 | 54 | ### JDK 55 | 56 | - [java.lang.Object#clone()](http://docs.oracle.com/javase/8/docs/api/java/lang/Object.html#clone%28%29) 57 | -------------------------------------------------------------------------------- /设计模式/DesignPattern/设计模式 - 外观.md: -------------------------------------------------------------------------------- 1 | ## 外观(Facade) 2 | 3 | ### Intent 4 | 5 | 提供了一个统一的接口,用来访问子系统中的一群接口,从而让子系统更容易使用。 6 | 7 | ### Class Diagram 8 | 9 |

10 | 11 | ### Implementation 12 | 13 | 观看电影需要操作很多电器,使用外观模式实现一键看电影功能。 14 | 15 | ```java 16 | public class SubSystem { 17 | public void turnOnTV() { 18 | System.out.println("turnOnTV()"); 19 | } 20 | 21 | public void setCD(String cd) { 22 | System.out.println("setCD( " + cd + " )"); 23 | } 24 | 25 | public void startWatching(){ 26 | System.out.println("startWatching()"); 27 | } 28 | } 29 | ``` 30 | 31 | ```java 32 | public class Facade { 33 | private SubSystem subSystem = new SubSystem(); 34 | 35 | public void watchMovie() { 36 | subSystem.turnOnTV(); 37 | subSystem.setCD("a movie"); 38 | subSystem.startWatching(); 39 | } 40 | } 41 | ``` 42 | 43 | ```java 44 | public class Client { 45 | public static void main(String[] args) { 46 | Facade facade = new Facade(); 47 | facade.watchMovie(); 48 | } 49 | } 50 | ``` 51 | 52 | ### 设计原则 53 | 54 | 最少知识原则:只和你的密友谈话。也就是说客户对象所需要交互的对象应当尽可能少。 55 | -------------------------------------------------------------------------------- /设计模式/DesignPattern/设计模式 - 工厂方法.md: -------------------------------------------------------------------------------- 1 | ## 工厂方法(Factory Method) 2 | 3 | ### Intent 4 | 5 | 定义了一个创建对象的接口,但由子类决定要实例化哪个类。工厂方法把实例化操作推迟到子类。 6 | 7 | ### Class Diagram 8 | 9 | 在简单工厂中,创建对象的是另一个类,而在工厂方法中,是由子类来创建对象。 10 | 11 | 下图中,Factory 有一个 doSomething() 方法,这个方法需要用到一个产品对象,这个产品对象由 factoryMethod() 方法创建。该方法是抽象的,需要由子类去实现。 12 | 13 |

14 | 15 | ### Implementation 16 | 17 | ```java 18 | public abstract class Factory { 19 | abstract public Product factoryMethod(); 20 | public void doSomething() { 21 | Product product = factoryMethod(); 22 | // do something with the product 23 | } 24 | } 25 | ``` 26 | 27 | ```java 28 | public class ConcreteFactory extends Factory { 29 | public Product factoryMethod() { 30 | return new ConcreteProduct(); 31 | } 32 | } 33 | ``` 34 | 35 | ```java 36 | public class ConcreteFactory1 extends Factory { 37 | public Product factoryMethod() { 38 | return new ConcreteProduct1(); 39 | } 40 | } 41 | ``` 42 | 43 | ```java 44 | public class ConcreteFactory2 extends Factory { 45 | public Product factoryMethod() { 46 | return new ConcreteProduct2(); 47 | } 48 | } 49 | ``` 50 | 51 | ### JDK 52 | 53 | - [java.util.Calendar](http://docs.oracle.com/javase/8/docs/api/java/util/Calendar.html#getInstance--) 54 | - [java.util.ResourceBundle](http://docs.oracle.com/javase/8/docs/api/java/util/ResourceBundle.html#getBundle-java.lang.String-) 55 | - [java.text.NumberFormat](http://docs.oracle.com/javase/8/docs/api/java/text/NumberFormat.html#getInstance--) 56 | - [java.nio.charset.Charset](http://docs.oracle.com/javase/8/docs/api/java/nio/charset/Charset.html#forName-java.lang.String-) 57 | - [java.net.URLStreamHandlerFactory](http://docs.oracle.com/javase/8/docs/api/java/net/URLStreamHandlerFactory.html#createURLStreamHandler-java.lang.String-) 58 | - [java.util.EnumSet](https://docs.oracle.com/javase/8/docs/api/java/util/EnumSet.html#of-E-) 59 | - [javax.xml.bind.JAXBContext](https://docs.oracle.com/javase/8/docs/api/javax/xml/bind/JAXBContext.html#createMarshaller--) 60 | -------------------------------------------------------------------------------- /设计模式/DesignPattern/设计模式 - 空对象.md: -------------------------------------------------------------------------------- 1 | ## 空对象(Null) 2 | 3 | ### Intent 4 | 5 | 使用什么都不做 6 | 7 | 的空对象来代替 NULL。 8 | 9 | 一个方法返回 NULL,意味着方法的调用端需要去检查返回值是否是 NULL,这么做会导致非常多的冗余的检查代码。并且如果某一个调用端忘记了做这个检查返回值,而直接使用返回的对象,那么就有可能抛出空指针异常。 10 | 11 | ### Class Diagram 12 | 13 |

14 | 15 | ### Implementation 16 | 17 | ```java 18 | public abstract class AbstractOperation { 19 | abstract void request(); 20 | } 21 | ``` 22 | 23 | ```java 24 | public class RealOperation extends AbstractOperation { 25 | @Override 26 | void request() { 27 | System.out.println("do something"); 28 | } 29 | } 30 | ``` 31 | 32 | ```java 33 | public class NullOperation extends AbstractOperation{ 34 | @Override 35 | void request() { 36 | // do nothing 37 | } 38 | } 39 | ``` 40 | 41 | ```java 42 | public class Client { 43 | public static void main(String[] args) { 44 | AbstractOperation abstractOperation = func(-1); 45 | abstractOperation.request(); 46 | } 47 | 48 | public static AbstractOperation func(int para) { 49 | if (para < 0) { 50 | return new NullOperation(); 51 | } 52 | return new RealOperation(); 53 | } 54 | } 55 | ``` 56 | -------------------------------------------------------------------------------- /设计模式/DesignPattern/设计模式 - 策略.md: -------------------------------------------------------------------------------- 1 | ## 9. 策略(Strategy) 2 | 3 | ### Intent 4 | 5 | 定义一系列算法,封装每个算法,并使它们可以互换。 6 | 7 | 策略模式可以让算法独立于使用它的客户端。 8 | 9 | ### Class Diagram 10 | 11 | - Strategy 接口定义了一个算法族,它们都实现了 behavior() 方法。 12 | - Context 是使用到该算法族的类,其中的 doSomething() 方法会调用 behavior(),setStrategy(Strategy) 方法可以动态地改变 strategy 对象,也就是说能动态地改变 Context 所使用的算法。 13 | 14 |

15 | 16 | ### 与状态模式的比较 17 | 18 | 状态模式的类图和策略模式类似,并且都是能够动态改变对象的行为。但是状态模式是通过状态转移来改变 Context 所组合的 State 对象,而策略模式是通过 Context 本身的决策来改变组合的 Strategy 对象。所谓的状态转移,是指 Context 在运行过程中由于一些条件发生改变而使得 State 对象发生改变,注意必须要是在运行过程中。 19 | 20 | 状态模式主要是用来解决状态转移的问题,当状态发生转移了,那么 Context 对象就会改变它的行为;而策略模式主要是用来封装一组可以互相替代的算法族,并且可以根据需要动态地去替换 Context 使用的算法。 21 | 22 | ### Implementation 23 | 24 | 设计一个鸭子,它可以动态地改变叫声。这里的算法族是鸭子的叫声行为。 25 | 26 | ```java 27 | public interface QuackBehavior { 28 | void quack(); 29 | } 30 | ``` 31 | 32 | ```java 33 | public class Quack implements QuackBehavior { 34 | @Override 35 | public void quack() { 36 | System.out.println("quack!"); 37 | } 38 | } 39 | ``` 40 | 41 | ```java 42 | public class Squeak implements QuackBehavior{ 43 | @Override 44 | public void quack() { 45 | System.out.println("squeak!"); 46 | } 47 | } 48 | ``` 49 | 50 | ```java 51 | public class Duck { 52 | 53 | private QuackBehavior quackBehavior; 54 | 55 | public void performQuack() { 56 | if (quackBehavior != null) { 57 | quackBehavior.quack(); 58 | } 59 | } 60 | 61 | public void setQuackBehavior(QuackBehavior quackBehavior) { 62 | this.quackBehavior = quackBehavior; 63 | } 64 | } 65 | ``` 66 | 67 | ```java 68 | public class Client { 69 | 70 | public static void main(String[] args) { 71 | Duck duck = new Duck(); 72 | duck.setQuackBehavior(new Squeak()); 73 | duck.performQuack(); 74 | duck.setQuackBehavior(new Quack()); 75 | duck.performQuack(); 76 | } 77 | } 78 | ``` 79 | 80 | ```html 81 | squeak! 82 | quack! 83 | ``` 84 | 85 | ### JDK 86 | 87 | - java.util.Comparator#compare() 88 | - javax.servlet.http.HttpServlet 89 | - javax.servlet.Filter#doFilter() 90 | -------------------------------------------------------------------------------- /设计模式/DesignPattern/设计模式 - 简单工厂.md: -------------------------------------------------------------------------------- 1 | ## 简单工厂(Simple Factory) 2 | 3 | ### Intent 4 | 5 | 在创建一个对象时不向客户暴露内部细节,并提供一个创建对象的通用接口。 6 | 7 | ### Class Diagram 8 | 9 | 简单工厂把实例化的操作单独放到一个类中,这个类就成为简单工厂类,让简单工厂类来决定应该用哪个具体子类来实例化。 10 | 11 | 这样做能把客户类和具体子类的实现解耦,客户类不再需要知道有哪些子类以及应当实例化哪个子类。客户类往往有多个,如果不使用简单工厂,那么所有的客户类都要知道所有子类的细节。而且一旦子类发生改变,例如增加子类,那么所有的客户类都要进行修改。 12 | 13 |

14 | 15 | ### Implementation 16 | 17 | ```java 18 | public interface Product { 19 | } 20 | ``` 21 | 22 | ```java 23 | public class ConcreteProduct implements Product { 24 | } 25 | ``` 26 | 27 | ```java 28 | public class ConcreteProduct1 implements Product { 29 | } 30 | ``` 31 | 32 | ```java 33 | public class ConcreteProduct2 implements Product { 34 | } 35 | ``` 36 | 37 | 以下的 Client 类包含了实例化的代码,这是一种错误的实现。如果在客户类中存在这种实例化代码,就需要考虑将代码放到简单工厂中。 38 | 39 | ```java 40 | public class Client { 41 | 42 | public static void main(String[] args) { 43 | int type = 1; 44 | Product product; 45 | if (type == 1) { 46 | product = new ConcreteProduct1(); 47 | } else if (type == 2) { 48 | product = new ConcreteProduct2(); 49 | } else { 50 | product = new ConcreteProduct(); 51 | } 52 | // do something with the product 53 | } 54 | } 55 | ``` 56 | 57 | 以下的 SimpleFactory 是简单工厂实现,它被所有需要进行实例化的客户类调用。 58 | 59 | ```java 60 | public class SimpleFactory { 61 | 62 | public Product createProduct(int type) { 63 | if (type == 1) { 64 | return new ConcreteProduct1(); 65 | } else if (type == 2) { 66 | return new ConcreteProduct2(); 67 | } 68 | return new ConcreteProduct(); 69 | } 70 | } 71 | ``` 72 | 73 | ```java 74 | public class Client { 75 | 76 | public static void main(String[] args) { 77 | SimpleFactory simpleFactory = new SimpleFactory(); 78 | Product product = simpleFactory.createProduct(1); 79 | // do something with the product 80 | } 81 | } 82 | ``` 83 | -------------------------------------------------------------------------------- /设计模式/DesignPattern/设计模式 - 迭代器.md: -------------------------------------------------------------------------------- 1 | ## 迭代器(Iterator) 2 | 3 | ### Intent 4 | 5 | 提供一种顺序访问聚合对象元素的方法,并且不暴露聚合对象的内部表示。 6 | 7 | ### Class Diagram 8 | 9 | - Aggregate 是聚合类,其中 createIterator() 方法可以产生一个 Iterator; 10 | - Iterator 主要定义了 hasNext() 和 next() 方法; 11 | - Client 组合了 Aggregate,为了迭代遍历 Aggregate,也需要组合 Iterator。 12 | 13 |
image-20191130164425351

14 | 15 | ### Implementation 16 | 17 | ```java 18 | public interface Aggregate { 19 | Iterator createIterator(); 20 | } 21 | ``` 22 | 23 | ```java 24 | public class ConcreteAggregate implements Aggregate { 25 | 26 | private Integer[] items; 27 | 28 | public ConcreteAggregate() { 29 | items = new Integer[10]; 30 | for (int i = 0; i < items.length; i++) { 31 | items[i] = i; 32 | } 33 | } 34 | 35 | @Override 36 | public Iterator createIterator() { 37 | return new ConcreteIterator(items); 38 | } 39 | } 40 | ``` 41 | 42 | ```java 43 | public interface Iterator { 44 | 45 | Item next(); 46 | 47 | boolean hasNext(); 48 | } 49 | ``` 50 | 51 | ```java 52 | public class ConcreteIterator implements Iterator { 53 | 54 | private Item[] items; 55 | private int position = 0; 56 | 57 | public ConcreteIterator(Item[] items) { 58 | this.items = items; 59 | } 60 | 61 | @Override 62 | public Object next() { 63 | return items[position++]; 64 | } 65 | 66 | @Override 67 | public boolean hasNext() { 68 | return position < items.length; 69 | } 70 | } 71 | ``` 72 | 73 | ```java 74 | public class Client { 75 | 76 | public static void main(String[] args) { 77 | Aggregate aggregate = new ConcreteAggregate(); 78 | Iterator iterator = aggregate.createIterator(); 79 | while (iterator.hasNext()) { 80 | System.out.println(iterator.next()); 81 | } 82 | } 83 | } 84 | ``` 85 | 86 | ### JDK 87 | 88 | - [java.util.Iterator](http://docs.oracle.com/javase/8/docs/api/java/util/Iterator.html) 89 | - [java.util.Enumeration](http://docs.oracle.com/javase/8/docs/api/java/util/Enumeration.html) 90 | -------------------------------------------------------------------------------- /设计模式/DesignPattern/设计模式 - 适配器.md: -------------------------------------------------------------------------------- 1 | ## 1. 适配器(Adapter) 2 | 3 | ### Intent 4 | 5 | 把一个类接口转换成另一个用户需要的接口。 6 | 7 |

8 | 9 | ### Class Diagram 10 | 11 |

12 | 13 | ### Implementation 14 | 15 | 鸭子(Duck)和火鸡(Turkey)拥有不同的叫声,Duck 的叫声调用 quack() 方法,而 Turkey 调用 gobble() 方法。 16 | 17 | 要求将 Turkey 的 gobble() 方法适配成 Duck 的 quack() 方法,从而让火鸡冒充鸭子! 18 | 19 | ```java 20 | public interface Duck { 21 | void quack(); 22 | } 23 | ``` 24 | 25 | ```java 26 | public interface Turkey { 27 | void gobble(); 28 | } 29 | ``` 30 | 31 | ```java 32 | public class WildTurkey implements Turkey { 33 | @Override 34 | public void gobble() { 35 | System.out.println("gobble!"); 36 | } 37 | } 38 | ``` 39 | 40 | ```java 41 | public class TurkeyAdapter implements Duck { 42 | Turkey turkey; 43 | 44 | public TurkeyAdapter(Turkey turkey) { 45 | this.turkey = turkey; 46 | } 47 | 48 | @Override 49 | public void quack() { 50 | turkey.gobble(); 51 | } 52 | } 53 | ``` 54 | 55 | ```java 56 | public class Client { 57 | public static void main(String[] args) { 58 | Turkey turkey = new WildTurkey(); 59 | Duck duck = new TurkeyAdapter(turkey); 60 | duck.quack(); 61 | } 62 | } 63 | ``` 64 | 65 | ### JDK 66 | 67 | - [java.util.Arrays#asList()](http://docs.oracle.com/javase/8/docs/api/java/util/Arrays.html#asList%28T...%29) 68 | - [java.util.Collections#list()](https://docs.oracle.com/javase/8/docs/api/java/util/Collections.html#list-java.util.Enumeration-) 69 | - [java.util.Collections#enumeration()](https://docs.oracle.com/javase/8/docs/api/java/util/Collections.html#enumeration-java.util.Collection-) 70 | - [javax.xml.bind.annotation.adapters.XMLAdapter](http://docs.oracle.com/javase/8/docs/api/javax/xml/bind/annotation/adapters/XmlAdapter.html#marshal-BoundType-) 71 | -------------------------------------------------------------------------------- /设计模式/设计模式 Patterns.xmind: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/iOrchid/AndroidInterviewNotes/3f5958440165f6bd17df41d2c49ae6e33288ceef/设计模式/设计模式 Patterns.xmind -------------------------------------------------------------------------------- /设计模式/设计模式 学习简述.md: -------------------------------------------------------------------------------- 1 | ## 设计模式简要学习笔记 2 | 3 | ### 一、原则 4 | 5 | 口诀:“单开迪里接依” 6 | 7 | 1. 单一职责 8 | 2. 开闭原则(扩展开放、修改封闭) 9 | 3. 迪米特法则 (最小关联、最少知识) 10 | 4. 里氏替换(基类作用处可用扩展类替换) 11 | 5. 接口隔离(面向接口、隔离解耦) 12 | 6. 依赖倒置(依赖高纬度) 13 | 注,多用组合,少用继承,也算一原则。 14 | ### 二、分类 15 | 16 | > 分为创建型、结构型、行为型 17 | 18 | #### 2.1 创建型 5种 19 | 20 | > 口诀:“原工单抽建” 21 | 22 | 1. 原型模式(Prototype Pattern) 23 | 1. 工厂模式(Factory Pattern) 24 | 1. 单例模式(Singleton Pattern) 25 | 1. 抽象工厂模式(Abstract Pattern) 26 | 1. 建造者模式(Builder Pattern) 27 | 28 | #### 2.2 结构型 7 + 1 种 (过滤器模式不在23种经典模式之中) 29 | 30 | > 口诀:“代享适外组装过桥” 31 | 32 | 1. 代理模式(Proxy Pattern) 33 | 1. 享元模式(Flyweight Pattern) 34 | 1. 适配器模式(Adapter Pattern) 35 | 1. 外观模式(Facade Pattern) 36 | 1. 组合模式(Composite Pattern) 37 | 1. 装饰器模式(Decorate Pattern) 38 | 1. 过滤器模式(Filter Pattern)或称作标准模式(Criteria Pattern) 39 | 1. 桥接模式(Bridge Pattern) 40 | 41 | #### 2.3 行为型 11 + 1 种 (空对象模式不在23种经典模式之中) 42 | 43 | > 口诀:“观模责备空命中解访策迭状” 44 | 45 | 1. 观察者模式(Observer Pattern) 46 | 1. 模版模式(Template Pattern) 47 | 1. 责任链模式(Chain Of Responsiblity Pattern) 48 | 1. 备忘录模式(Memento Pattern) 49 | 1. **空对象模式(Null Object Pattern)** 50 | 1. 命令模式(Command Pattern) 51 | 1. 中介者模式(Mediator Pattern) 52 | 1. 解释器模式(Interpreter Pattern) 53 | 1. 访问者模式(Visitor Pattern) 54 | 1. 策略模式(Strategy Pattern) 55 | 1. 迭代器模式(Iterator Pattern) 56 | 1. 状态模式(State Pattern) --------------------------------------------------------------------------------