├── .gitignore ├── .gitmodules ├── Algorithms ├── Backtrace │ └── main.cpp ├── Binary-Search │ └── main.cpp ├── Boyer-Moore │ └── bm.py └── Quick-Sort │ └── head-tail-pointer.cpp ├── Data Structures ├── FST │ └── c++ │ │ ├── CMakeLists.txt │ │ ├── README.md │ │ ├── fst.h │ │ ├── main.cpp │ │ └── test.cpp ├── Fenwick Tree │ └── c++ │ │ └── BIT.cpp ├── Huffman Tree │ └── huffman.cpp └── Segment Tree │ └── go │ └── SegmentTree │ ├── st.go │ └── st_test.go ├── Interview └── Fundamental │ ├── README.md │ ├── homework │ ├── 2022 │ │ └── 05 │ │ │ ├── 5 │ │ │ └── .gitignore │ │ │ ├── 6 │ │ │ └── .gitignore │ │ │ ├── 7 │ │ │ └── .gitignore │ │ │ ├── 8 │ │ │ └── .gitignore │ │ │ ├── 9 │ │ │ └── .gitignore │ │ │ ├── 10 │ │ │ └── .gitignore │ │ │ ├── 11 │ │ │ └── .gitignore │ │ │ ├── 12 │ │ │ └── .gitignore │ │ │ ├── 13 │ │ │ └── .gitignore │ │ │ ├── 14 │ │ │ └── .gitignore │ │ │ ├── 15 │ │ │ └── .gitignore │ │ │ ├── 16 │ │ │ └── .gitignore │ │ │ ├── 17 │ │ │ └── .gitignore │ │ │ ├── 18 │ │ │ └── .gitignore │ │ │ ├── 19 │ │ │ └── .gitignore │ │ │ ├── 20 │ │ │ └── .gitignore │ │ │ ├── 21 │ │ │ └── .gitignore │ │ │ ├── 22 │ │ │ └── .gitignore │ │ │ ├── 23 │ │ │ └── .gitignore │ │ │ ├── 24 │ │ │ └── .gitignore │ │ │ ├── 25 │ │ │ └── .gitignore │ │ │ ├── 26 │ │ │ └── .gitignore │ │ │ ├── 27 │ │ │ └── .gitignore │ │ │ ├── 28 │ │ │ └── .gitignore │ │ │ ├── 29 │ │ │ └── .gitignore │ │ │ └── 30 │ │ │ └── .gitignore │ └── create.sh │ └── questions │ ├── DistributedSystem │ └── 分布式系统架构.md │ ├── c++ │ └── C++常考问题汇总.md │ ├── c │ └── C语言常考问题汇总.md │ └── network │ ├── .gitignore │ ├── 2022-05-07-19-15-46.png │ └── TCP常考问题汇总.md ├── LICENSE ├── README.md ├── Source Code Reading └── STL │ └── Vector │ └── experiment.cpp ├── System ├── LRU │ ├── lru.go │ └── lru_test.go └── RateLimit │ ├── .gitignore │ ├── ratelimit.go │ └── ratelimit_test.go ├── Talks ├── 聚集算子.key └── 通关BAT的算法学习之旅.pdf ├── column.png ├── papers └── diff2.pdf └── perturbation.png /.gitignore: -------------------------------------------------------------------------------- 1 | .vscode 2 | .DS_Store 3 | test 4 | build -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "Leetcode"] 2 | path = Leetcode 3 | url = https://github.com/wfnuser/leetcode 4 | branch = master 5 | -------------------------------------------------------------------------------- /Algorithms/Backtrace/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | 5 | 6 | // 回溯法是递归思想的经典应用。本模板以力扣经典问题全排列为例讨论。 7 | // https://leetcode.cn/problems/permutations/description/ 8 | 9 | // 回溯中需要设置状态 表达当前局面在搜索空间中的位置,比如下棋时当前的棋盘状态(历史以来的每一步棋所累积的状态) 10 | // 本例中为搜索到第n个数时,前n个数的排列;为了加快搜索速度,用used数组标记每个数字是否已经被使用过 11 | bool backtrace(vector >& res, vector& path, vector& used, vector& selections) { 12 | // 判断是否满足退出条件 13 | if (path.size() == selections.size()) { 14 | // 退出后处理逻辑 15 | // 此例中具体行为为积累可行方案至结果数组;注意,path本身 16 | res.push_back(vector(path)); 17 | } 18 | 19 | // 尝试所有可能的方案 20 | for (int i = 0; i < selections.size(); i++) { 21 | // 如果数字没有被选中过,可以尝试加入排列 22 | if (!used[selections[i]]) { 23 | // 尝试当前方案,设置状态 24 | path.push_back(selections[i]); 25 | used[selections[i]] = 1; 26 | // 递归 27 | backtrace(res, path, used, selections); 28 | // 恢复现场 29 | // 不采用当前方案,则需要把对应的状态清理;好比下棋的时候不能连下两步 30 | used[selections[i]] = 0; 31 | path.pop_back(); 32 | } 33 | } 34 | } 35 | 36 | int main() { 37 | vector > res; 38 | vector path; 39 | 40 | vector selections = {1,2,3}; 41 | vector used(selections.size(), 0); 42 | 43 | backtrace(res, path, used, selections); 44 | 45 | for (auto sol: res) { 46 | cout << "{"; 47 | cout << sol[0]; 48 | for (int i = 1; i < sol.size(); i++) { 49 | cout << ", " << sol[i]; 50 | } 51 | cout << "}" << endl; 52 | } 53 | } 54 | 55 | 56 | -------------------------------------------------------------------------------- /Algorithms/Binary-Search/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | 5 | bool judge(int guess, int target) { 6 | return guess <= target; 7 | } 8 | 9 | bool judge2(int guess, int target) { 10 | return guess < target; 11 | } 12 | 13 | int binary_search_ml(vector& nums, int target) { 14 | int l = 0; 15 | int r = nums.size() - 1; 16 | 17 | while (l < r) { 18 | int mid = (l + r + 1) / 2; 19 | if (judge(nums[mid], target)) { 20 | l = mid; 21 | } else { 22 | r = mid - 1; 23 | } 24 | } 25 | 26 | return l; 27 | } 28 | 29 | int binary_search_nb(vector& nums, int target) { 30 | int l = 0; 31 | int r = nums.size() - 1; 32 | 33 | while (l < r) { 34 | int mid = (l + r) / 2; 35 | if (judge2(nums[mid], target)) { 36 | l = mid + 1; 37 | } else { 38 | r = mid; 39 | } 40 | } 41 | 42 | return l; 43 | } 44 | 45 | int binary_search(vector& nums, int target) { 46 | int l = 0; 47 | int r = nums.size() - 1; 48 | 49 | while (l < r) { 50 | int mid = (l + r) / 2; 51 | if (nums[mid] == target) return mid; 52 | if (nums[mid] > target) { 53 | r = mid - 1; 54 | } else { 55 | l = mid + 1; 56 | } 57 | } 58 | 59 | if (nums[l] == target) return l; 60 | 61 | return -1; 62 | }; 63 | 64 | int main() { 65 | int tmp[] = {1, 2, 3, 3, 3, 4, 5, 6}; 66 | vector nums(tmp, tmp + 8); 67 | cout << binary_search(nums, 3) << endl; // any target 68 | cout << binary_search_ml(nums, 3) << endl; // last target 69 | cout << binary_search_nb(nums, 3) << endl; // first target 70 | return 0; 71 | } 72 | 73 | 74 | -------------------------------------------------------------------------------- /Algorithms/Boyer-Moore/bm.py: -------------------------------------------------------------------------------- 1 | # -*- coding: UTF-8 -*- 2 | def get_bc(pattern): 3 | bc = dict() # 记录每个badchar最右出现的位置 4 | for i in range(len(pattern) - 1): 5 | char = pattern[i] 6 | bc[char] = i + 1 7 | return bc 8 | 9 | 10 | def get_gs(pattern): 11 | gs = dict() 12 | gs[''] = len(pattern) 13 | 14 | # suf_len 用于标记后缀长度 15 | for suf_len in range(len(pattern)): 16 | suffix = pattern[len(pattern) - suf_len - 1:] 17 | # j 用于标记可用于匹配的位置 18 | for j in range(len(pattern) - suf_len - 1): 19 | substr = pattern[j:j + suf_len + 1] 20 | if suffix == substr: 21 | gs[suffix] = len(pattern) - j - suf_len - 1 22 | 23 | for suf_len in range(len(pattern)): 24 | suffix = pattern[len(pattern) - suf_len - 1:] 25 | if suffix in gs: continue 26 | gs[suffix] = gs[suffix[1:]] 27 | 28 | gs[''] = 0 29 | return gs 30 | 31 | 32 | def bm(string, pattern, bc, gs): 33 | # i 用于标记当前模式串和主串哪个位置左对齐。 34 | i = 0 35 | # j 用于标记当前模式串匹配到哪个位置;从右往左遍历匹配。 36 | j = len(pattern) 37 | 38 | while i < len(string) - len(pattern) and (j > 0): 39 | a = string[i + j - 1] 40 | b = pattern[j - 1] 41 | if a == b: 42 | j = j - 1 43 | else: 44 | i = i + max(gs.setdefault(pattern[j:], len(pattern)), j - bc.setdefault(a, 0)) 45 | j = len(pattern) 46 | # 匹配成功返回匹配位置 47 | if j == 0: 48 | return i 49 | # 匹配失败返回 None 50 | return -1 51 | 52 | 53 | if __name__ == '__main__': 54 | string = 'here is a simple example ' 55 | pattern = 'example' 56 | 57 | bc = get_bc(pattern) # 坏字符表 58 | gs = get_gs(pattern) # 好后缀表 59 | 60 | print(gs) 61 | 62 | x = bm(string, pattern, bc, gs) 63 | 64 | print(x) -------------------------------------------------------------------------------- /Algorithms/Quick-Sort/head-tail-pointer.cpp: -------------------------------------------------------------------------------- 1 | int q[N]; 2 | 3 | void quick_sort(int q[], int b, int e) { 4 | if (b >= e) return; 5 | 6 | int p = q[(b+e)/2]; 7 | 8 | int i = b - 1, j = e + 1; 9 | 10 | /* 11 | * In case we use 'j' as the split point, the pivot must not be the index 12 | * 'e'. 13 | * 14 | * If there's a chance the pivot becomes 'q[e]', then there's a possibility 15 | * that after the loop, 'j' will be set to 'e'. 16 | * In such a case, we might end up in an infinite recursive call of 17 | * quick_sort(b, j). 18 | */ 19 | 20 | while (i < j) { 21 | do i++; while (q[i] < p); 22 | do j--; while (q[j] > p); 23 | if (i < j) swap(q[i], q[j]); 24 | } 25 | 26 | quick_sort(q, b, j); 27 | quick_sort(q, j + 1, e); 28 | 29 | return; 30 | } -------------------------------------------------------------------------------- /Data Structures/FST/c++/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required (VERSION 2.8) 2 | project(code-for-blog) 3 | set(CMAKE_CXX_STANDARD 11) 4 | set(CMAKE_CXX_STANDARD_REQUIRED ON) # not necessary, but encouraged 5 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -std=c++11 -Wall") 6 | find_package(GTest REQUIRED) 7 | find_package(Threads REQUIRED) 8 | include_directories(${GTEST_INCLUDE_DIRS}) 9 | add_executable(MyTests test.cpp) 10 | target_link_libraries(MyTests ${GTEST_BOTH_LIBRARIES}) 11 | target_link_libraries(MyTests ${CMAKE_THREAD_LIBS_INIT}) 12 | add_test(Test MyTests) 13 | enable_testing() -------------------------------------------------------------------------------- /Data Structures/FST/c++/README.md: -------------------------------------------------------------------------------- 1 | # Implementation of Finite State Transducer 2 | ![image](https://user-images.githubusercontent.com/8191686/159220068-a1e07aa4-5db1-4eb3-8031-792d47c345ac.png) 3 | 4 | ## How to run 5 | ```shell 6 | g++ main.cpp -o test 7 | ./test 8 | ``` 9 | 10 | # Reference 11 | https://blog.burntsushi.net/transducers/#fst-construction 12 | -------------------------------------------------------------------------------- /Data Structures/FST/c++/fst.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | #define INT_MIN -2147483648 8 | 9 | class State { 10 | public: 11 | // tag is one character in some keys 12 | char tag; 13 | // each state should bind with weight 14 | int weight; 15 | 16 | // each state contains pointers to next state 17 | // each arc should bind with weight 18 | unordered_map > nextStates; 19 | // pointers back to prev state | tagged by char 20 | unordered_map > prevStates; 21 | 22 | State(char tag, int weight) : tag(tag), weight(weight) { 23 | nextStates = unordered_map >(); 24 | } 25 | }; 26 | 27 | class StateMachine { 28 | public: 29 | State* source; 30 | State* sink; 31 | 32 | // source state as every keys begin 33 | // sink state as every keys end 34 | StateMachine() { 35 | source = new State(' ', 0); 36 | sink = new State(' ', 0); 37 | } 38 | 39 | /** 40 | * Add function is for insert key-value. 41 | * s is the key and w is the value. 42 | * Weight should be spread over every state and arc along the path. 43 | * The add will be separated into two steps. 44 | * First, we will traverse or create each states for `s` by traverse each character from front to back. 45 | * Then we will try to combine some states together to save memory. 46 | * We will do this by traversing the path from back to front. To see if each state is exactly the same with another. 47 | * If it is, we will combine these two states and release the space. 48 | * TODO: should bind weight in the edges 49 | */ 50 | void add(string s, int w) { 51 | State* cur = source; 52 | vector curStates; 53 | curStates.push_back(cur); 54 | 55 | // create linked list of states for each character of added key. 56 | for (auto c: s) { 57 | if (cur->nextStates.find(c) != cur->nextStates.end()) { 58 | (cur->nextStates)[c].first->prevStates[cur->tag].push_back(cur); 59 | w -= (cur->nextStates)[c].second; 60 | cur = (cur->nextStates)[c].first; 61 | w -= cur->weight; 62 | } else { 63 | State* s = new State(c, w); 64 | cur->nextStates[c] = make_pair(s, 0); 65 | (cur->nextStates)[c].first->prevStates[cur->tag].push_back(cur); 66 | w -= (cur->nextStates)[c].second; 67 | cur = (cur->nextStates)[c].first; 68 | w -= cur->weight; 69 | } 70 | curStates.push_back(cur); 71 | } 72 | cur->nextStates[' '] = make_pair(sink, 0); 73 | if (cur != source) sink->prevStates[cur->tag].push_back(cur); 74 | 75 | State* p = sink; 76 | // compare suffix and try to combine redundant states 77 | for (int i = curStates.size() - 1; i >= 0; i--) { 78 | bool combined = false; 79 | for (auto s: p->prevStates[curStates[i]->tag]) { 80 | if (s == curStates[i]) continue; 81 | if (s->nextStates.size() != curStates[i]->nextStates.size()) continue; 82 | 83 | bool flag = true; 84 | 85 | // We can combine two states if they are duplicated. 86 | // Which means all of both states' next states are strictly equal. 87 | for (auto p: s->nextStates) { 88 | if (curStates[i]->nextStates[p.first] != s->nextStates[p.first]) { 89 | flag = false; 90 | break; 91 | } 92 | } 93 | 94 | // Ff there is common suffix; we should combine the vertex. It works just like zipper. 95 | /** 96 | * From: 97 | * y -> o -> x -> SINK 98 | * z -> o -> x -> SINK 99 | * 100 | * To: 101 | * y -> o -> x -> SINK 102 | * / 103 | * z 104 | */ 105 | // TODO: should deal with the memory leak problem here. 106 | if (flag) { 107 | curStates[i-1]->nextStates[s->tag] = make_pair(s, curStates[i]->weight - s->weight); 108 | s->prevStates[curStates[i-1]->tag].push_back(curStates[i-1]); 109 | auto tmp = p->prevStates[s->tag].back(); 110 | p->prevStates[s->tag].pop_back(); 111 | delete(tmp); 112 | p = s; 113 | combined = true; 114 | break; 115 | } 116 | } 117 | if (!combined) break; 118 | } 119 | } 120 | 121 | /** 122 | * Get value of key. 123 | * Compare to `add`, `get` is much more easy to implement. 124 | * We can just traverse key's characters, and see if there is a state corresponding to it. 125 | * If not, the key is not in FST. 126 | * If the last state we traversed has a pointer to sink. 127 | * We should sum all the state weights and arc weights and return. 128 | */ 129 | int get(string key) { 130 | State* p = source; 131 | int w = 0; 132 | for (auto c: key) { 133 | if (p->nextStates.find(c) == p->nextStates.end()) return INT_MIN; 134 | w += p->nextStates[c].second; 135 | p = p->nextStates[c].first; 136 | w += p->weight; 137 | } 138 | if (p->nextStates.find(' ') == p->nextStates.end()) return INT_MIN; 139 | 140 | return w; 141 | } 142 | 143 | void print(State* begin, vector& path) { 144 | if (begin == sink) { 145 | for (auto s: path) { 146 | cout << s->tag << "(" << s << ") -> "; 147 | } 148 | cout << endl; 149 | return; 150 | } 151 | for (auto s: begin->nextStates) { 152 | path.push_back(s.second.first); 153 | print(s.second.first, path); 154 | path.pop_back(); 155 | } 156 | } 157 | }; 158 | -------------------------------------------------------------------------------- /Data Structures/FST/c++/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include "fst.h" 7 | 8 | using namespace std; 9 | 10 | int main() { 11 | auto SM = StateMachine(); 12 | 13 | SM.add("mox", 10); 14 | SM.add("moxr", 5); 15 | SM.add("yox", 2); 16 | SM.add("yoxr", 8); 17 | SM.add("zox", 6); 18 | SM.add("uox", 1); 19 | vector v = vector(); 20 | SM.print(SM.source, v); 21 | 22 | cout << SM.get("mox") << endl; 23 | cout << SM.get("moxr") << endl; 24 | cout << SM.get("yox") << endl; 25 | cout << SM.get("yoxr") << endl; 26 | 27 | return 0; 28 | } -------------------------------------------------------------------------------- /Data Structures/FST/c++/test.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "fst.h" 8 | 9 | #define GTEST_COUT std::cerr << "[ ] [ INFO ]" 10 | 11 | TEST(MyTest, Sum) 12 | { 13 | auto SM = StateMachine(); 14 | SM.add("mox", 10); 15 | SM.add("moxr", 5); 16 | SM.add("yox", 2); 17 | SM.add("yoxr", 8); 18 | SM.add("zox", 6); 19 | SM.add("uox", 1); 20 | 21 | // should return correct value 22 | EXPECT_EQ(SM.get("mox"), 10); 23 | EXPECT_EQ(SM.get("moxr"), 5); 24 | EXPECT_EQ(SM.get("yox"), 2); 25 | EXPECT_EQ(SM.get("yoxr"), 8); 26 | EXPECT_EQ(SM.get("zox"), 6); 27 | EXPECT_EQ(SM.get("uox"), 1); 28 | 29 | // key not exists 30 | // should return INT_MIN 31 | GTEST_COUT << SM.get("ox") << std::endl; 32 | EXPECT_EQ(SM.get("ox"), INT_MIN); 33 | EXPECT_EQ(SM.get("zo"), INT_MIN); 34 | EXPECT_EQ(SM.get(""), INT_MIN); 35 | 36 | } 37 | 38 | int main(int argc, char *argv[]) 39 | { 40 | ::testing::InitGoogleTest(&argc, argv); 41 | return RUN_ALL_TESTS(); 42 | } -------------------------------------------------------------------------------- /Data Structures/Fenwick Tree/c++/BIT.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | class BIT { 6 | int n; 7 | vector tr; 8 | 9 | public: 10 | BIT(int n) { 11 | this->n = n; 12 | tr = vector(n+1, 0); 13 | } 14 | 15 | int lowbit(int x) { 16 | return x & -x; 17 | } 18 | 19 | void add(int x, int v) { 20 | for (int i = x; i <= n; i += lowbit(i)) { 21 | tr[i] += v; 22 | } 23 | } 24 | 25 | int query(int x) { 26 | int res = 0; 27 | for (int i = x; i != 0; i -= lowbit(i)) { 28 | res += tr[i]; 29 | } 30 | return res; 31 | } 32 | }; -------------------------------------------------------------------------------- /Data Structures/Huffman Tree/huffman.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | using namespace std; 6 | 7 | struct Node 8 | { 9 | char ch; 10 | int freq; 11 | Node *left, *right; 12 | }; 13 | 14 | Node* getNode(char ch, int freq, Node* left, Node* right) 15 | { 16 | Node* node = new Node(); 17 | 18 | node->ch = ch; 19 | node->freq = freq; 20 | node->left = left; 21 | node->right = right; 22 | 23 | return node; 24 | } 25 | 26 | struct comp 27 | { 28 | bool operator()(Node* l, Node* r) 29 | { 30 | return l->freq > r->freq; 31 | } 32 | }; 33 | 34 | void encode(Node* root, string str, 35 | unordered_map &huffmanCode) 36 | { 37 | if (root == nullptr) 38 | return; 39 | 40 | if (!root->left && !root->right) { 41 | huffmanCode[root->ch] = str; 42 | } 43 | 44 | encode(root->left, str + "0", huffmanCode); 45 | encode(root->right, str + "1", huffmanCode); 46 | } 47 | 48 | void decode(Node* root, int &index, string str) 49 | { 50 | if (root == nullptr) { 51 | return; 52 | } 53 | 54 | if (!root->left && !root->right) 55 | { 56 | cout << root->ch; 57 | return; 58 | } 59 | 60 | index++; 61 | 62 | if (str[index] =='0') 63 | decode(root->left, index, str); 64 | else 65 | decode(root->right, index, str); 66 | } 67 | 68 | void buildHuffmanTree(string text) 69 | { 70 | unordered_map freq; 71 | for (char ch: text) { 72 | freq[ch]++; 73 | } 74 | 75 | priority_queue, comp> pq; 76 | 77 | for (auto pair: freq) { 78 | pq.push(getNode(pair.first, pair.second, nullptr, nullptr)); 79 | } 80 | 81 | while (pq.size() != 1) 82 | { 83 | Node *left = pq.top(); pq.pop(); 84 | Node *right = pq.top(); pq.pop(); 85 | 86 | int sum = left->freq + right->freq; 87 | pq.push(getNode('\0', sum, left, right)); 88 | } 89 | 90 | Node* root = pq.top(); 91 | 92 | unordered_map huffmanCode; 93 | encode(root, "", huffmanCode); 94 | 95 | cout << "\nOriginal string :\n" << text << '\n'; 96 | 97 | string str = ""; 98 | for (char ch: text) { 99 | str += huffmanCode[ch]; 100 | } 101 | 102 | cout << "\nEncoded string :\n" << str << '\n'; 103 | 104 | int index = -1; 105 | cout << "\nDecoded string is: \n"; 106 | while (index < (int)str.size() - 2) { 107 | decode(root, index, str); 108 | } 109 | } 110 | 111 | int main() 112 | { 113 | string text = "Huffman coding is a data compression algorithm."; 114 | 115 | buildHuffmanTree(text); 116 | 117 | return 0; 118 | } -------------------------------------------------------------------------------- /Data Structures/Segment Tree/go/SegmentTree/st.go: -------------------------------------------------------------------------------- 1 | package st 2 | 3 | import ( 4 | "errors" 5 | "fmt" 6 | ) 7 | 8 | type SegmentTree struct { 9 | tree []int //线段树 10 | a []int //数组数据 11 | } 12 | 13 | func leftChild(i int) int { 14 | return 2*i + 1 15 | } 16 | 17 | // 传入一个数组arrs和一个功能函数func,根据功能函数返回一个线段树 18 | func NewSegmentTree(arrs []int) *SegmentTree { 19 | length := len(arrs) 20 | tree := &SegmentTree{ 21 | tree: make([]int, length*4), 22 | a: arrs, 23 | } 24 | tree.build(0, 0, length-1) 25 | return tree 26 | } 27 | 28 | // 在tree的index位置创建 arrs [ l 到 r ] 的线段树 29 | func (tree *SegmentTree) build(index, l, r int) int { 30 | // 递归终止条件 31 | if l == r { 32 | tree.tree[index] = tree.a[l] 33 | return tree.a[l] 34 | } 35 | // 递归过程 36 | leftI := leftChild(index) 37 | rightI := leftI + 1 38 | mid := l + (r-l)/2 39 | leftResp := tree.build(leftI, l, mid) 40 | rightResp := tree.build(rightI, mid+1, r) 41 | tree.tree[index] = leftResp + rightResp 42 | return tree.tree[index] 43 | } 44 | 45 | // 查询arrs范围queryL到queryR 的结果 46 | func (tree *SegmentTree) Query(queryL, queryR int) (int, error) { 47 | length := len(tree.a) 48 | if queryL < 0 || queryL > queryR || queryR >= length { 49 | return 0, errors.New("index is illegal") 50 | } 51 | return tree.queryrange(0, 0, length-1, queryL, queryR), nil 52 | } 53 | 54 | // 在以index为根的线段树中[l...r]范围里,搜索区间[queryL...queryR]的值 55 | func (tree *SegmentTree) queryrange(index, l, r, queryL, queryR int) int { 56 | if l == queryL && r == queryR { 57 | return tree.tree[index] 58 | } 59 | leftI := leftChild(index) 60 | rightI := leftI + 1 61 | mid := l + (r-l)/2 62 | if queryL > mid { 63 | return tree.queryrange(rightI, mid+1, r, queryL, queryR) 64 | } 65 | if queryR <= mid { 66 | return tree.queryrange(leftI, l, mid, queryL, queryR) 67 | } 68 | leftResp := tree.queryrange(leftI, l, mid, queryL, mid) 69 | rightResp := tree.queryrange(rightI, mid+1, r, mid+1, queryR) 70 | return leftResp + rightResp 71 | } 72 | 73 | // 更新a中索引k的值为v 74 | func (tree *SegmentTree) Change(k, v int) { 75 | length := len(tree.a) 76 | if k < 0 || k >= length { 77 | return 78 | } 79 | tree.set(0, 0, length-1, k, v) 80 | } 81 | 82 | // 在以treeIndex为根的线段树中更新index的值为e 83 | func (tree *SegmentTree) set(treeIndex, l, r, k, v int) { 84 | if l == r { 85 | tree.tree[treeIndex] = v 86 | return 87 | } 88 | leftI := leftChild(treeIndex) 89 | rightI := leftI + 1 90 | midI := l + (r-l)/2 91 | if k > midI { 92 | tree.set(rightI, midI+1, r, k, v) 93 | } else { 94 | tree.set(leftI, l, midI, k, v) 95 | } 96 | tree.tree[treeIndex] = tree.tree[leftI] + tree.tree[rightI] 97 | } 98 | 99 | func (tree *SegmentTree) Print() { 100 | fmt.Println(tree.tree) 101 | } 102 | -------------------------------------------------------------------------------- /Data Structures/Segment Tree/go/SegmentTree/st_test.go: -------------------------------------------------------------------------------- 1 | package st 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestSegmentTree(t *testing.T) { 8 | tree := NewSegmentTree([]int{11, 12, 13, 14, 15}) 9 | tree.Print() 10 | } 11 | -------------------------------------------------------------------------------- /Interview/Fundamental/README.md: -------------------------------------------------------------------------------- 1 | # 每日一题 2 | ## 规则 3 | - 佛系打卡 4 | - 群友可将作业文件命名为自己的 github ID,并用 Git 上传至 [homework](https://github.com/wfnuser/Algorithms/tree/main/Interview/Fundamental/homework) 指定日期目录 5 | - 参考答案由 [「**微扰理论**」](https://github.com/wfnuser) 整理至 [questions](https://github.com/wfnuser/Algorithms/tree/main/Interview/Fundamental/questions) 目录 6 | 7 | 感兴趣的小伙伴可以加群一起讨论哦~ 8 | 对数据库内核开发感兴趣的同学也可以投递简历至 huangqinghao@hashdata.cn 9 | ![](https://github.com/wfnuser/wfnuser/raw/main/banner.png) 10 | 11 | 12 | ## 2022/05/28 13 | - TCP中的TIME_WAIT状态是什么 14 | ## 2022/05/27 15 | - 什么是存算分离架构[参考答案](/Interview/Fundamental/questions/DistributedSystem/分布式系统架构.md#什么是存算分离架构) 16 | ## 2022/05/14 17 | - TCP断开连接为什么需要四次挥手[参考答案](/Interview/Fundamental/questions/network/TCP常考问题汇总.md#TCP断开连接为什么需要四次挥手) 18 | ## 2022/05/12 19 | - TCP是如何做拥塞控制的 [参考答案](/Interview/Fundamental/questions/network/TCP常考问题汇总.md#TCP是如何做拥塞控制的) 20 | ## 2022/05/11 21 | - TCP协议中的滑动窗口是指什么[参考答案](/Interview/Fundamental/questions/network/TCP常考问题汇总.md#TCP协议中的滑动窗口是指什么) 22 | ## 2022/05/10 23 | - C++的内存序是指什么[TODO: 延后更新] 24 | ## 2022/05/09 25 | - C语言如何对字符串判空[参考答案](/Interview/Fundamental/questions/c/C语言常考问题汇总.md#C语言如何对字符串判空) 26 | ## 2022/05/08 27 | - 在C++中什么是右值引用[参考答案](/Interview/Fundamental/questions/c++/C++常考问题汇总.md#在C++中什么是右值引用) 28 | ## 2022/05/07 29 | - 什么是TCP粘包现象[参考答案](/Interview/Fundamental/questions/network/TCP常考问题汇总.md#什么是TCP粘包现象) 30 | ## 2022/05/06 31 | - 在TCP中什么是半连接队列[参考答案](/Interview/Fundamental/questions/network/TCP常考问题汇总.md#在TCP中什么是半连接队列) 32 | ## 2022/05/05 33 | - TCP连接为什么要进行三次握手[参考答案](/Interview/Fundamental/questions/network/TCP常考问题汇总.md#TCP连接为什么要进行三次握手) 34 | -------------------------------------------------------------------------------- /Interview/Fundamental/homework/2022/05/10/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wfnuser/Algorithms/8bb7db73d3413b7c49e09965b8dcd7ee9074b4c1/Interview/Fundamental/homework/2022/05/10/.gitignore -------------------------------------------------------------------------------- /Interview/Fundamental/homework/2022/05/11/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wfnuser/Algorithms/8bb7db73d3413b7c49e09965b8dcd7ee9074b4c1/Interview/Fundamental/homework/2022/05/11/.gitignore -------------------------------------------------------------------------------- /Interview/Fundamental/homework/2022/05/12/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wfnuser/Algorithms/8bb7db73d3413b7c49e09965b8dcd7ee9074b4c1/Interview/Fundamental/homework/2022/05/12/.gitignore -------------------------------------------------------------------------------- /Interview/Fundamental/homework/2022/05/13/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wfnuser/Algorithms/8bb7db73d3413b7c49e09965b8dcd7ee9074b4c1/Interview/Fundamental/homework/2022/05/13/.gitignore -------------------------------------------------------------------------------- /Interview/Fundamental/homework/2022/05/14/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wfnuser/Algorithms/8bb7db73d3413b7c49e09965b8dcd7ee9074b4c1/Interview/Fundamental/homework/2022/05/14/.gitignore -------------------------------------------------------------------------------- /Interview/Fundamental/homework/2022/05/15/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wfnuser/Algorithms/8bb7db73d3413b7c49e09965b8dcd7ee9074b4c1/Interview/Fundamental/homework/2022/05/15/.gitignore -------------------------------------------------------------------------------- /Interview/Fundamental/homework/2022/05/16/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wfnuser/Algorithms/8bb7db73d3413b7c49e09965b8dcd7ee9074b4c1/Interview/Fundamental/homework/2022/05/16/.gitignore -------------------------------------------------------------------------------- /Interview/Fundamental/homework/2022/05/17/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wfnuser/Algorithms/8bb7db73d3413b7c49e09965b8dcd7ee9074b4c1/Interview/Fundamental/homework/2022/05/17/.gitignore -------------------------------------------------------------------------------- /Interview/Fundamental/homework/2022/05/18/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wfnuser/Algorithms/8bb7db73d3413b7c49e09965b8dcd7ee9074b4c1/Interview/Fundamental/homework/2022/05/18/.gitignore -------------------------------------------------------------------------------- /Interview/Fundamental/homework/2022/05/19/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wfnuser/Algorithms/8bb7db73d3413b7c49e09965b8dcd7ee9074b4c1/Interview/Fundamental/homework/2022/05/19/.gitignore -------------------------------------------------------------------------------- /Interview/Fundamental/homework/2022/05/20/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wfnuser/Algorithms/8bb7db73d3413b7c49e09965b8dcd7ee9074b4c1/Interview/Fundamental/homework/2022/05/20/.gitignore -------------------------------------------------------------------------------- /Interview/Fundamental/homework/2022/05/21/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wfnuser/Algorithms/8bb7db73d3413b7c49e09965b8dcd7ee9074b4c1/Interview/Fundamental/homework/2022/05/21/.gitignore -------------------------------------------------------------------------------- /Interview/Fundamental/homework/2022/05/22/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wfnuser/Algorithms/8bb7db73d3413b7c49e09965b8dcd7ee9074b4c1/Interview/Fundamental/homework/2022/05/22/.gitignore -------------------------------------------------------------------------------- /Interview/Fundamental/homework/2022/05/23/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wfnuser/Algorithms/8bb7db73d3413b7c49e09965b8dcd7ee9074b4c1/Interview/Fundamental/homework/2022/05/23/.gitignore -------------------------------------------------------------------------------- /Interview/Fundamental/homework/2022/05/24/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wfnuser/Algorithms/8bb7db73d3413b7c49e09965b8dcd7ee9074b4c1/Interview/Fundamental/homework/2022/05/24/.gitignore -------------------------------------------------------------------------------- /Interview/Fundamental/homework/2022/05/25/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wfnuser/Algorithms/8bb7db73d3413b7c49e09965b8dcd7ee9074b4c1/Interview/Fundamental/homework/2022/05/25/.gitignore -------------------------------------------------------------------------------- /Interview/Fundamental/homework/2022/05/26/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wfnuser/Algorithms/8bb7db73d3413b7c49e09965b8dcd7ee9074b4c1/Interview/Fundamental/homework/2022/05/26/.gitignore -------------------------------------------------------------------------------- /Interview/Fundamental/homework/2022/05/27/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wfnuser/Algorithms/8bb7db73d3413b7c49e09965b8dcd7ee9074b4c1/Interview/Fundamental/homework/2022/05/27/.gitignore -------------------------------------------------------------------------------- /Interview/Fundamental/homework/2022/05/28/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wfnuser/Algorithms/8bb7db73d3413b7c49e09965b8dcd7ee9074b4c1/Interview/Fundamental/homework/2022/05/28/.gitignore -------------------------------------------------------------------------------- /Interview/Fundamental/homework/2022/05/29/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wfnuser/Algorithms/8bb7db73d3413b7c49e09965b8dcd7ee9074b4c1/Interview/Fundamental/homework/2022/05/29/.gitignore -------------------------------------------------------------------------------- /Interview/Fundamental/homework/2022/05/30/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wfnuser/Algorithms/8bb7db73d3413b7c49e09965b8dcd7ee9074b4c1/Interview/Fundamental/homework/2022/05/30/.gitignore -------------------------------------------------------------------------------- /Interview/Fundamental/homework/2022/05/5/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wfnuser/Algorithms/8bb7db73d3413b7c49e09965b8dcd7ee9074b4c1/Interview/Fundamental/homework/2022/05/5/.gitignore -------------------------------------------------------------------------------- /Interview/Fundamental/homework/2022/05/6/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wfnuser/Algorithms/8bb7db73d3413b7c49e09965b8dcd7ee9074b4c1/Interview/Fundamental/homework/2022/05/6/.gitignore -------------------------------------------------------------------------------- /Interview/Fundamental/homework/2022/05/7/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wfnuser/Algorithms/8bb7db73d3413b7c49e09965b8dcd7ee9074b4c1/Interview/Fundamental/homework/2022/05/7/.gitignore -------------------------------------------------------------------------------- /Interview/Fundamental/homework/2022/05/8/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wfnuser/Algorithms/8bb7db73d3413b7c49e09965b8dcd7ee9074b4c1/Interview/Fundamental/homework/2022/05/8/.gitignore -------------------------------------------------------------------------------- /Interview/Fundamental/homework/2022/05/9/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wfnuser/Algorithms/8bb7db73d3413b7c49e09965b8dcd7ee9074b4c1/Interview/Fundamental/homework/2022/05/9/.gitignore -------------------------------------------------------------------------------- /Interview/Fundamental/homework/create.sh: -------------------------------------------------------------------------------- 1 | for i in {01..30}; do echo "$i"; mkdir $i; touch $i/.gitignore; done 2 | -------------------------------------------------------------------------------- /Interview/Fundamental/questions/DistributedSystem/分布式系统架构.md: -------------------------------------------------------------------------------- 1 | # 分布式系统架构 2 | 3 | ### 什么是存算分离架构 4 | 存算分离是指存储计算分离的架构方式;通常应用于新兴的数据库、消息队列等系统中;在云原生时代得到广泛的认可。 5 | 6 | 事实上,存储和计算本身并不是完全独立的两个环节,在计算时往往需要依赖存储;在存算分离中,存储指数据的持久化,计算则通常需要通过网络先将需要计算的数据获取到计算节点,利用CPU和内存进行计算。 7 | 这样的隔离在带宽大幅提升之后,成为了可能。 8 | 9 | 好处在于,传统存储和计算节点放在一起的部署方式,不管遇到存储瓶颈还是计算瓶颈都需要对服务器进行扩容;这必不可少的带来了资源的浪费。 10 | 存算分离则很好的避免了这个问题,提供了计算存储独立扩容的能力;也更加可以利用云存储资源弹性扩容的便捷性。 -------------------------------------------------------------------------------- /Interview/Fundamental/questions/c++/C++常考问题汇总.md: -------------------------------------------------------------------------------- 1 | # C++常考问题汇总 2 | 3 | ### 在C++中什么是右值引用 4 | 参考链接: https://www.cnblogs.com/qicosmos/p/4283455.html 5 | 6 | 首先我们要明确左值和右值的区别。 7 | ``` 8 | int i = 0; 9 | int j = 5; 10 | auto f = []{return 5;}; 11 | ``` 12 | 通常来说,我们可以简单的认为`=`左边的值为左值;`=`右边的值为右值。两种值最大的区别在于生命周期;右值在表达式结束之后就会被销毁,左值则不会。另一个区别在于左值可以取地址;右值则不可。 13 | 14 | 常见的右值包括:字面量、lambda表达式、表达式产生的临时变量和非引用返回的临时变量。 15 | 16 | ``` 17 | int i = 0; 18 | int& j = i; 19 | int&& k = 0; 20 | ``` 21 | c++中采用两个`&`表示右值引用,一个`&`表示左值引用。 22 | 引入右值引用主要用于解决:1. 免去临时对象不必要的拷贝操作 2. 在模板中按照参数的实际类型转发。 23 | 由于微扰酱目前只理解了第一个目的,第二个目的之后再进行讨论。(TODO) 24 | 25 | ``` 26 | #include 27 | using namespace std; 28 | 29 | int g_constructCount=0; 30 | int g_copyConstructCount=0; 31 | int g_destructCount=0; 32 | struct A 33 | { 34 | A(){ 35 | cout<<"construct: "<<++g_constructCount<SYN 11 | <-ACK/SYN 12 | ->ACK 13 | ``` 14 | 15 | ### 在TCP中什么是半连接队列 16 | Linux内核针对TCP协议会维护两个队列分别是 syn队列 和 accept队列。 17 | 内核收到 syn 请求的时候就会将连接放入 syn队列 也就是半连接队列;当收到第三次握手的ACK时候,则会将连接从半连接队列中移除,放入 accept队列 等待系统调用 accept 将连接取出,并进行后续 read 等操作。 18 | ![](2022-05-07-19-15-46.png) 19 | 20 | ### 什么是TCP粘包现象 21 | TCP是基于字节流的传输层协议;应用层的消息可能会被拆分重组成一个数据段发给目标主机。 22 | 比如Nagle算法就是这样一种拆分重组从而减少数据包数量进而提高TCP传输效率的算法;它就会导致粘包现象的出现。应用层一次传输的数据若不多;则会暂存于系统缓冲区,等待下次请求的数据来临;如果两次的数据之和超过MSS的大小,则会将数据拆成MSS+剩余大小,分两次进行发送。则应用层分离的两个消息被放入了同一个segment;即粘包现象。 23 | 解决方案就是定义清楚消息的边界;通常可以采用确定长度或增加终结符两种方案进行解决。 24 | 25 | ### TCP协议中的滑动窗口是指什么 26 | 滑动窗口也被称为通告窗口是接收方发送给发送方用于限制传输速率的手段。发送方可以最多发送滑动窗口大小的未确认分组信息;超过则需要等待接收方的回复。 27 | 28 | ### TCP是如何做拥塞控制的 29 | 拥塞控制主要手段是引入拥塞窗口。当发送方发现网络出现拥塞时,TCP会通过控制拥塞窗口大小降低传输的最大分组数量,使得网络拥塞得以缓解。 30 | 具体包括四个拥塞控制方法:慢启动、拥塞避免、快重传、快恢复四种。 31 | 32 | ### TCP断开连接为什么需要四次挥手 33 | 和建立连接不同;断开连接的时候需要进行4次挥手。其主要原因在于TCP是双工网络协议;网络连接一旦建立,双方都可以向对方发送数据;主动关闭方想要断开连接的时候会发送FIN通知被动关闭方,被动关闭方应立刻回复ACK,但此时被动关闭方仍然可能有数据需要继续发送;被动关闭方会等数据发送完毕后再发送FIN给主动关闭方,主动方收到后回复ACK,并进入time_wait状态。 34 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Perturbation Theory 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Algorithms 2 | 本仓库旨在实现各种常用算法,欢迎大家来提issue或者pr。如果觉得有帮助的话;**也欢迎点个star**,这是对我最好的支持和鼓励。 3 | 4 | 5 | 可以配合极客时间专栏[《算法实战高手课》](https://time.geekbang.org/column/intro/100100901?code=I%252F1%252FovCrth0wXifam7LWC3eGnJy9VdcYcfWACA1NG%252Fk%253D&utm_term=SPoster&page=A) 一起学习。从推荐链接订阅的话可以找「微扰酱」返现哦~ 6 | 7 | ### 八股文·每日一题 8 | #### 规则 9 | - 佛系打卡 10 | - 群友可将作业文件命名为自己的 github ID,并用 Git 上传至 [homework](https://github.com/wfnuser/Algorithms/tree/main/Interview/Fundamental/homework) 指定日期目录 11 | - 参考答案由 [「**微扰理论**」](https://github.com/wfnuser) 整理至 [questions](https://github.com/wfnuser/Algorithms/tree/main/Interview/Fundamental/questions) 目录 12 | 13 | 感兴趣的小伙伴可以加群一起讨论哦~ 14 | 对数据库内核开发感兴趣的同学也可以投递简历至 huangqinghao@hashdata.cn 15 | 16 | 17 | 18 | ### 关于作者 19 | 你好,我是[「**微扰理论**」](https://leetcode-cn.com/u/wfnuser/)。目前正在连载国服每日一题题解;可以加「微扰酱」微信交个朋友。 20 | 21 | ![](https://github.com/wfnuser/wfnuser/raw/main/banner.png) 22 | -------------------------------------------------------------------------------- /Source Code Reading/STL/Vector/experiment.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | using namespace std; 7 | 8 | int main() { 9 | 10 | vector v; 11 | 12 | for (int i = 0; i < 20; i++) { 13 | cout << "size: " << v.size() << " capacity " << v.capacity() << endl; 14 | v.push_back(i); 15 | } 16 | 17 | return 0; 18 | } -------------------------------------------------------------------------------- /System/LRU/lru.go: -------------------------------------------------------------------------------- 1 | package lru 2 | 3 | import ( 4 | "container/list" 5 | "errors" 6 | ) 7 | 8 | type LRU struct { 9 | size int 10 | innerList *list.List 11 | innerMap map[int]*list.Element 12 | } 13 | 14 | type entry struct { 15 | key int 16 | value int 17 | } 18 | 19 | func NewLRU(size int) (*LRU, error) { 20 | if size <= 0 { 21 | return nil, errors.New("must provide a positive size") 22 | } 23 | c := &LRU{ 24 | size: size, 25 | innerList: list.New(), 26 | innerMap: make(map[int]*list.Element), 27 | } 28 | return c, nil 29 | } 30 | 31 | func (c *LRU) Get(key int) (int, bool) { 32 | if e, ok := c.innerMap[key]; ok { 33 | c.innerList.MoveToFront(e) 34 | return e.Value.(*entry).value, true 35 | } 36 | return -1, false 37 | } 38 | 39 | func (c *LRU) Put(key int, value int) (evicted bool) { 40 | if e, ok := c.innerMap[key]; ok { 41 | c.innerList.MoveToFront(e) 42 | e.Value.(*entry).value = value 43 | return false 44 | } else { 45 | e := &entry{key, value} 46 | ent := c.innerList.PushFront(e) 47 | c.innerMap[key] = ent 48 | 49 | if c.innerList.Len() > c.size { 50 | last := c.innerList.Back() 51 | c.innerList.Remove(last) 52 | delete(c.innerMap, last.Value.(*entry).key) 53 | return true 54 | } 55 | return false 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /System/LRU/lru_test.go: -------------------------------------------------------------------------------- 1 | package lru 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestPass(t *testing.T) { 8 | l, e := NewLRU(3) 9 | if e != nil { 10 | t.Errorf("new lru failed") 11 | } 12 | 13 | _, ok := l.Get(10) 14 | if ok { 15 | t.Errorf("should not get nonexistent value") 16 | } 17 | l.Put(10, 10) 18 | l.Put(10, 20) 19 | if l.innerList.Len() != 1 { 20 | t.Errorf("uncorrect size") 21 | } 22 | v, ok := l.Get(10) 23 | if v != 20 { 24 | t.Errorf("uncorrect value") 25 | } 26 | l.Put(11, 11) 27 | l.Put(12, 12) 28 | l.Put(13, 13) 29 | l.Put(11, 14) 30 | if l.innerList.Len() != 3 { 31 | t.Errorf("uncorrect size") 32 | } 33 | if l.innerList.Front().Value.(*entry).key != 11 { 34 | t.Errorf("uncorrect position") 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /System/RateLimit/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | -------------------------------------------------------------------------------- /System/RateLimit/ratelimit.go: -------------------------------------------------------------------------------- 1 | package ratelimit 2 | 3 | import ( 4 | "fmt" 5 | "sync" 6 | "time" 7 | ) 8 | 9 | type RateLimiter struct { 10 | rate int64 11 | max int64 12 | last int64 13 | amount int64 14 | lock sync.Mutex 15 | } 16 | 17 | // (now - last) * rate 18 | 19 | func cur() int64 { 20 | return time.Now().Unix() 21 | } 22 | 23 | func New(rate int64, max int64) *RateLimiter { 24 | // TODO: 检查一下rate和max是否合法 25 | return &RateLimiter{ 26 | rate: rate, 27 | max: max, 28 | last: cur(), 29 | amount: max, 30 | } 31 | } 32 | 33 | func (rl *RateLimiter) Pass() bool { 34 | rl.lock.Lock() 35 | defer rl.lock.Unlock() 36 | 37 | // 当前桶中 是否还有令牌 38 | passed := cur() - rl.last 39 | fmt.Println("passed is: ", passed) 40 | 41 | amount := rl.amount + passed*rl.rate 42 | 43 | if amount > rl.max { 44 | amount = rl.max 45 | } 46 | 47 | if amount <= 0 { 48 | return false 49 | } 50 | 51 | amount-- 52 | rl.amount = amount 53 | rl.last = cur() 54 | return true 55 | } 56 | -------------------------------------------------------------------------------- /System/RateLimit/ratelimit_test.go: -------------------------------------------------------------------------------- 1 | package ratelimit 2 | 3 | import ( 4 | "fmt" 5 | "testing" 6 | "time" 7 | ) 8 | 9 | func TestPass(t *testing.T) { 10 | rl := New(1, 3) 11 | 12 | for i := 0; i < 60; i++ { 13 | res := rl.Pass() 14 | time.Sleep(100 * time.Millisecond) 15 | fmt.Println(res) 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Talks/聚集算子.key: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wfnuser/Algorithms/8bb7db73d3413b7c49e09965b8dcd7ee9074b4c1/Talks/聚集算子.key -------------------------------------------------------------------------------- /Talks/通关BAT的算法学习之旅.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wfnuser/Algorithms/8bb7db73d3413b7c49e09965b8dcd7ee9074b4c1/Talks/通关BAT的算法学习之旅.pdf -------------------------------------------------------------------------------- /column.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wfnuser/Algorithms/8bb7db73d3413b7c49e09965b8dcd7ee9074b4c1/column.png -------------------------------------------------------------------------------- /papers/diff2.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wfnuser/Algorithms/8bb7db73d3413b7c49e09965b8dcd7ee9074b4c1/papers/diff2.pdf -------------------------------------------------------------------------------- /perturbation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wfnuser/Algorithms/8bb7db73d3413b7c49e09965b8dcd7ee9074b4c1/perturbation.png --------------------------------------------------------------------------------