├── README.md └── 素材——算法.md /README.md: -------------------------------------------------------------------------------- 1 | ## 前言 2 | >感觉现在的面试越来越难了,问得也越来越深,但是说实话很不实用,有应试的感觉。面试问各种原理,各种算法,实际用到的有多少?面试造核弹,工作拧螺丝。很多干了多年(5+)的真正资深反而在面试表现上还不如做了几周面试准备的应届生,难道这些应届生能力上比这些熟手强?或者有什么根据说他们的“潜力”强?真正入职了之后面对的是一个迭代接一个迭代,一个产品接一个产品,为了生活为了房子为了贷款不停的在工作,技术的沉淀又能有多少?又能有多少时间能给你去实践一个个新get的知识点? 3 | > 4 | >作为9年的安卓开发,刚毕业就进入正规外企开始安卓开发,一步一步从初级到中级到高级到现在的架构,app leader,期间也因为公司业务快速学习IOS,web vue等,各种新技术也保持着接触,到现在也没有止步不前。但这些并不代表我现在就已经掌握了所有这些曾经接触过的技术。**人的忘性是无可避免的,没有谁会一直记得不经常使用到的东西,但对一个开发来说,真正宝贵的应该是学习新技术快速使用的经验,面对新业务能快速深入理解并能给出风险和边际连带影响的提示,解决问题的思路、态度和与团队完美配合的工作方法。** 5 | > 6 | >但是现在的社会肤浅的,是喜欢人云亦云的,是崇尚浮夸的。为了适应这个现实,我从而有了这个app的构思,希望能帮助到有面试需要的同学。 7 | *** 8 | 9 | 10 | 目录 11 | 12 | [TOC] 13 | 14 | ## 结构构思 15 | 不搞什么花里花哨的东西,全是最常用的干活,讲究的就是精准实用,并不是要大家都会所有的技能,面试之前能熟悉就好,能背诵更好,应试之用。 16 | 17 | ### 页签形式的主界面 18 | 列表类型包含 19 | * java基础 20 | * android基础 21 | * 算法 22 | * 热更新/插件化/组件化 23 | * 常用设计模式 24 | * 架构模式 25 | * java源码解读 26 | * android源码解读 27 | * 常用库原理及对比,rxjava等 28 | * rn,weex,flutter,cordova 29 | * 流行的效果式样 30 | 31 | 每一个页签用懒加载形式加载,按最热的形式排序 32 | 每一个item点开后都用fragment展现 33 | 自用先用本地json读取,以后如果想收费了再搞接口读取。或者搞本地json文件,读取每个页签所需要用到的数据。这样就可以不限定安卓了,其他所有的内容都可以让用户自己编辑定制 34 | 35 | ### 具体内容 36 | #### java基础 37 | #### android基础 38 | #### 算法 39 | #### 热更新/插件化/组件化 40 | #### 常用设计模式 41 | #### 架构模式 42 | #### java源码解读 43 | #### android源码解读 44 | #### 常用库原理及对比,rxjava等 45 | #### rn,weex,flutter,cordova 46 | #### 流行的效果式样 47 | 48 | ## 开源协议 49 | 50 | ``` 51 | MIT License 52 | 53 | Copyright (c) 2018 张沅龙 54 | 55 | Permission is hereby granted, free of charge, to any person obtaining a copy 56 | of this software and associated documentation files (the "Software"), to deal 57 | in the Software without restriction, including without limitation the rights 58 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 59 | copies of the Software, and to permit persons to whom the Software is 60 | furnished to do so, subject to the following conditions: 61 | 62 | The above copyright notice and this permission notice shall be included in all 63 | copies or substantial portions of the Software. 64 | 65 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 66 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 67 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 68 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 69 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 70 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 71 | SOFTWARE. 72 | ``` 73 | -------------------------------------------------------------------------------- /素材——算法.md: -------------------------------------------------------------------------------- 1 | > * 原文地址:[github.com/kdn251/interviews](https://github.com/kdn251/interviews) 2 | > * 译文出自:[掘金翻译计划](https://github.com/xitu/gold-miner) 3 | > * 译者:[王下邀月熊](https://github.com/wxyyxc1992) 4 | > * 校对者:[PhxNirvana](https://github.com/phxnirvana)、[根号三](https://github.com/sqrthree) 5 | > * 这个 [链接](https://github.com/xitu/interviews/compare/master...kdn251:master) 用来查看本翻译与英文版是否有差别(如果你没有看到 README.md 发生变化,那就意味着这份翻译文档是最新的)。 6 | 7 | # Interviews 8 | > 软件工程技术面试个人指南。 9 | > 10 | > Maintainer - [Kevin Naughton Jr.](https://github.com/kdn251) 11 | 12 | ## 其他语言版本 13 | 14 | - [English](./README.md) 15 | 16 | ## 目录 17 | - [在线练习](#在线练习) 18 | - [在线面试编程](#在线面试编程) 19 | - [数据结构](#数据结构) 20 | - [算法](#算法) 21 | - [位运算](#位运算) 22 | - [算法复杂度分析](#算法复杂度分析) 23 | - [视频教程](#视频教程) 24 | - [面试书籍](#面试书籍) 25 | - [计算机科学与技术资讯](#计算机科学与技术资讯) 26 | - [文件结构](#文件结构) 27 | 28 | ## 在线练习 29 | * [LeetCode](https://leetcode.com/) 30 | * [Virtual Judge](https://vjudge.net/) 31 | * [CareerCup](https://www.careercup.com/) 32 | * [HackerRank](https://www.hackerrank.com/) 33 | * [CodeFights](https://codefights.com/) 34 | * [Kattis](https://open.kattis.com/) 35 | * [HackerEarth](https://www.hackerearth.com) 36 | * [Codility](https://codility.com/programmers/lessons/1-iterations/) 37 | * [Code Forces](http://codeforces.com/) 38 | * [Code Chef](https://www.codechef.com/) 39 | * [Sphere Online Judge - SPOJ](http://www.spoj.com/) 40 | * [InterviewBit](https://www.interviewbit.com/) 41 | 42 | ## 在线面试编程 43 | * [Pramp](https://www.pramp.com/ref/gt4-cn) 44 | * [Gainlo](http://www.gainlo.co/#!/) 45 | * [Refdash](https://refdash.com/) 46 | * [Interviewing.io](https://www.interviewing.io/) 47 | 48 | ## 数据结构 49 | ### Linked List 50 | * 链表即是由节点(Node)组成的线性集合,每个节点可以利用指针指向其他节点。它是一种包含了多个节点的、能够用于表示序列的数据结构。 51 | * **单向链表**: 链表中的节点仅指向下一个节点,并且最后一个节点指向空。 52 | * **双向链表**: 其中每个节点具有两个指针 p、n,使得 p 指向先前节点并且 n 指向下一个节点;最后一个节点的 n 指针指向 null。 53 | * **循环链表**:每个节点指向下一个节点并且最后一个节点指向第一个节点的链表。 54 | * 时间复杂度: 55 | * 索引: `O(n)` 56 | * 搜索: `O(n)` 57 | * 插入: `O(1)` 58 | * 移除: `O(1)` 59 | 60 | ### Stack 61 | * 栈是元素的集合,其包含了两个基本操作:push 操作可以用于将元素压入栈,pop 操作可以将栈顶元素移除。 62 | * 遵循后入先出(LIFO)原则。 63 | * 时间复杂度: 64 | * 索引: `O(n)` 65 | * 搜索: `O(n)` 66 | * 插入: `O(1)` 67 | * 移除: `O(1)` 68 | 69 | ### Queue 70 | * 队列是元素的集合,其包含了两个基本操作:enqueue 操作可以用于将元素插入到队列中,而 dequeue 操作则是将元素从队列中移除。 71 | * 遵循先入先出原则 (FIFO)。 72 | * 时间复杂度: 73 | * 索引: `O(n)` 74 | * 搜索: `O(n)` 75 | * 插入: `O(1)` 76 | * 移除: `O(1)` 77 | 78 | ### Tree 79 | * 树是无向、连通的无环图。 80 | 81 | ### Binary Tree 82 | * 二叉树即是每个节点最多包含左子节点与右子节点这两个节点的树形数据结构。 83 | * **满二叉树**: 树中的每个节点仅包含 0 或 2 个节点。 84 | * **完美二叉树(Perfect Binary Tree)**: 二叉树中的每个叶节点都拥有两个子节点,并且具有相同的高度。 85 | * **完全二叉树**: 除最后一层外,每一层上的结点数均达到最大值;在最后一层上只缺少右边的若干结点。 86 | 87 | ### Binary Search Tree 88 | 89 | * 二叉搜索树(BST)是一种特殊的二叉树,其任何节点中的值都会大于或者等于其左子树中存储的值并且小于或者等于其右子树中存储的值。 90 | * 时间复杂度: 91 | * 索引: `O(log(n))` 92 | * 搜索: `O(log(n))` 93 | * 插入: `O(log(n))` 94 | * 删除: `O(log(n))` 95 | 96 | Binary Search Tree 97 | 98 | ### Trie 99 | * 字典树,又称基数树或者前缀树,能够用于存储键为字符串的动态集合或者关联数组的搜索树。树中的节点并没有直接存储关联键值,而是该节点在树中的挂载位置决定了其关联键值。某个节点的所有子节点都拥有相同的前缀,整棵树的根节点则是空字符串。 100 | 101 | ![Alt text](/images/trie.png?raw=true "Trie") 102 | 103 | ### Fenwick Tree 104 | * 树状数组又称 Binary Indexed Tree,其表现形式为树,不过本质上是以数组实现。数组中的下标代表着树中的顶点,每个顶点的父节点或者子节点的下标能够通过位运算获得。数组中的每个元素包含了预计算的区间值之和,在整棵树更新的过程中同样会更新这些预计算的值。 105 | * 时间复杂度: 106 | * 区间求值: `O(log(n))` 107 | * 更新: `O(log(n))` 108 | 109 | ![Alt text](/images/fenwickTree.png?raw=true "Fenwick Tree") 110 | 111 | ### Segment Tree 112 | * 线段树是用于存放间隔或者线段的树形数据结构,它允许快速的查找某一个节点在若干条线段中出现的次数. 113 | * 时间复杂度: 114 | * 区间查询: `O(log(n))` 115 | * 更新: `O(log(n))` 116 | 117 | ![Alt text](/images/segmentTree.png?raw=true "Segment Tree") 118 | 119 | ### Heap 120 | * 堆是一种特殊的基于树的满足某些特性的数据结构,整个堆中的所有父子节点的键值都会满足相同的排序条件。堆更准确地可以分为最大堆与最小堆,在最大堆中,父节点的键值永远大于或者等于子节点的值,并且整个堆中的最大值存储于根节点;而最小堆中,父节点的键值永远小于或者等于其子节点的键值,并且整个堆中的最小值存储于根节点。 121 | * 时间复杂度: 122 | * 访问最大值 / 最小值: `O(1)` 123 | * 插入: `O(log(n))` 124 | * 移除最大值 / 最小值: `O(log(n))` 125 | 126 | Max Heap 127 | 128 | 129 | ### Hashing 130 | * 哈希能够将任意长度的数据映射到固定长度的数据。哈希函数返回的即是哈希值,如果两个不同的键得到相同的哈希值,即将这种现象称为碰撞。 131 | * **Hash Map**: Hash Map 是一种能够建立起键与值之间关系的数据结构,Hash Map 能够使用哈希函数将键转化为桶或者槽中的下标,从而优化对于目标值的搜索速度。 132 | * 碰撞解决 133 | * **链地址法(Separate Chaining)**: 链地址法中,每个桶是相互独立的,包含了一系列索引的列表。搜索操作的时间复杂度即是搜索桶的时间(固定时间)与遍历列表的时间之和。 134 | * **开地址法(Open Addressing)**: 在开地址法中,当插入新值时,会判断该值对应的哈希桶是否存在,如果存在则根据某种算法依次选择下一个可能的位置,直到找到一个尚未被占用的地址。所谓开地址法也是指某个元素的位置并不永远由其哈希值决定。 135 | 136 | ![Alt text](/images/hash.png?raw=true "Hashing") 137 | 138 | ### Graph 139 | * 图是一种数据元素间为多对多关系的数据结构,加上一组基本操作构成的抽象数据类型。 140 | * **无向图(Undirected Graph)**: 无向图具有对称的邻接矩阵,因此如果存在某条从节点 u 到节点 v 的边,反之从 v 到 u 的边也存在。 141 | * **有向图(Directed Graph)**: 有向图的邻接矩阵是非对称的,即如果存在从 u 到 v 的边并不意味着一定存在从 v 到 u 的边。 142 | 143 | Graph 144 | 145 | ## 算法 146 | 147 | ### 排序 148 | 149 | #### 快速排序 150 | * 稳定: 否 151 | * 时间复杂度: 152 | * 最优时间: `O(nlog(n))` 153 | * 最坏时间: `O(n^2)` 154 | * 平均时间: `O(nlog(n))` 155 | 156 | ![Alt text](/images/quicksort.gif?raw=true "Quicksort") 157 | 158 | #### 归并排序 159 | * 归并排序是典型的分治算法,它不断地将某个数组分为两个部分,分别对左子数组与右子数组进行排序,然后将两个数组合并为新的有序数组。 160 | * 稳定: 是 161 | * 时间复杂度: 162 | * 最优时间: `O(nlog(n))` 163 | * 最坏时间: `O(nlog(n))` 164 | * 平均时间: `O(nlog(n))` 165 | 166 | ![Alt text](/images/mergesort.gif?raw=true "Mergesort") 167 | 168 | #### 桶排序 169 | * 桶排序将数组分到有限数量的桶子里。每个桶子再个别排序(有可能再使用别的排序算法或是以递归方式继续使用桶排序进行排序)。 170 | * 时间复杂度: 171 | * 最优时间: `Ω(n + k)` 172 | * 最坏时间: `O(n^2)` 173 | * 平均时间:`Θ(n + k)` 174 | 175 | 176 | ![Alt text](/images/bucketsort.png?raw=true "Bucket Sort") 177 | 178 | #### 基数排序 179 | * 基数排序类似于桶排序,将数组分割到有限数目的桶中;不过其在分割之后并没有让每个桶单独地进行排序,而是直接进行了合并操作。 180 | * 时间复杂度: 181 | * 最优时间: `Ω(nk)` 182 | * 最坏时间: `O(nk)` 183 | * 平均时间: `Θ(nk)` 184 | 185 | ### 图算法 186 | 187 | #### 深度优先搜索 188 | * 深度优先算法是一种优先遍历子节点而不是回溯的算法。 189 | * 时间复杂度: `O(|V| + |E|)` 190 | 191 | ![Alt text](/images/dfsbfs.gif?raw=true "DFS / BFS Traversal") 192 | 193 | #### 广度优先搜索 194 | * 广度优先搜索是优先遍历邻居节点而不是子节点的图遍历算法。 195 | * 时间复杂度: `O(|V| + |E|)` 196 | 197 | ![Alt text](/images/dfsbfs.gif?raw=true "DFS / BFS Traversal") 198 | 199 | #### 拓扑排序 200 | * 拓扑排序是对于有向图节点的线性排序,如果存在某条从 u 到 v 的边,则认为 u 的下标先于 v。 201 | * 时间复杂度: `O(|V| + |E|)` 202 | 203 | #### Dijkstra 算法 204 | * **Dijkstra 算法** 用于计算有向图中单源最短路径问题。 205 | * 时间复杂度: `O(|V|^2)` 206 | 207 | ![Alt text](/images/dijkstra.gif?raw=true "Dijkstra's") 208 | 209 | #### Bellman-Ford 算法 210 | * **Bellman-Ford 算法**是在带权图中计算从单一源点出发到其他节点的最短路径的算法。 211 | * 尽管算法复杂度大于 Dijkstra 算法,但是它适用于包含了负值边的图。 212 | * 时间复杂度: 213 | * 最优时间: `O(|E|)` 214 | - 最坏时间: `O(|V||E|)` 215 | 216 | ![Alt text](/images/bellman-ford.gif?raw=true "Bellman-Ford") 217 | 218 | #### Floyd-Warshall 算法 219 | * **Floyd-Warshall 算法** 能够用于在无环带权图中寻找任意节点的最短路径。 220 | * 时间复杂度: 221 | * 最优时间: `O(|V|^3)` 222 | * 最坏时间: `O(|V|^3)` 223 | * 平均时间: `O(|V|^3)` 224 | 225 | #### Prim 算法 226 | * **Prim 算法**是用于在带权无向图中计算最小生成树的贪婪算法。换言之,Prim 算法能够在图中抽取出连接所有节点的边的最小代价子集。 227 | * 时间复杂度: `O(|V|^2)` 228 | 229 | ![Alt text](/images/prim.gif?raw=true "Prim's Algorithm") 230 | 231 | #### Kruskal 算法 232 | * **Kruskal 算法**同样是计算图的最小生成树的算法,与 Prim 的区别在于并不需要图是连通的。 233 | * 时间复杂度: `O(|E|log|V|)` 234 | 235 | ![Alt text](/images/kruskal.gif?raw=true "Kruskal's Algorithm") 236 | 237 | ## 位运算 238 | * 位运算即是在位级别进行操作的技术,合适的位运算能够帮助我们得到更快地运算速度与更小的内存使用。 239 | * 测试第 k 位: `s & (1 << k)` 240 | * 设置第 k 位: `s |= (1 << k)` 241 | * 第 k 位置零: `s &= ~(1 << k)` 242 | * 切换第 k 位值: `s ^= ~(1 << k)` 243 | * 乘以 2n: `s << n` 244 | * 除以 2n: `s >> n` 245 | * 交集: `s & t` 246 | * 并集: `s | t` 247 | * 减法: `s & ~t` 248 | * 交换 `x = x ^ y ^ (y = x)` 249 | * 取出最小非 0 位(Extract lowest set bit): `s & (-s)` 250 | * 取出最小 0 位(Extract lowest unset bit): `~s & (s + 1)` 251 | * 交换值: 252 | ``` 253 | x ^= y; 254 | y ^= x; 255 | x ^= y; 256 | ``` 257 | 258 | ## 算法复杂度分析 259 | 260 | #### 大 O 表示 261 | * **大 O 表示** 用于表示某个算法的上限,往往用于描述最坏的情况。 262 | 263 | ![Alt text](/images/bigO.png?raw=true "Theta Notation") 264 | 265 | #### 小 O 表示 266 | * **小 O 表示**用于描述某个算法的渐进上界,不过二者要更为紧密。 267 | 268 | #### 大 Ω 表示 269 | * **大 Ω 表示**用于描述某个算法的渐进下界。 270 | 271 | ![Alt text](/images/bigOmega.png?raw=true "Theta Notation") 272 | 273 | #### 小 ω 表示 274 | * **Little Omega Notation**用于描述某个特定算法的下界,不过不一定很靠近。 275 | 276 | #### Theta Θ 表示 277 | * **Theta Notation**用于描述某个确定算法的确界。 278 | 279 | ![Alt text](/images/theta.png?raw=true "Theta Notation") 280 | 281 | ## 视频教程 282 | * Data Structures 283 | * [UC Berkeley Data Structures](https://www.youtube.com/watch?v=mFPmKGIrQs4&index=1&list=PL-XXv-cvA_iAlnI-BQr9hjqADPBtujFJd) 284 | * [MIT Advanced Data Structures](https://www.youtube.com/watch?v=T0yzrZL1py0&list=PLUl4u3cNGP61hsJNdULdudlRL493b-XZf&index=1) 285 | * Algorithms 286 | * [MIT Introduction to Algorithms](https://www.youtube.com/watch?v=HtSuA80QTyo&list=PLUl4u3cNGP61Oq3tWYp6V_F-5jb5L2iHb&index=1) 287 | * [MIT Advanced Algorithms](https://www.youtube.com/playlist?list=PL6ogFv-ieghdoGKGg2Bik3Gl1glBTEu8c) 288 | 289 | ## 面试书籍 290 | * Competitive Programming 3 - Steven Halim & Felix Halim 291 | * Cracking The Coding Interview - Gayle Laakmann McDowell 292 | * Cracking The PM Interview - Gayle Laakmann McDowell & Jackie Bavaro 293 | 294 | ## 计算机科学与技术资讯 295 | * [Hacker News](https://news.ycombinator.com/) 296 | * [Lobsters](https://lobste.rs/) 297 | 298 | --------------------------------------------------------------------------------