diff --git a/README.md b/README.md index 6a64da9f..9e255970 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ > 1. **介绍**:本项目是一套完整的刷题计划,旨在帮助大家少走弯路,循序渐进学算法,[关注作者](#关于作者) > 2. **PDF版本** : [「代码随想录」算法精讲 PDF 版本](https://mp.weixin.qq.com/s/RsdcQ9umo09R6cfnwXZlrQ) 。 > 3. **刷题顺序** : README已经将刷题顺序排好了,按照顺序一道一道刷就可以。 -> 3. **学习社区** : 一起学习打卡/面试技巧/如何选择offer/大厂内推/职场规则/简历修改/技术分享/程序人生。欢迎加入[「代码随想录」学习社区](https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ) 。 +> 3. **学习社区** : 一起学习打卡/面试技巧/如何选择offer/大厂内推/职场规则/简历修改/技术分享/程序人生。欢迎加入[「代码随想录」知识星球](https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ) 。 > 4. **提交代码**:本项目统一使用C++语言进行讲解,但已经有Java、Python、Go、JavaScript等等多语言版本,感谢[这里的每一位贡献者](https://github.com/youngyangyang04/leetcode-master/graphs/contributors),如果你也想贡献代码点亮你的头像,[点击这里](https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A)了解提交代码的方式。 > 5. **转载须知** :以下所有文章皆为我([程序员Carl](https://github.com/youngyangyang04))的原创。引用本项目文章请注明出处,发现恶意抄袭或搬运,会动用法律武器维护自己的权益。让我们一起维护一个良好的技术创作环境! @@ -97,6 +97,8 @@ * [看了这么多代码,谈一谈代码风格!](./problems/前序/代码风格.md) * [力扣上的代码想在本地编译运行?](./problems/前序/力扣上的代码想在本地编译运行?.md) * [什么是核心代码模式,什么又是ACM模式?](./problems/前序/什么是核心代码模式,什么又是ACM模式?.md) + * [ACM模式如何构造二叉树](./problems/前序/ACM模式如何构建二叉树.md) + * [解密互联网大厂研发流程](./problems/前序/互联网大厂研发流程.md) * 工具 * [一站式vim配置](https://github.com/youngyangyang04/PowerVim) @@ -124,6 +126,11 @@ ## 知识星球精选 +* [HR特意刁难非科班!](./problems/知识星球精选/HR特意刁难非科班.md) +* [offer的选择](./problems/知识星球精选/offer的选择.md) +* [天下乌鸦一般黑,哪家没有PUA?](./problems/知识星球精选/天下乌鸦一般黑.md) +* [初入大三,考研VS工作](./problems/知识星球精选/初入大三选择考研VS工作.md) +* [非科班2021秋招总结](./problems/知识星球精选/非科班2021秋招总结.md) * [秋招下半场依然没offer,怎么办?](./problems/知识星球精选/秋招下半场依然没offer.md) * [合适自己的就是最好的](./problems/知识星球精选/合适自己的就是最好的.md) * [为什么都说客户端会消失](./problems/知识星球精选/客三消.md) @@ -466,6 +473,7 @@ * [234.回文链表](./problems/0234.回文链表.md) * [143.重排链表](./problems/0143.重排链表.md)【数组】【双向队列】【直接操作链表】 * [141.环形链表](./problems/0141.环形链表.md) +* [160.相交链表](./problems/面试题02.07.链表相交.md) ## 哈希表 * [205.同构字符串](./problems/0205.同构字符串.md):【哈希表的应用】 diff --git a/problems/0035.搜索插入位置.md b/problems/0035.搜索插入位置.md index 593e3fe5..58171f59 100644 --- a/problems/0035.搜索插入位置.md +++ b/problems/0035.搜索插入位置.md @@ -18,22 +18,22 @@ 你可以假设数组中无重复元素。 示例 1: -输入: [1,3,5,6], 5 -输出: 2 +* 输入: [1,3,5,6], 5 +* 输出: 2 示例 2: -输入: [1,3,5,6], 2 -输出: 1 +* 输入: [1,3,5,6], 2 +* 输出: 1 示例 3: -输入: [1,3,5,6], 7 -输出: 4 +* 输入: [1,3,5,6], 7 +* 输出: 4 示例 4: -输入: [1,3,5,6], 0 -输出: 0 +* 输入: [1,3,5,6], 0 +* 输出: 0 -# 思路 +## 思路 这道题目不难,但是为什么通过率相对来说并不高呢,我理解是大家对边界处理的判断有所失误导致的。 @@ -50,13 +50,13 @@ 接下来我将从暴力的解法和二分法来讲解此题,也借此好好讲一讲二分查找法。 -## 暴力解法 +### 暴力解法 暴力解题 不一定时间消耗就非常高,关键看实现的方式,就像是二分查找时间消耗不一定就很低,是一样的。 -## 暴力解法C++代码 +C++代码 -``` +```CPP class Solution { public: int searchInsert(vector& nums, int target) { @@ -75,14 +75,14 @@ public: }; ``` -时间复杂度:O(n) -空间复杂度:O(1) +* 时间复杂度:O(n) +* 空间复杂度:O(1) 效率如下: ![35_搜索插入位置](https://img-blog.csdnimg.cn/20201216232127268.png) -## 二分法 +### 二分法 既然暴力解法的时间复杂度是O(n),就要尝试一下使用二分查找法。 @@ -108,7 +108,7 @@ public: 要在二分查找的过程中,保持不变量,这也就是**循环不变量** (感兴趣的同学可以查一查)。 -## 二分法第一种写法 +### 二分法第一种写法 以这道题目来举例,以下的代码中定义 target 是在一个在左闭右闭的区间里,**也就是[left, right] (这个很重要)**。 @@ -142,13 +142,13 @@ public: } }; ``` -时间复杂度:O(logn) -时间复杂度:O(1) +* 时间复杂度:O(logn) +* 时间复杂度:O(1) 效率如下: ![35_搜索插入位置2](https://img-blog.csdnimg.cn/2020121623272877.png) -## 二分法第二种写法 +### 二分法第二种写法 如果说定义 target 是在一个在左闭右开的区间里,也就是[left, right) 。 @@ -185,10 +185,10 @@ public: }; ``` -时间复杂度:O(logn) -时间复杂度:O(1) +* 时间复杂度:O(logn) +* 时间复杂度:O(1) -# 总结 +## 总结 希望通过这道题目,大家会发现平时写二分法,为什么总写不好,就是因为对区间定义不清楚。 @@ -196,16 +196,11 @@ public: 然后在**二分查找的循环中,坚持循环不变量的原则**,很多细节问题,自然会知道如何处理了。 -**循序渐进学算法,认准「代码随想录」,Carl手把手带你过关斩将!** - - - - ## 其他语言版本 -Java: +### Java ```java class Solution { @@ -234,7 +229,7 @@ class Solution { ``` -Python: +### Python ```python3 class Solution: def searchInsert(self, nums: List[int], target: int) -> int: @@ -252,7 +247,7 @@ class Solution: return right + 1 ``` -JavaScript: +### JavaScript ```js var searchInsert = function (nums, target) { let l = 0, r = nums.length - 1, ans = nums.length; @@ -272,7 +267,7 @@ var searchInsert = function (nums, target) { }; ``` -Swift: +### Swift ```swift // 暴力法 diff --git a/problems/0037.解数独.md b/problems/0037.解数独.md index 7bc07252..30c50365 100644 --- a/problems/0037.解数独.md +++ b/problems/0037.解数独.md @@ -9,7 +9,7 @@ 如果对回溯法理论还不清楚的同学,可以先看这个视频[视频来了!!带你学透回溯算法(理论篇)](https://mp.weixin.qq.com/s/wDd5azGIYWjbU0fdua_qBg) -## 37. 解数独 +# 37. 解数独 [力扣题目链接](https://leetcode-cn.com/problems/sudoku-solver/) @@ -53,7 +53,7 @@ ![37.解数独](https://img-blog.csdnimg.cn/2020111720451790.png) -## 回溯三部曲 +### 回溯三部曲 * 递归函数以及参数 @@ -115,7 +115,7 @@ bool backtracking(vector>& board) { 那么会直接返回, **这也就是为什么没有终止条件也不会永远填不满棋盘而无限递归下去!** -## 判断棋盘是否合法 +### 判断棋盘是否合法 判断棋盘是否合法有如下三个维度: @@ -150,9 +150,8 @@ bool isValid(int row, int col, char val, vector>& board) { } ``` -最后整体代码如下: +最后整体C++代码如下: -## C++代码 ```CPP class Solution { @@ -218,7 +217,7 @@ public: ## 其他语言版本 -Java: +### Java ```java class Solution { public void solveSudoku(char[][] board) { @@ -286,7 +285,7 @@ class Solution { } ``` -Python: +### Python ```python3 class Solution: def solveSudoku(self, board: List[List[str]]) -> None: @@ -321,7 +320,7 @@ class Solution: backtrack(board) ``` -Python3: +### Python3 ```python3 class Solution: @@ -374,7 +373,7 @@ class Solution: self.isSolved() ``` -Go: +### Go ```go func solveSudoku(board [][]byte) { @@ -431,7 +430,7 @@ func isvalid(row,col int,k byte,board [][]byte)bool{ -Javascript: +### Javascript ```Javascript var solveSudoku = function(board) { function isValid(row, col, val, board) { @@ -487,7 +486,7 @@ var solveSudoku = function(board) { }; ``` -C: +### C ```C bool isValid(char** board, int row, int col, int k) { diff --git a/problems/0046.全排列.md b/problems/0046.全排列.md index 487a07ad..bf104acd 100644 --- a/problems/0046.全排列.md +++ b/problems/0046.全排列.md @@ -7,15 +7,15 @@

欢迎大家参与本项目,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!

-## 46.全排列 +# 46.全排列 [力扣题目链接](https://leetcode-cn.com/problems/permutations/) 给定一个 没有重复 数字的序列,返回其所有可能的全排列。 示例: -输入: [1,2,3] -输出: +* 输入: [1,2,3] +* 输出: [ [1,2,3], [1,3,2], @@ -42,7 +42,7 @@ ![46.全排列](https://img-blog.csdnimg.cn/20201209174225145.png) -## 回溯三部曲 +### 回溯三部曲 * 递归函数参数 @@ -105,7 +105,6 @@ for (int i = 0; i < nums.size(); i++) { 整体C++代码如下: - ```CPP class Solution { public: @@ -148,8 +147,8 @@ public: ## 其他语言版本 +### Java -Java: ```java class Solution { @@ -182,7 +181,8 @@ class Solution { } } } -``` +``` + ```java // 解法2:通过判断path中是否存在数字,排除已经选择的数字 class Solution { @@ -210,8 +210,8 @@ class Solution { } ``` -Python: -```python3 +### Python +```python class Solution: def permute(self, nums: List[int]) -> List[List[int]]: res = [] #存放符合条件结果的集合 @@ -251,7 +251,7 @@ class Solution: return res ``` -Go: +### Go ```Go var res [][]int func permute(nums []int) [][]int { @@ -278,7 +278,7 @@ func backTrack(nums []int,numsLen int,path []int) { ``` -Javascript: +### Javascript ```js diff --git a/problems/0047.全排列II.md b/problems/0047.全排列II.md index 4c2c2758..e4aca30c 100644 --- a/problems/0047.全排列II.md +++ b/problems/0047.全排列II.md @@ -15,15 +15,15 @@ 给定一个可包含重复数字的序列 nums ,按任意顺序 返回所有不重复的全排列。 示例 1: -输入:nums = [1,1,2] -输出: +* 输入:nums = [1,1,2] +* 输出: [[1,1,2], [1,2,1], [2,1,1]] 示例 2: -输入:nums = [1,2,3] -输出:[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]] +* 输入:nums = [1,2,3] +* 输出:[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]] 提示: * 1 <= nums.length <= 8 @@ -153,7 +153,7 @@ if (i > 0 && nums[i] == nums[i - 1] && used[i - 1] == true) { ## 其他语言版本 -java: +### java ```java class Solution { @@ -195,7 +195,7 @@ class Solution { } ``` -python: +### python ```python class Solution: @@ -223,7 +223,7 @@ class Solution: return res ``` -Go: +### Go ```go var res [][]int @@ -256,7 +256,7 @@ func backTrack(nums []int,numsLen int,path []int) { } ``` -Javascript: +### Javascript ```javascript @@ -292,45 +292,6 @@ var permuteUnique = function (nums) { }; ``` -Go: -回溯+本层去重+下层去重 -```golang -func permuteUnique(nums []int) [][]int { - var subRes []int - var res [][]int - sort.Ints(nums) - used:=make([]bool,len(nums)) - backTring(nums,subRes,&res,used) - return res -} -func backTring(nums,subRes []int,res *[][]int,used []bool){ - if len(subRes)==len(nums){ - tmp:=make([]int,len(nums)) - copy(tmp,subRes) - *res=append(*res,tmp) - return - } - // used[i - 1] == true,说明同一树支candidates[i - 1]使用过 - // used[i - 1] == false,说明同一树层candidates[i - 1]使用过 - for i:=0;i0&&nums[i]==nums[i-1]&&used[i-1]==false{//当本层元素相同且前一个被使用过,则继续向后找(本层去重) - continue - } - //到达这里有两种情况:1.该层前后元素不同;2.该层前后元素相同但该层没有使用过 - //所以只能对该层没有被使用过的抽取 - if used[i]==false{ - //首先将该元素置为使用过(即同一树枝使用过),下一层的元素就不能选择重复使用过的元素(下层去重) - used[i]=true - subRes=append(subRes,nums[i]) - backTring(nums,subRes,res,used) - //回溯 - //回溯回来,将该元素置为false,表示该元素在该层使用过 - used[i]=false - subRes=subRes[:len(subRes)-1] - } - } -} -``` diff --git a/problems/0051.N皇后.md b/problems/0051.N皇后.md index 7e2b202f..71f04097 100644 --- a/problems/0051.N皇后.md +++ b/problems/0051.N皇后.md @@ -7,46 +7,28 @@

欢迎大家参与本项目,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!

-## 第51题. N皇后 +# 第51题. N皇后 [力扣题目链接](https://leetcode-cn.com/problems/n-queens/) -n 皇后问题研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击。 +n 皇后问题 研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并且使皇后彼此之间不能相互攻击。 -上图为 8 皇后问题的一种解法。 -![51n皇后](https://img-blog.csdnimg.cn/20200821152118456.png) +给你一个整数 n ,返回所有不同的 n 皇后问题 的解决方案。 -给定一个整数 n,返回所有不同的 n 皇后问题的解决方案。 +每一种解法包含一个不同的 n 皇后问题 的棋子放置方案,该方案中 'Q' 和 '.' 分别代表了皇后和空位。 -每一种解法包含一个明确的 n 皇后问题的棋子放置方案,该方案中 'Q' 和 '.' 分别代表了皇后和空位。 +示例 1: -示例: +![](https://code-thinking-1253855093.file.myqcloud.com/pics/20211020232201.png) -输入: 4 +* 输入:n = 4 +* 输出:[[".Q..","...Q","Q...","..Q."],["..Q.","Q...","...Q",".Q.."]] +* 解释:如上图所示,4 皇后问题存在两个不同的解法。 -输出: - -解法 1 - -[ - [".Q..", - "...Q", - "Q...", - "..Q."], - -解法 2 - - ["..Q.", - "Q...", - "...Q", - ".Q.."] -] - -解释: 4 皇后问题存在两个不同的解法。 - -提示: -> 皇后,是国际象棋中的棋子,意味着国王的妻子。皇后只做一件事,那就是“吃子”。当她遇见可以吃的棋子时,就迅速冲上去吃掉棋子。当然,她横、竖、斜都可走一到七步,可进可退。(引用自 百度百科 - 皇后 ) +示例 2: +* 输入:n = 1 +* 输出:[["Q"]] ## 思路 @@ -71,7 +53,7 @@ n 皇后问题研究的是如何将 n 个皇后放置在 n×n 的棋盘上,并 那么我们用皇后们的约束条件,来回溯搜索这颗树,**只要搜索到了树的叶子节点,说明就找到了皇后们的合理位置了**。 -## 回溯三部曲 +### 回溯三部曲 按照我总结的如下回溯模板,我们来依次分析: @@ -178,8 +160,6 @@ bool isValid(int row, int col, vector& chessboard, int n) { 那么按照这个模板不难写出如下C++代码: -## C++代码 - ```CPP class Solution { private: @@ -247,7 +227,7 @@ public: ## 其他语言补充 -Python: +### Python ```python class Solution: @@ -296,7 +276,7 @@ class Solution: return res ``` -Java: +### Java ```java class Solution { @@ -366,7 +346,7 @@ class Solution { ``` -Go: +### Go ```Go import "strings" var res [][]string @@ -433,8 +413,7 @@ func solveNQueens(n int) [][]string { return res } ``` - -Javascript: +### Javascript ```Javascript var solveNQueens = function(n) { function isValid(row, col, chessBoard, n) { diff --git a/problems/0090.子集II.md b/problems/0090.子集II.md index 7ae7c6c2..2777bc84 100644 --- a/problems/0090.子集II.md +++ b/problems/0090.子集II.md @@ -6,8 +6,9 @@

欢迎大家参与本项目,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!

+# 子集问题(二) -## 第90题.子集II +## 90.子集II [力扣题目链接](https://leetcode-cn.com/problems/subsets-ii/) @@ -16,8 +17,8 @@ 说明:解集不能包含重复的子集。 示例: -输入: [1,2,2] -输出: +* 输入: [1,2,2] +* 输出: [ [2], [1], @@ -46,7 +47,7 @@ 本题就是其实就是[回溯算法:求子集问题!](https://programmercarl.com/0078.子集.html)的基础上加上了去重,去重我们在[回溯算法:求组合总和(三)](https://programmercarl.com/0040.组合总和II.html)也讲过了,所以我就直接给出代码了: -## C++代码 +C++代码如下: ```CPP class Solution { @@ -168,7 +169,8 @@ if (i > startIndex && nums[i] == nums[i - 1] ) { ## 其他语言版本 -Java: +### Java + ```java class Solution { List> result = new ArrayList<>();// 存放符合条件结果的集合 @@ -204,8 +206,8 @@ class Solution { } ``` -Python: -```python3 +### Python +```python class Solution: def subsetsWithDup(self, nums: List[int]) -> List[List[int]]: res = [] #存放符合条件结果的集合 @@ -223,7 +225,8 @@ class Solution: return res ``` -Go: +### Go + ```Go var res[][]int func subsetsWithDup(nums []int)[][]int { @@ -249,7 +252,7 @@ func dfs(temp, num []int, start int) { ``` -Javascript: +### Javascript ```Javascript @@ -279,7 +282,8 @@ var subsetsWithDup = function(nums) { ``` -C: +### C + ```c int* path; int pathTop; @@ -348,7 +352,6 @@ int** subsetsWithDup(int* nums, int numsSize, int* returnSize, int** returnColum ``` - ----------------------- * 作者微信:[程序员Carl](https://mp.weixin.qq.com/s/b66DFkOp8OOxdZC_xLZxfw) * B站视频:[代码随想录](https://space.bilibili.com/525438321) diff --git a/problems/0093.复原IP地址.md b/problems/0093.复原IP地址.md index 4e56ddc4..c8e94bf4 100644 --- a/problems/0093.复原IP地址.md +++ b/problems/0093.复原IP地址.md @@ -352,6 +352,7 @@ class Solution(object): ans = [] path = [] def backtrack(path, startIndex): + if len(s) > 12: return [] if len(path) == 4: if startIndex == len(s): ans.append(".".join(path[:])) @@ -367,7 +368,7 @@ class Solution(object): path.pop() backtrack([], 0) - return ans``` + return ans ``` diff --git a/problems/0110.平衡二叉树.md b/problems/0110.平衡二叉树.md index 7858fa60..40486d38 100644 --- a/problems/0110.平衡二叉树.md +++ b/problems/0110.平衡二叉树.md @@ -80,7 +80,7 @@ public: } int maxDepth(TreeNode* root) { result = 0; - if (root == 0) return result; + if (root == NULL) return result; getDepth(root, 1); return result; } diff --git a/problems/0332.重新安排行程.md b/problems/0332.重新安排行程.md index 9a9cada9..d3047e94 100644 --- a/problems/0332.重新安排行程.md +++ b/problems/0332.重新安排行程.md @@ -9,7 +9,7 @@ > 这也可以用回溯法? 其实深搜和回溯也是相辅相成的,毕竟都用递归。 -## 332.重新安排行程 +# 332.重新安排行程 [力扣题目链接](https://leetcode-cn.com/problems/reconstruct-itinerary/) @@ -23,13 +23,13 @@ 示例 1: -输入:[["MUC", "LHR"], ["JFK", "MUC"], ["SFO", "SJC"], ["LHR", "SFO"]] -输出:["JFK", "MUC", "LHR", "SFO", "SJC"] +* 输入:[["MUC", "LHR"], ["JFK", "MUC"], ["SFO", "SJC"], ["LHR", "SFO"]] +* 输出:["JFK", "MUC", "LHR", "SFO", "SJC"] 示例 2: -输入:[["JFK","SFO"],["JFK","ATL"],["SFO","ATL"],["ATL","JFK"],["ATL","SFO"]] -输出:["JFK","ATL","JFK","SFO","ATL","SFO"] -解释:另一种有效的行程是 ["JFK","SFO","ATL","JFK","ATL","SFO"]。但是它自然排序更大更靠后。 +* 输入:[["JFK","SFO"],["JFK","ATL"],["SFO","ATL"],["ATL","JFK"],["ATL","SFO"]] +* 输出:["JFK","ATL","JFK","SFO","ATL","SFO"] +* 解释:另一种有效的行程是 ["JFK","SFO","ATL","JFK","ATL","SFO"]。但是它自然排序更大更靠后。 ## 思路 @@ -75,8 +75,9 @@ 含义如下: -`unordered_map> targets`:`unordered_map<出发机场, 到达机场的集合> targets` -`unordered_map> targets`:`unordered_map<出发机场, map<到达机场, 航班次数>> targets` +unordered_map> targets:unordered_map<出发机场, 到达机场的集合> targets + +unordered_map> targets:unordered_map<出发机场, map<到达机场, 航班次数>> targets 这两个结构,我选择了后者,因为如果使用`unordered_map> targets` 遍历multiset的时候,不能删除元素,一旦删除元素,迭代器就失效了。 @@ -258,7 +259,7 @@ for (pairtarget : targets[result[result.size() - 1]]) ## 其他语言版本 -java 版本: +### java ```java class Solution { @@ -307,7 +308,7 @@ class Solution { } ``` -python: +### python ```python class Solution: @@ -340,7 +341,7 @@ class Solution: return path ``` -C语言版本: +### C语言 ```C char **result; @@ -402,7 +403,7 @@ char ** findItinerary(char *** tickets, int ticketsSize, int* ticketsColSize, in } ``` -Javascript: +### Javascript ```Javascript var findItinerary = function(tickets) { diff --git a/problems/0491.递增子序列.md b/problems/0491.递增子序列.md index e947b2b9..e55263a1 100644 --- a/problems/0491.递增子序列.md +++ b/problems/0491.递增子序列.md @@ -9,7 +9,7 @@ > 和子集问题有点像,但又处处是陷阱 -## 491.递增子序列 +# 491.递增子序列 [力扣题目链接](https://leetcode-cn.com/problems/increasing-subsequences/) @@ -17,8 +17,8 @@ 示例: -输入: [4, 6, 7, 7] -输出: [[4, 6], [4, 7], [4, 6, 7], [4, 6, 7, 7], [6, 7], [6, 7, 7], [7,7], [4,7,7]] +* 输入: [4, 6, 7, 7] +* 输出: [[4, 6], [4, 7], [4, 6, 7], [4, 6, 7, 7], [6, 7], [6, 7, 7], [7,7], [4,7,7]] 说明: * 给定数组的长度不会超过15。 @@ -50,7 +50,7 @@ ![491. 递增子序列1](https://img-blog.csdnimg.cn/20201124200229824.png) -## 回溯三部曲 +### 回溯三部曲 * 递归函数参数 @@ -187,7 +187,6 @@ public: **所以正如在[哈希表:总结篇!(每逢总结必经典)](https://programmercarl.com/哈希表总结.html)中说的那样,数组,set,map都可以做哈希表,而且数组干的活,map和set都能干,但如果数值范围小的话能用数组尽量用数组**。 - ## 总结 本题题解清一色都说是深度优先搜索,但我更倾向于说它用回溯法,而且本题我也是完全使用回溯法的逻辑来分析的。 @@ -202,7 +201,8 @@ public: ## 其他语言版本 -Java: +### Java + ```java class Solution { private List path = new ArrayList<>(); @@ -231,8 +231,9 @@ class Solution { ``` -Python: -```python3 +### Python + +```python class Solution: def findSubsequences(self, nums: List[int]) -> List[List[int]]: res = [] @@ -255,7 +256,7 @@ class Solution: return res ``` -Go: +### Go ```golang func findSubsequences(nums []int) [][]int { @@ -285,7 +286,7 @@ func backTring(startIndex int,nums,subRes []int,res *[][]int){ } ``` -Javascript: +### Javascript ```Javascript @@ -313,7 +314,7 @@ var findSubsequences = function(nums) { ``` -C: +### C ```c int* path; int pathTop; diff --git a/problems/0724.寻找数组的中心索引.md b/problems/0724.寻找数组的中心索引.md index 13d2ab68..d05d55b8 100644 --- a/problems/0724.寻找数组的中心索引.md +++ b/problems/0724.寻找数组的中心索引.md @@ -35,9 +35,9 @@ * 解释:中心下标是 0。左侧数之和 sum = 0 ,(下标 0 左侧不存在元素),右侧数之和 sum = nums[1] + nums[2] = 1 + -1 = 0 。 -# 思路 +## 思路 -这道题目还是比较简单直接啊哈哈 +这道题目还是比较简单直接的 1. 遍历一遍求出总和sum 2. 遍历第二遍求中心索引左半和leftSum @@ -64,9 +64,9 @@ public: ``` -# 其他语言版本 +## 其他语言版本 -## Java +### Java ```java class Solution { @@ -89,7 +89,7 @@ class Solution { } ``` -## Python3 +### Python3 ```python class Solution: @@ -103,7 +103,7 @@ class Solution: return -1 ``` -## Go +### Go ```go func pivotIndex(nums []int) int { @@ -126,7 +126,7 @@ func pivotIndex(nums []int) int { ``` -## JavaScript +### JavaScript ```js var pivotIndex = function(nums) { diff --git a/problems/0922.按奇偶排序数组II.md b/problems/0922.按奇偶排序数组II.md index 43046133..4f60666f 100644 --- a/problems/0922.按奇偶排序数组II.md +++ b/problems/0922.按奇偶排序数组II.md @@ -26,11 +26,11 @@ * 解释:[4,7,2,5],[2,5,4,7],[2,7,4,5] 也会被接受。 -# 思路 +## 思路 这道题目直接的想法可能是两层for循环再加上used数组表示使用过的元素。这样的的时间复杂度是O(n^2)。 -## 方法一 +### 方法一 其实这道题可以用很朴实的方法,时间复杂度就就是O(n)了,C++代码如下: @@ -59,10 +59,10 @@ public: }; ``` -时间复杂度:O(n) -空间复杂度:O(n) +* 时间复杂度:O(n) +* 空间复杂度:O(n) -## 方法二 +### 方法二 以上代码我是建了两个辅助数组,而且A数组还相当于遍历了两次,用辅助数组的好处就是思路清晰,优化一下就是不用这两个辅助树,代码如下: @@ -88,10 +88,10 @@ public: }; ``` -时间复杂度O(n) -空间复杂度O(n) +* 时间复杂度O(n) +* 空间复杂度O(n) -## 方法三 +### 方法三 当然还可以在原数组上修改,连result数组都不用了。 @@ -111,15 +111,15 @@ public: }; ``` -时间复杂度:O(n) -空间复杂度:O(1) +* 时间复杂度:O(n) +* 空间复杂度:O(1) 这里时间复杂度并不是O(n^2),因为偶数位和奇数位都只操作一次,不是n/2 * n/2的关系,而是n/2 + n/2的关系! -# 其他语言版本 +## 其他语言版本 -## Java +### Java ```java // 方法一 @@ -149,7 +149,7 @@ class Solution { } ``` -## Python3 +### Python3 ```python #方法2 @@ -179,7 +179,7 @@ class Solution: return nums ``` -## Go +### Go ```go @@ -206,7 +206,7 @@ func sortArrayByParityII(nums []int) []int { } ``` -## JavaScript +### JavaScript ```js //方法一 diff --git a/problems/前序/互联网大厂研发流程.md b/problems/前序/互联网大厂研发流程.md new file mode 100644 index 00000000..9616958d --- /dev/null +++ b/problems/前序/互联网大厂研发流程.md @@ -0,0 +1,238 @@ +# 揭秘互联网大厂研发流程 + +很多录友会很好奇这么个事: + +* 大厂的研发流程应该是什么样的呢 +* 为什么会有那么多繁琐的流程呢 +* 每一步都有什么作用呢 + +这次给大家介绍一波大厂的研发流程,让大家明明白白。 + +同时我已经录制了视频,昨晚已经在B站首发了。 + +视频里讲的更清楚一点,因为我是没有草稿,先录的视频,然后在根据视频写的文章,写文章的时候,发现我视频里讲的太多了,码字实在是码不过来,所以这篇文字稿中每一个研发环节的解释稍稍精简了一下。 + +如果详细了解研发流程就直接看视频吧,**别告诉卡哥,你还没关注 「代码随想录」的B站,还不赶紧关注一波[机智]**。 + +重要重要重要: **要给三连呀!** + +[B站:揭秘互联网大厂研发流程](https://www.bilibili.com/video/BV1KR4y1H7ST) + + +其实对于几十人或者上百人一起开发一个项目的话,一个规范的研发流程是很重要的。 + +有的同学可能想,哪有这么多流程啊,就是写完代码,跑一下,没问题,然后就上线了。 + +其实在大厂里研发流程是很重要的。 + +**一个项目从开发到上线到后面的维护,从流程上就保证大家少出错,也方便后面人继续维护**。 + +那么接下来给大家介绍一下详细的流程。 + +## 1.需求文档 + +看需求文档,我们要根据需求文档来确定我们究竟要做什么。 + +一些同学可能感觉 为什么还要用一个需求文档呢,你就告诉我做啥我就做啥不就完事了。 + +其实需求文档一方面是倒逼产品经理去系统性的思考这个需求究竟有哪些功能,用来满足哪些用户的需求。 + +另一方面,是保证我们在研发的时候,研发出来的功能是满足需求文档里所描述的。 + +如果是口头对接的话,很有可能就是你做出来的东西,产品经理看完感觉:这和我说的需求不一样啊!!这和我想的不一样啊!! + +这样就是两个人相互甩锅,那这究竟是谁的锅呢。都没有一个证据,对吧。 + +所以说,有一个需求文档很重要。 + +而且每个阶段的需求文档相当于是把这个项目的整个迭代过程都记录下来了。 + +这样也方便后面的人,了解这个项目是如何迭代的。 + +## 2.这个需求包含了哪些功能 + +产品经理在需求文档里描述一个功能,那么我们在实现的时候,可能要改很多模块,或者说我们要增加一些模块。 + +就是我们从代码的角度上来讲,可能要增添很多功能才能满足 用户看起来好像微不足道的小功能。 + +例如点击登录,点击下单,后台都有很多模块协同运行的。 + +我们要把产品经理角度上的这个功能,拆解为我们代码角度上的具体应该开发的那些功能。 + +## 3.确定有哪些难点 + +这里可能有同学疑惑了,我确定这东西干嘛呢。 + +给大家举一个例子,给你一个需求文档。 + +你说你一周的时间就能把它开发完,那为什么是一周呢,为什么不是两天,为什么不是两周呢。 + +其实 和上面的领导汇报你的工作的时候 都要把自己的工作进行量化。 + +那么这个功能有哪些难点,我们要克服这个难点,所需要花费的时间,都要有一个大体的量化。 + +这样才能量化我们自己的工作,**领导其实不知道你的工作是简单 还是困难, 领导只在意最终结果**,所以你要展现给领导你的工作是有难度的是有挑战的。 + +而且这些也是我们年底用来晋升或者评职称的素材。 + +如果这些东西你自己都不在乎的话,谁还会帮你在乎呢。 + +而且**确定了自己的工作难点,把这些难点都记录下来,对以后跳槽也很有帮助**。 + +面试官最喜欢问的问题,就是:**你做的项目中有哪些难点?以及你是如何克服的**。 + +所以这一步对自己个人成长来说也是很有重要的。 对于项目组来说也是记录下来,每一个迭代版本有哪些难点,这些难点团队是如何克服的。 + +这也是项目组往上一级去邀功的资料。 + + +## 4.画架构图 + +一般来说,大厂项目的架构都是比较复杂的,特别是后端架构。 + +如果添加一个模块连个文档都没有,连个图也没有,上来就添加的话,后面的人是很难维护的。 + +而且每个模块和每一个模块之间的依赖关系,如果没有画出一个架构图的话,直接看代码很容易直接就看懵了。 + +为什么你可以快速开发一个新的模块,也是因为之前团队有人把这个架构图画清楚了,你只需要看一眼这个架构图,就知道你的模块应该添加在哪里。 + +那么你去添加模块的时候,也应该把这个架构图相应的位置 完善一下。 + +同时呢,在画架构图的过程中,也增添了自己对整个系统架构的掌握程度。 + +这个图也会让你确定,你的模块在整个项目中扮演一个什么样的角色。 + +## 5.定协议 + +后台模块之间进行通讯需要协议,后台和前端通讯也需要协议。 + +所以只要有交互,就要确定协议的数据格式。 + +定协议要考虑到兼容,要考虑易于维护。 + +## 6.设计数据结构和算法 + +其实设计数据结构更多一些,因为我们要选择使用什么容器,什么格式来处理我们的数据。 + +至于算法的话,就很少我们亲自设计了。 + +什么快排,二叉树,动态规划,最短路啥的,在实际开发中,都不需要我们自己去写,**直接调包!** + +面试造火箭,工作拧螺丝 就体现在这里。 + +为什么会这样呢? 一个很简单的例子,互联网研发讲究其实就是要快,例如一个功能2天就要开发完,如果算法都要自己去写的话,等都写完了,花都谢了。 + +## 7.预估一下容量 + +特别是后端开发,要估计出 我们自己模块大体需要多大磁盘,多大内存,多大带宽,多少核CPU。 + +这也是没有做过研发工作的同学经常忽略的,**因为大家好像默认 磁盘、内存、带宽、cpu是无穷的**。 + +其实我们在设计一个模块的时候,这些都要评估的,不能模块一上线,把机器直接打爆了,例如 直接把带宽打满了,不仅影响自己的模块功能,还影响了机器上其他模块的运行。 + + +## 8.考虑部署 + +要考虑如果一台机器挂了(可能是硬件原因),那么我们的模块还能不能正常提供服务。 + +这就是考虑模块的容灾性,一般都是采用分布式,服务部署在三台机器上,一台如果挂了,还有其他两台提供服务。 + +还有就是要弹性可伸缩,即我们的模块可不可以直接 部署多台机器来提高承载能力。 + +如果用户量突然上来了,或者流量突然上来了,可以通过快速部署多台机器来抗住流量。而不是模块只能在单机上跑,多部署几台就发生各种问题。 + +**这才能说明是有足够强的风险意识的**。 + +## 9.设计评审 + +前八的阶段其实都是设计阶段,那么你的设计需要让组里的同学一起来评审一下,看看有没有什么问题。 + +大家主要也是看看你的模块 会不会给其他模块或者整个系统带来什么问题 以及 设计的是否合理。 + + +## 10.写代码 + +终于到写代码的阶段了,其实到这时候,是最容易的。 + +**写代码就是体力活了,不是脑力活了**。 + +## 11.自测 + +写完代码,我们需要自测,自己的功能会不会有什么问题。 + +这里可能需要自己造一造数据,跑一跑 看看和预想的是不是一样的。 + +## 12.联调 + +自己的模块可能会涉及到其他模块之间的一个交互,或者和前端的一个交互。 + +所以需要其他同学配合一起来测试。 + +这里就有很多沟通工作了,因为其他同学可能手头有自己的活,那么就要协调一个时间来一起测试。 + +这一步也是很费时间的,其费时关键是要等,要等其他同学有空和你联调,而且往往不是联调一次就能解决问题的。 + +所以 在评估开发时间的时候 也要考虑到联调的时间。 + +这也是大厂研发效率低的地方,但上百人开发的项目,这种沟通上消耗也是在所难免的。 + +## 13.交给测试 + +自己的代码,自己测 一般都测不出什么问题,需要交给测试同学来给你测一测。 + +这里如果测试同学测出问题,你就要判断确实有问题还是 测试方式不对,如果有问题就要修改,在提给测试,反反复复这么几轮,直到测试同学测试没问题了。 + +这个过程也是累心的。 + +## 14.code review + +代码合入主干之前,需要 项目组的同学一起来评审一下你的代码。 + +之前是评审设计,看设计上有没有什么缺失,这次是大家来看看你代码写的怎么样。 + +例如合入主干会不会有什么问题,代码兼容性做的好不好,接口设计的好不好,甚至字段,函数,变量名,命名合不合理。 + +都要经过大家的评审,如果有问题就还是要改。 + +如果没有问题一般 大家会给+2(就是通过的意思),这样就可以合入主干了。 + +## 15.合入主干 + +合入主干为什么会单独列出来呢。 + +其实合入主干是很重要的,经常是自己的代码没问题,但合入主干之后就有问题了。 + +一般就是合入主干的时候有冲突,例如你从主干拉出一个分支,另一个同学从主干拉出一个分支,而且两个分支修改了同一个模块,如果另一个同学提前合入主干,你在合入主干的时候就会有代码冲突。 + +在解决代码冲突的时候 就会修改别人的代码,这个过程很容易产生新的bug。 + +**一般合入主干之后,测试同学还要重新跑一个全量测试,才能放心发布**。 + +## 16.发布 + +最后一步就是发布了。 + +发布其实就是把主干的代码更新到线上的服务器上。 + +一些还没有工作的同学,可能不太理解究竟什么是发布。 + +用大白话来讲,就是把 本地的代码或者某台机器的代码,编译成可执行文件,然后更新到 线上的服务器(一个独立的集群,专门处理线上的流量)并运行起来。 + +上线是最重要的一步了,也很容易出问题,因为一个大型项目,其上线的过程都非常复杂(要更新上百台机器的集群),而且要考虑线上新版和旧版本的兼容问题。 + +这也是为什么大厂项目都选择深夜上线,**因为深夜在线用户最少,如果出问题,影响的用户会比较少,可以快速修复**。 + +所以大家经常看到 某大厂程序员深夜上线发布版本之类的。 + +# 总结 + +好了,整整讲了十六个步骤!​把大厂研发流程中 具体都有哪一步,为什么要这么做,都分析的很清楚了。 + +不过在大厂也不是所有部门都按照这个流程来的,每个部门都有自己玩法,各个部门也不太统一。 + +我这里是介绍的是已经比较规范的流程,**但流程越正规,研发效率就越低,想要提高效率,就是简化流程,简化流程,就会提高项目出错的概率**。 + +**所以这也是一个相互权衡的过程,每一个部门可能根据自己的业务特点,适当简化流程**。 + +好了,讲了这么多,希望对录友们有所启发。 + diff --git a/problems/知识星球精选/HR特意刁难非科班.md b/problems/知识星球精选/HR特意刁难非科班.md new file mode 100644 index 00000000..c59debf2 --- /dev/null +++ b/problems/知识星球精选/HR特意刁难非科班.md @@ -0,0 +1,47 @@ + +

+ + + + +# HR特意刁难非科班! + +不少录友都是非科班转程序员,或者进军互联网的,但有一些HR在HR面的时候特意刁难大家。 + +正如[知识星球](https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ)里,这位录友所遭受的情景。 + +![](https://code-thinking-1253855093.file.myqcloud.com/pics/20211006230202.png) + +1. 你的研究方向并不是这个方面的,你为什么要转行? +2. 你和非科班的同学相比肯定有一些劣势,你打算怎么赶上他们?或者是你如何应对你作为非科班生在工作中的挑战? + +以下是我的回答: + +对于问题一,你这么说没问题,可以再润色一下,说一说自己看过哪些技术大牛的传记,例如《黑客与画家》,对自己影响很大,然后对编程就非常感兴趣,想从事这个行业 等等。 或者说 你感觉 新能源汽车是以后非常明确的方向,而自动驾驶是新能源汽车的标配,所以想投身这个行业。 + +问题二: 首先要自信起来,说:在技术方面和对编程的热情方面,我不比科班同学差,因为大学里教的内容和企业要求的基本脱钩的,大家准备面试进大厂都是靠自学,**反而因为我是非科班,我更加的努力,也特别珍惜来之不易的机会**。 + +如果要说科班同学有什么优势的话,我感觉他们的学习编程的氛围会好好一些,也就是遇到问题大家能一起交流,因为我车辆工程专业,所以我会经常去蹭计算机的课,也会去认识很多计算机专业的同学和他们一起讨论问题。 + +总之在HR面的时候,不要说自己哪里的缺点,也不说自己哪里技术掌握的不好,**HR不懂技术,你说自己哪里不懂,他就真认为你不懂了**。 + +缺点就说一些不痛不痒的,甚至化缺点为自己的优势。 + +例如问你的缺点是什么? + +**可以说自己有时候 对技术细节过于执着,以至于影响整体的进度**。 + +这种缺点 无形之中 就体现出自己 对技术的热爱和专研 (起到装逼于无形的效果),而且 这种缺点 是分分钟就可以改的。 + +如果问你 :作为非科班生在工作中的挑战? + +你也这么说:其实大家都是靠自学,如果说非科班在工作中遇到的挑战,我相信 科班同学在工作中也是遇到一样的挑战,工作之后自学能力更加重要,互联网变化是飞快的,只有自学能力强的同学才能跟上步伐。 + +然后随便举例一下,说明自己自学能力如何如何的强,就可以了。 + +**总之不能示弱,不能说自己哪里不好,哪里不行!** + +HR也不懂技术,主要就是看你的态度。 + +就酱,希望对录友们有所启发,加油💪 + diff --git a/problems/知识星球精选/offer的选择.md b/problems/知识星球精选/offer的选择.md new file mode 100644 index 00000000..b9b40dea --- /dev/null +++ b/problems/知识星球精选/offer的选择.md @@ -0,0 +1,137 @@ + +

+ + + + +# offer的选择 + +秋招基本要结束了,一些录友也拿到了一些offer,如果是拿到大厂和小厂的offer,那当然就不用纠结了,直接选大厂。 + +不过大部分同学应该拿到的是 两个大厂offer,或者说拿到两个小厂offer,还要考虑岗位,业务,公司前景,那么就要纠结如何选择了。 + +在[知识星球](https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ)里,我已经给很多录友提供了选择offer的建议,这里也分享出来,希望对大家在选择offer上有所启发。 + +## 保研与工作 + +![](https://code-thinking-1253855093.file.myqcloud.com/pics/20211005233504.png) + +1. 建议你直接工作,你都已经拿到了大厂offer,没有必要读研究生了,如果你是保研到 985高校,倒是可以考虑考虑。 +2. 这是送分题,去百度吧,贴吧不算边缘,而且百度对新人的培养体系是很到位了,及时是边缘,对你技术成长也很有帮助,而且还有大厂光环。 + +3. 星球里 前端同学也很多啊,只不过你没注意到而已,我经常看到。而且前端和后端都是一样的,不能说没地位,不过不同的部门不太一样而已。(大家都是打工的,不用搞出鄙视链哈哈) +4. 躺平吧,可以歇息了,给还没拿offer的录友一条出路 + + +## 阿里云与微众 + +![](https://code-thinking-1253855093.file.myqcloud.com/pics/20211005233646.png) + +中间件一点都不吭啊。 + +有云的地方,有分布式的地方,就有中间件,应用面很广泛,各大厂哪个能离开云计算,哪个能离开分布式,你就知道中间件有多重要了。当然中间件也是很大的一个领域了,是基础架构范畴。 + +关于业务部门和基础架构部门的选择,**我也倾向于 应届生选择基础架构部, 业务部门很忙没有时间沉底技术**。 + +其实你还要考虑,以后跳槽出来如何,在微众做基础架构,以后 跳槽可能更容易一些。注意跳槽不一定是你主动的,可能是被动跳槽。 + +假如阿里给你来个3.25 你就要找下家了,做 供应链管理 技术上没有太精进的话,找下家不太容易。 + +关于两个公司,我感觉差不多,微众也很不错,一般给出的薪资都比较高。 + +至于买房,杭州现在的房价涨的很猛,虽然说整体没有深圳高,但也差不多了,码农聚集地,就别想着房价多便宜。 + +互联网金融 这块后面发展一定是大势所趋的,不会差。 + +两个offer都不错,选哪个都可以! + +对技术有追求,我倾向于微众,如果对BAT有执念,就去阿里吧。 都差不多。 + +## 深信服、小米和海康 +![](https://code-thinking-1253855093.file.myqcloud.com/pics/20211006094624.png) + +音视频开发现在很火,是一个很好的方向,音视频里也是一个很大的方向了,里面有 音视频信号分析与处理、音视频编解码格式压缩、音视频文件打包封装、流媒体推流协议处理等等。 + +现在 腾讯会议,阿里钉钉,zoom都是靠音视频技术起家。 而且发展势头很不错。 + +但如果只是基于现有音视频做 SDK开发,那就没啥意思了。所以也是看具体的工作内容了。 + +股票这个 不用报太大期望,大概率 你等不到那个时候。 + +其实 深信服的技术栈 也挺封闭的,毕竟是算是比较偏硬的厂商,深信服做云计算,也是私有云,最终也是卖硬件。 + +不过小米其实你也说不好最终入职具体是干啥。 + +选一个的话,倾向于选深信服吧,毕竟深信服总部就在深圳,同事多,大家有个交流,相对来说发展稳定一些。小米 好像最近 深圳才有部门吧,估计应该没多少人,甚至入职之后 可能你单兵作战,和同事没有交流的话,无论是工作还是成长都比较难。 + +海康更硬一些,是做安防的,所以C++服务器开发基本是服务安防设备。 相对来说,选深信服更好一些,毕竟深信服是做网络安全和云计算的。 + +## 奇安信、顺网科技和东方财富 + +![](https://code-thinking-1253855093.file.myqcloud.com/pics/20211005234238.png) + +这两家公司我也不太了解。 我就从业务上 简单分析一下 + +现在很多公司做私有云都有用OpenStack,你针对OpenStack 做二次开发,估计不太用深入理解OpenStack,但如何你能沉下心来学下去,以后跳槽的话 出路还是比较多的。 **就要看你对技术有没有钻劲了**。 + +东方财富 毕竟不是互联网公司,**主要业务也不是技术驱动,可能技术部门话语权还是挺低的**,大概率 可能是日常后台增删改查处理一些信息,(注意这也是我猜的,真实情况也要亲自体验了才知道) + +综上,我感觉 如果对技术热情一般,可以考虑东方财富(毕竟给的钱多), 如果想以后技术立身,考虑奇安信。 + + +## 字节客户端、度小满后端 +![](https://code-thinking-1253855093.file.myqcloud.com/pics/20211005234515.png) + +你这拿到这么多大厂offer,还说自己菜,凡尔赛石锤了,哈哈哈 + +客户端确实在劝退,但 客户端不会消失,现在客户端都在往大前端方向去转,**如果你很喜欢字节,喜欢 抖音的话,可以考虑去抖音做IOS**。但如果你一直做IOS的话,指定是发展不容乐观,入职之后就要考虑自己的下一步方向。 + +度小满后端支付业务 这个其实也不错,支付业务是核心部门,以后跳 微信支付,跳蚂蚁 都是可以的,每个互联网巨头都要做自己的支付。 + +这两个offer都可以。 + +如果非要选一个的话,我倾向于 选度小满后端支付业务吧。 以后 跳槽 选择更多一些。可以 通过社招 再去BAT,这时候自己的方向也比较稳定。缺点:不是大厂 + +如果对字节有情节,去也可以的,大厂福利待遇都不错,缺点:要考虑自己以后的方向。 + + +## 百度和华为 + +![](https://code-thinking-1253855093.file.myqcloud.com/pics/20211006095816.png) + +针对于你的问题,我挨个说一下哈: + +1. 大华是做安防的,和主流互联网偏了一些。 +2. 成都有没有招人的机会,这个我也确定不了,但可以确定的是,第一份工作确实很重要!对以后的发展还是有很大影响的。 不过和 女朋友异地 如何权衡还是要看你自己。 +3. 百度大数据 也有做toB,就是给企业提供服务,做toB是比较辛苦,而且赚的不多(这里指的是部门营收),不过相对于你的其他几个offer,我倾向于你选百度,百度对应届生的培养还是很到位的。对你以后的技术发展有帮助。 而且大数据做tob的不止百度一家,阿里云,腾讯云,等等很多都做大数据toB,以后跳槽也容易。 +4. 这种情况有没有救,我也不清楚了,大概率是不太行了,不用过于纠结,能抓住目前的机会就很好了。 + + +## 大华和小米 + +![](https://code-thinking-1253855093.file.myqcloud.com/pics/20211005234847.png) + +倾向于选小米吧,大华是做安防的,**在安防公司里做客户端,可以说是偏上加偏了**。 + +关于 小米南京工资 我也不了解,不过一般来说 南京工资都会低一些。 + +小米手机部门,以后你的选择 也会多一些,毕竟国内这么多手机厂商,而且小米的发展势头还是可以的,最近小米在发力小米汽车,如果能内部转岗到小米汽车,就很不错了,这是未来十年的一个重大机会,可以跟着雷总起飞。 + +在看以后定居,南京的房价可比杭州亲民多了,南京也就2w一平左右,以后你在南京定居基本压力不大,如果算上房价,杭州大华多出来的那点工资 简直不值一提了。 + +# 总结 + +最后我也只是针对大家给我的情况,我来做一个基本的分析,给出我的判断。 + +毕竟最了解你的,还是你自己,而且入职之后 工作具体内容,部门发展,其实我们都无法预测,只能结合我们能确定的内容来做分析。 + +拿我自己来举例,我当初毕业拿到是腾讯互娱XX工作室的后端开发offer 和 华为2012 数据库部门的offer,当然还有其他offer就不提了,那么当时问身边朋友前辈,一定是选 腾讯了,我也倾向于腾讯,但这么多年过后 反过来看,我感觉当初如果去华为可能更好一些。 + +具体原因我也会在知识星球里做分享。 + +所以 **在选择offer上,是有很多是未知的,再好的部门也有坑,再差的部门 遇到好领导也会很舒服**。 + +**我们只能把握住 目前能把握的,至于后面怎么样,只有经历了才知道**。 + +录友们在选择offer上,也多和问一问身边的同学,前辈们,多方面接受建议,在结合自己的情况做出判断,也希望录友们都有一个好的发展,加油💪 + diff --git a/problems/知识星球精选/初入大三选择考研VS工作.md b/problems/知识星球精选/初入大三选择考研VS工作.md new file mode 100644 index 00000000..ba675761 --- /dev/null +++ b/problems/知识星球精选/初入大三选择考研VS工作.md @@ -0,0 +1,49 @@ + +

+ + + + +# 初入大三,考研VS工作 + +9月份开学季,已过,一些录友也升入大三了,升入大三摆在自己面前最大的问题就是,考研还是找工作? + +在[知识星球](https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ)里就有录友问我这样一个问题, 其实每个人情况不一样,做出的选择也不一样,这里给大家分享一下,相信对你也会有启发。 + +![](https://code-thinking-1253855093.file.myqcloud.com/pics/20211002110618.png) + +以下是我的回答: + +首先我是考过研的,比较幸运一次就上岸了,这里说一下我的心得。 + +你才刚刚大三 就已经做了这么充分的准备了,那我倾向于 选择直接工作。 + +因为现在你准备的这些,都是找工作需要的,也都是实用的技术。 + +如果你明年初就开始准备考研了,那么你现在学的这些东西,就是半途而废了,考研一年 能让你的 编程技能水平 回到解放前(考过研的同学应该都懂的)。 + +不能说考研的内容一点用都没有,如果从技术学习的角度来说,其投入产出性价比极其极其极其的低。 + +举一个不太恰当的例子,考研就是大家一起学 “一个不太实用的知识”,看谁学的好。 + +所以考研其实更多的是学历上的提升,如果想通过考研,或者读研学习到什么? **还是不要有这个打算,大概率会让你失望的**。 + +正如你所说的,你有信心成为年级里比较优秀的(就业方面),也正是 准备的早,所以给了自己信心。 + +而且你们学校还有很多学长本科毕业就找到了好的工作,完全可以追随他们的足迹。 + +去考研的话,有信心考上更好的学校,当然可以,关键是 考研也是千军万马过独木桥,特别是计算机考研,特别是985名校,非常的卷。 + +如果没考上研究生,再去找工作就很被动了。 + +这也是为什么,很多一战失利都会选择二战,因为如果失败,损失很大,所以这条路还要继续走下去,一定要上岸。 + +再结合自己的情况,假如能考上,但考上了一所一般学校,其实对自己来说都是损失。 毕业之后 未必 有现在直接找工作找的好,年轻就是优势,特别是做研发,读研出来也是做研发,本科也是做研发,其实没太大区别的。 + +所以 如果本科毕业的学长学姐 就业也不错,可以追随他们的脚步,毕竟你已经开始准备了。 + +**如果有信心要冲 名校计算机研究生,或者说对某一所大学有情节,添补高考遗憾,那么可以冲,考上了是值得的**。 + + +当然也可以多和身边的 师兄 师姐交流,看看他们的说法,综合评估一下。 + diff --git a/problems/知识星球精选/天下乌鸦一般黑.md b/problems/知识星球精选/天下乌鸦一般黑.md new file mode 100644 index 00000000..29543747 --- /dev/null +++ b/problems/知识星球精选/天下乌鸦一般黑.md @@ -0,0 +1,71 @@ + +

+ + + + +# 天下乌鸦一般黑,哪家没有PUA? + +相信大家应该经常在 各大论坛啊之类的 看到对各个互联网公司的评价,有风评好的,也有风评不好的。 + +在[知识星球](https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ)里有录友问我这样一个问题: + +![](https://code-thinking-1253855093.file.myqcloud.com/pics/20211004095707.png) + +这位录友,拿了阿里云,腾讯,百度,shopee的意向书,可以确是收割机了,但如果还没有进入职场,还容易被网上这些风评误导。 + +卡哥来客观的分析一下,如何看到这些网上对公司的评论。 + +脉脉,知乎上喷阿里,百度的 都比较多。喷腾讯的确实少一些。 + +**只能说腾讯的舆论控制相对比较好**,在加上职能体系的人文关怀比较到位(公仔,各种活动,逢年过节小礼品之类的)。 + +但**天下乌鸦一般黑**,腾讯的职场PUA,一点都不比阿里的少,各种套路 ,阿里有的,腾讯都有,还有什么各种花边吃瓜新闻,在腾讯内网特别多。 + +但这些都在公司内网传播,很少传出去。 这就是腾讯厉害所在了。 + +其实我们在选择公司的时候,**主要是看岗位,看业务,看发展**,至于 有没有PUA之类的,只能说**有人的地方就有江湖**,腾讯人 就比 阿里人 就更正直么? + +相信大家都参加过面试。招聘的时候,几个小时的面试能看出人品么?对吧。 + +各种新人背锅,末尾淘汰,PUA,阿里有的,腾讯都有。 所以大家求职的时候不用在乎这些风评。 + +至于这种锅和套路 能不能落到自己的头上,就要看碰到了什么样的直属领导了。 + +例如两位同学去了同一家公司,同一个事业群,同一个部门,同一个项目组,只是在两个不同的领导下干活,其区别都可以一个天上,一个地上。 + +有的录友 可能对职场套路不太了解,或者 初入职场比较顺利,没有感受过什么套路。 + +这里卡哥给大家随便说一个,例如,一个项目组,有前端组和后端组,分别是两个老大,有一个需求,要开发一个功能,这个功能本来前端就可以独立完成的,但上线可能会有风险,保护自己手下的前端领导,就会让前端同学和后端的同学一起实现这个功能,也就是前端实现一部分,后端也要做一部分数据处理,前端展示就可以了。 + +为什么这么安排呢? + +因为一旦上线出问题了,就是前端和后端一起背锅,这样前端同学压力就小很多了。 + +而整个需求安排,前端同学其实并不知道 自己的风险,其实是领导保护了他。 + +那么 不保守下手的领导,当然就啥也不说了,让你一个人把这个功能做了,上线没出问题 那还算万事大吉,一旦出问题,那年底考核是不是就要背一个指标了。 + +所以不要感觉程序员的工作环境很单纯,其实套路多得很,还是那句话:**有人的地方就有江湖**,不区分公司的。 + +只能说 业务发展越好的部门,套路相对来说少一点,毕竟高速发展可以掩盖很多问题。 + +**所以遇到什么样的直属领导非常非常的重要**,但这又是我们决定不了的。 所以这都看缘分(运气)了。 + +有的同学毕业在大厂顺风顺水,除了自己努力外(而大家谁又不努力呢?),更重要的是遇到了好领导。 + +但有的同学同样进大厂,发展就很差,而且没人给他指引一些部门潜在的规则,那就难免会撞坑。 + +未必是他不够努力,不够聪明,不会沟通,可能恰巧 部门效益不好,部门考核就差,领导一般不会让老人背锅,毕竟系统的bug都是老人写的,老人都走了,谁来修bug呢(人间真实)。 + +那领导就拿他这个新人开刀了呗。 + +所以,**同样是进大厂,发展好的同学 不用过于优越感,感觉是自己能力多强,其实大概率是赶上了 好部门好领导,发展不好的同学也不要 自责自己能力不行,甚至开始自卑,大概率是运气不太好而已**。 + +那么是 发展好坏全看运气了么,当然不是! + +重要是 遇到挫折(背锅,绩效不好,甚至被开除),不要自卑,不要放弃,相信自己,只要把时间拉长,5-10年的时间,**真正努力的人,发展都不错!** + +卡哥希望录友们都有好的发展,加油💪 + + diff --git a/problems/知识星球精选/非科班2021秋招总结.md b/problems/知识星球精选/非科班2021秋招总结.md new file mode 100644 index 00000000..c2c7ed33 --- /dev/null +++ b/problems/知识星球精选/非科班2021秋招总结.md @@ -0,0 +1,117 @@ + +

+ + + + +# 非科班,收获满满! + +九月份悄然已过,秋招已经快接近尾声了,星球里已经纷纷有录友开始写这次的秋招总结。 + +其中一位录友写的很好,所以想分享出来 给公众号上的录友也看一看,相信对大家有所启发,特别是明年要找工作的录友,值得好好看一看。 + +这篇总结首发在代码随想录[知识星球](https://mp.weixin.qq.com/s/QVF6upVMSbgvZy8lHZS3CQ)上,立刻就获得了60个赞,很多评论,我这里放出一个截图: + +![](https://code-thinking-1253855093.file.myqcloud.com/pics/20210929220903.png) + +以下是星球上该录友的总结: + +-------------------- + +211本硕非科班菜鸡转码不到一年,从最开始的迷茫到后面认识到差距的焦虑再到后面逐渐恢复坦然的心态,一路起起伏伏,但也算连滚带爬的趟了过来,**感激一路上耐心为我答疑解惑的各路大佬,尤其是咱们卡哥哈哈**。 + +秋招收获如下(按收到意向顺序): + +* 诺瓦星云 西安 软件开发工程师 提前批意向书 +* 字节跳动 抖音客户端开发工程师 提前批意向书 +* 滴滴 网约车部门后端开发工程师C++/Go 提前批意向书 +* 腾讯 IEG光子工作室技术中心测试开发 正式批意向书 +* 美团 基础研发平台后端开发工程师JAVA 正式批意向书 +* 阿里 阿里云计算平台后端开发工程师C++ 正式批意向书 + +被终结的岗位: +* 蔚来 提前批后端三面挂 +* 百度/京东 后端提前批无音讯,正式批笔试我就都拒了 +* 网易 正式批一面过,但感觉不喜欢,二面就放弃了 +* 虾皮 提前批二面挂(北京hc太少,卷不动,秋招甚至直接不放岗) +* 蓝湖 提前批二面挂(面完字节三面之后半个小时紧接着蓝湖二面,字节面了两个小时,人都麻了,强烈建议大家面试不要排太挤!!) +* 招银网络 正式批一面过,二面放弃 +* 商汤、oppo、知乎 提前批简历挂,后面懒得投了 + +# 秋招历程 + +## 开始准备 + +最开始的准备是从**去年十月份左右开始**,那个时候刚开始意识到自己将来找工作的问题,就选择了一门自己相对来说有一些基础的C++开始入手学习,看到网上的很多经验都说语言不是最大的问题,能学好一门后面转型都很快,所以并没有在这个问题上有什么纠结,大家看我拿到的岗位也可以发现事实确实如此。 + +**从十月份开始看C++ Primer这本书**,断断续续花了三个多月,确实拉胯。 + +当时主要是事情太多,而且我在熟悉完主要的语法和特性之后,大概一个月的时间吧,就开始上手刷leetcode了,入门真的很痛苦,递归啥的看一遍忘一遍,一天吭哧吭哧弄下来也就两三道题,还基本都不是自己写出来的,因为我光理解别人的方法就需要很长时间。 + +**后面刷题解刷到了卡哥,着实幸运,跟着卡哥的题解我也逐渐有了自己的方法模式和比较规范的代码风格**,所以到后面尽管有时候会发现也会有比卡哥更好的方法,我还是愿意先上手走一遍卡哥的思路,之后再补充别的。 + +**不得不说,题解能跟住一个人确实很有必要**,有的题卡哥没有出题解,我也是先找到之前卡哥类似的题目找思路,再自己写出来。整个刷题的流程持续到过年,我就开始刷剑指offer了,基本简单题都可以撕,中等困难的还是只能看题解。 + +我个人的经验是不愿意在思考题解上浪费太多时间,**如果打眼一看就知道自己不太可能做出来,我会选择直接看题解**,省下的时间哪怕自己多敲两遍也比对着屏幕发呆效率高,毕竟面试考察的不是你创造算法的能力,会用就行了,当然这只是个人见解,大佬息怒。 + +刷完剑指offer大概花了半个月的时间,**时间也来到了三月份**,周围的不少人已经开始找春招实习,但更多的人还是和我一样,由于各种原因没法去找实习。 + +这个时候各种情绪都会有,焦虑,迷茫,没办法,改变不了现实情况只能尽可能的提升自己。 + +这个时候我的算法已经比较熟练了,基本一天不用太多时间也能过四道题,尽管其中仍有不少是对着题解敲的,但是对别人思路的理解确实已经练得轻车熟路了,我觉得这也是一种进步吧。 + +**四月份开始准备项目**,没错,就是烂大街的webserver,大家都知道这个项目烂大街,但是经过后面的各种面试我也发现,不管你是什么项目,对于面试官来说都很基础。 + +哪怕是大厂实习的人又有几个能接触到核心,当然这也是对大部分人说的,实习大佬勿喷。**所以面试考察的就是你对基础的掌握**,就算你讲了项目各种高大上的方法,虽然可能有加分,但也是在给自己埋坑。 + +比如面试官可能问你有没有看过这个技术具体实现源码等等。 + +**把自己捧的越高,一旦被发现基础有漏洞,摔得也越惨**,面试官对每个人都会有一个心理预期,比如我可能就因为非科班占了一些心理预期比较低的便宜,也就是不容易让对方失望,客户端我0基础,测开0基础,但是都过了,当然像我这样的坏处就是offer大概率只是白菜,所以综合来看有利有弊,大家自己权衡。 + + +**搞这个webserver连带各种计网,操作系统的学习花了两个月的时间**。之后便开始了面向面经自习的流程。 + +这个时候算法题基本不再做新的了,力扣累计刷题已经接近400,我知道里面不少题就算再拿给我,我也不一定会做,所以做新题有什么意义呢,能把之前的高频题,热题刷好就已经超过很多人了。 + +因为之前做题都是自己按标签做,后面看到卡哥出了系列题解,基本都是我之前做过的,所以**花了一周左右就把卡哥的pdf全过了一遍,帮助很大**。 + +## 提前批 + +**后面六七月份的提前批我参与的不是特别积极**,和大多数人一样,我也总想着自己还没准备好,但是总得跨出第一步,所以就先找了一些小厂练手。 + +不过牛客上投的小厂基本都没有音讯,真正想投递还是官网最靠谱。 + +诺瓦是我的第一份offer,所以尽管我大概率去不了,我依然心怀感激,**因为经历过的人都知道第一份offer对于一个迷茫的秋招生来说是多么的宝贵**。 + +后面拿到字节和滴滴我着实没有想到,因为感觉自己的表现还有待提升,但能过肯定是开心的。 + +**提前批没有笔试,所以七月份的提前批窗口确实非常宝贵**。 + +## 正式秋招 + +八月份之后就比较正常了,基本就是笔试,面试等等,**可以分享的一点是腾讯、阿里这种大厂不是特别看重笔试**,因为很多人在笔试之前就走完面试流程了,但是对于有一些劣势的同学还是希望能认真对待笔试,争取让自己多一个闪光点。 + +后期的算法题主要都集中在高频题、热题上面,所以还是应该把剑指刷好,配合别人分享的面经来巩固,**卡哥的算法pdf可以多看多复习**,就算没有考到也会让自己安心一些。 + +同时对于基础知识的整理更多的应该从面经中获取,我个人秋招下来总共看了得有至少500份面经,其实别人的面经和自己面试没啥区别。 + +同时也因为看了太多的面经,我自己的面经就不需要太多的整理了,除了一些没答上来的关键问题,因为基本都被之前的涵盖了,所以与其海投参加一些不靠谱的面试,倒不如整理十份面经来得实在。 + +参加面试主要是锻炼临场的心态,但是大厂和小厂的面试确实是有区别的,所以大厂的面经一定要多看多整理。 + + +## 感想 + +一口气写下来就已经2000字了,最后还是多说两句,分享一点感想吧。 + +**除了超级大佬,基本每一个秋招生都会有过迷茫,焦虑的心路历程**。 + +一方面我们需要认识到自己的局限性,认清现实。 + +另一方面也应该看到自己能改变的现实,许多人的时间真的只是在盲目的焦虑中虚耗,这是一个死循环,浪费的时间越多后面只会越焦虑,唯一的方法就是打起精神行动起来。当然也不用把自己逼的太紧,找到合适的排解方式,比如打会儿球打会儿游戏,让自己运行在一个正确的,符合自己节奏的轨道上不断前进。 + +**面试是玄学,有些人的就是难,有些人的就是简单**,没有人能保证你每次都简单,但也不会每次都难,我们努力提升实力只是为了能创造更多机会,并在机会出现的时候把握住。 + +我觉得一个人最大的幸运就是付出的努力能有收获,所以我希望大家都能幸运地结束秋招,也希望我能继续不忘初心,保持谦逊。秋招只是人生的一段小插曲,未来的路还有很长很长,写下这篇流水账结束我的秋招,也希望能与诸君共勉,加油! + +