2020.2.28
-
Q&A:
-
Extra:
- process vs thread:
-
OOP:
-
Inheritance vs Composition: differences? advantages?
table Inheritance Composition Difference is-a relation has-a relation Difference extends implementation declare implementation advantages easy to understand relationship won't break encapsulation, easy to test, fits java for no multiple inheritance allowed -
what is dependency injection? advantages? Dependency Injection (DI) is a technique that transferring the task of creating the object to someone else and directly using the dependency.
Advantages:
- help unit tests
- easy to extend code / applications
-
polymorphism "many forms": able to process objects of various type through;
Polymorphism is a property of classes that they implement a common interface or derived from a base class.
Meanwhile Generics is a property of an algorithm.
-
connection pool? connection pool timeout? how to debug? Connection pool is a cache of database connections maintained so that the connections can be reused in the future.
print out connection in use and idle connection number, to see if there's abnormal usage. also check code for not releasing after used.
-
-
System Error:
-
CPU RAM: CPU invariable, GPU keeps rising: reason? solution? memory leak; thread usage too high? -> priority decay scheduling
-
Memory Leak: due to the program design problem, it loses control of the memory before releasing it, which will cause memory leak.
-
Garbage Collection: Garbage Collectin in Java is a mechanism that java virtual machine will from time to time recycle memory that no object is occupied in idle time.
-
Stack vs Heap:
-
Stack Stack is a special region of memory in computer, using LIFO priority, when function is called and declare new variables, they will be pushed onto stack, and freed when function is finished executing.
-
Heap Heap is another region of computer memory, it is not automatically managed. you need to use malloc() / calloc() to allocate memory on the heap, then free() after finishing using.
table Stack Heap Pros fast access, no need to do it manually variable can be gloabl, no limit on memory size Cons limit on memory size, can't resize variables, local variables only slower access, manual management -
-
-
-
Coding:
-
basicCalculator (without parenthesis):
public int basicCalculator(String s){ int sum = 0, num = 0, sign = 1, n = s.length(); char[] chars = s.toCharArray(); for(int i = 0; i < n - 1; i++){ char cur = chars[i]; if(Character.isDigit(cur)){ num = num * 10 + Character.getNumericValue(cur); } else if(cur == '+'|| cur == '-'){ sum += sign * num; num = 0; sign = (cur == '+') ? 1 : -1; } } sum += sign * num; return sum; } -
basicCalculator(with parenthesis):
public int basicCalculator2(String s){ int sum = 0, num = 0, sign = 1, n = s.length(); char[] chars = s.toCharArray(); Stack<Integer> stack = new Stack<>(); for(int i = 0; i < n; i++){ char cur = chars[i]; if(Character.isDigit(cur)){ num = num * 10 + Character.getNumericValue(cur); } else if(cur == '+' || cur == '-'){ sum += num * sign; num = 0; sign = (cur == '+') ? 1 : -1; } else if(cur == '('){ stack.push(sum); stack.push(sign); sum = 0; sign = 0; num = 0; } else if(cur == ')'){ sum += num * sign; sum = sum * stack.pop() + stack.pop(); num = 0; sign = 1; } } sum += num * sign; return sum; } -
basicCalculator(with words)* (skipped)
-
Find Leaves of Binary Tree
public List<List<Integer>> findLeaves(TreeNode root) { List<List<Integer>> ans = new ArrayList<>(); if(root == null) return ans; while(root != null){ List<Integer> cur_round = new ArrayList<>(); root = find_bottom(cur_round, root); ans.add(cur_round); } return ans; } public TreeNode find_bottom(List<Integer> list, TreeNode root){ if(root == null) return root; if(root.left == null && root.right == null){ list.add(root.val); return null; } root.left = find_bottom(list, root.left); root.right = find_bottom(list, root.right); return root; } -
Meeting Rooms
// naive brute force public boolean canAttendMeetings(int[][] intervals){ int cnt = 0; for(int i = 0; i < intervals.length; i++){ int curstart = intervals[i][0], curend = intervals[i][1]; for(int j = 0; j < intervals.length; j++) if(intervals[j][0] >= curstart && intervals[j][0] < curend) cnt++; if(cnt > 1) return false; cnt = 0; } return true; } // sort with lambda public boolean canAttendMeetings(int[][] intervals){ Arrays.sort(intervals, (a,b) -> Integer.compare(a[0],b[0])); for(int i = 0; i < intervals.length; i++){ if(i == intervals.length - 1) continue; if(intervals[i][1] > intervals[i+1][0]) return false; } return true; } -
Subdomain Visit Count
public static List<String> subdomainVisits(String[] cpdomains){ List<String> ans = new ArrayList<>(); Map<String,Integer> hm = new HashMap<>(); for(String pair : cpdomains){ int visit = 0, i = 0; while(i < pair.length()){ if(pair.charAt(i) == ' '){ i++; break; } visit = visit * 10 + Character.getNumericValue(pair.charAt(i++)); } String sub = pair.substring(i, pair.length()); hm.put(sub, hm.getOrDefault(sub, 0) + visit); while(i < pair.length()){ if(pair.charAt(i) == '.'){ String tmp = pair.substring(i+1, pair.length()); hm.put(tmp, hm.getOrDefault(tmp, 0) + visit); } i++; } } for(String domain : hm.keySet()){ int visits = hm.get(domain); StringBuilder sb = new StringBuilder(); sb.append(visits); sb.append(" "); sb.append(domain); ans.add(sb.toString()); } return ans; } -
Maximum Length of Repeated Subarray
public int findLength(int[] A, int[] B){ //[true, true, true, ..., false, false] //apply binary search int lo = 0, hi = Math.min(A.length, B.length) + 1; while(lo < hi){ int mi = (hi - lo) / 2 + lo; if(lencheck(mi)) lo = mid + 1; else hi = mid; } return lo - 1;//or hi - 1 since lo = hi } public boolean lencheck(int[] A, int[] B, int len){ Set<String> hs = new HashSet<>(); for(int i = 0; i + len <= A.length; i++){ hs.add(Arrays.toString(Arrays.copyOfRange(A, i, i + len))); } for(int i = 0; i + len <= B.length; i++){ if(hs.contains(Arrays.toString(Arrays.copyOfRange(B, i, i + len)))) return true; } return false; } -
Merge Intervals
public int[][] merge(int[][] intervals){ Arrays.sort(intervals, (a,b) -> Integer.compare(a[0], b[0])); LinkedList<int[]> list = new LinkedList<>(); for(int[] pair : intervals){ if(list.isEmpty() || list.getLast()[1] < pair[0]) list.add(pair); else{ list.getLast()[1] = Math.max(list.getLast()[1], pair[1]); } } return list.toArray(new int[list.size()][]); } -
Course Schedule
public String[] courseSchedule(String[][] courses){ Map<String, List<String>> students = new HashMap<>(); for(String[] match : courses){ if(!students.containsKey(match[0])){ List<String> courseList = new ArrayList<>(); courseList.add(match[1]); students.put(match[0], courseList); } else students.get(match[0]).add(match[1]); } List<String> ans = new ArrayList<>(); for(String s1 : students.keySet()) { for (String s2 : students.keySet()) { if (s1 != s2) { StringBuilder sb = new StringBuilder(); sb.append("[" + s1 + "," + s2 + "]" + ":"); for (String course : students.get(s1)) { if (students.get(s2).contains(course)) sb.append("\"" + course + "\"" + ", "); } if(sb.length() == s1.length() + s2.length() + 4) sb.append("[]"); while(sb.charAt(sb.length() - 1) == ',' || sb.charAt(sb.length() - 1) == ' ' ) sb.deleteCharAt(sb.length() - 1); ans.add(sb.toString()); } } } return ans.toArray(new String[ans.size()]); } -
Find Rectangles
public static List<List<Integer>> find_rectangles(int[][] matrix){ List<List<Integer>> ans = new ArrayList<>(); int row = matrix.length, col = matrix[0].length; boolean[][] possible = new boolean[row][col]; for(boolean[] b : possible) Arrays.fill(b,true); for(int i = 0; i < row; i++){ for(int j = 0; j < col; j++){ if(possible[i][j]){ if(matrix[i][j] == 1) possible[i][j] = false; else{ List<Integer> rec = new ArrayList<>(); rec.add(i); rec.add(j); int[] br = find_edge(matrix,possible,i,j); rec.add(br[0]); rec.add(br[1]); if(rec.get(0) == rec.get(2) && rec.get(1) == rec.get(3)) continue; ans.add(rec); } } } } return ans; } public static int[] find_edge(int[][] matrix, boolean[][] possible, int r, int c){ int i = r, j = c; while(i < possible.length && j < possible[0].length && possible[i][j]){ if(matrix[i][j] == 1){ possible[i][j] = false; break; } possible[i][j++] = false; } j--; i++; while(i < possible.length && j < possible[0].length && possible[i][j]){ if(matrix[i][j] == 1){ possible[i][j] = false; break; } possible[i++][j] = false; } i--; return new int[] {i,j}; } -
Line Wrapper:
public static List<String> line_wrapper(String[] words, int maxLen){ List<String> ans = new ArrayList<>(); StringBuilder sb = new StringBuilder(); int p = 0; while(p < words.length){ String word = words[p]; if(sb.length() == 0 && word.length() <= maxLen){ sb.append(word); p++; } else if(sb.length() != 0 && word.length() + 1 + sb.length() <= maxLen){ sb.append('-' + word); p++; } else{ ans.add(sb.toString()); sb.setLength(0); } } if(sb.length() != 0) ans.add(sb.toString()); return ans; } -
Friend Circle
public static int friendCircle_dfs(int[][] M) { int num = 0; boolean[] visited = new boolean[M.length]; Arrays.fill(visited, false); Map<Integer,List<Integer>> hm = new HashMap<>(); for(int i = 0; i < M.length; i++){ List<Integer> cur = new ArrayList<>(); cur.add(i); for(int j = 0; j < M.length; j++){ if(M[i][j] == 1) cur.add(j); } hm.put(i,cur); } for(int i = 0; i < M.length; i++){ HashSet<Integer> hs = new HashSet<>(); num += dfs(i,hm,hs,visited); } return num; } public static int dfs(int cur, Map<Integer,List<Integer>> hm, HashSet<Integer> group, boolean[] visited){ if(visited[cur]) return 0; group.add(cur); for(int friend : hm.get(cur)){ if(!group.contains(friend)) dfs(friend,hm,group,visited); } visited[cur] = true; return 1; } -
Parent Child
public static List<Integer> parentChildren1(int[][] relation){//0 and 1 parent nodes List<Integer> ans = new ArrayList<>(); Map<Integer,Integer> parentNum = new HashMap<>(); for(int[] pair : relation){ parentNum.put(pair[0], parentNum.getOrDefault(pair[0], 0)); parentNum.put(pair[1], parentNum.getOrDefault(pair[1], 0) + 1); } for(int node : parentNum.keySet()){ if(parentNum.get(node) <= 1) ans.add(node); } return ans; }public static boolean parentChildren2(int node1, int node2, int[][] pairs){//if have common parent HashSet<Integer> p1 = new HashSet<>(), p2 = new HashSet<>(); Map<Integer,Integer> child2parent = new HashMap<>(); for(int[] pair : pairs){ child2parent.put(pair[1], pair[0]); } int family1 = node1, family2 = node2; while(child2parent.containsKey(family1) || child2parent.containsKey(family2)){ if(child2parent.containsKey(family1)){ p1.add(family1); family1 = child2parent.get(family1); } if(child2parent.containsKey(family2)){ p1.add(family2); family2 = child2parent.get(family2); } } p1.add(family1); p2.add(family2); for(int root : p1){ if(p2.contains(root)) return true; } return false; }public static int parentChildren3(int node, int[][] pairs){//furthest ancestor HashMap<Integer,Integer> hm = new HashMap<>(); for(int[] pair : pairs) hm.put(pair[1],pair[0]); if(!hm.containsKey(node)) throw new IllegalArgumentException(); int root = node; while(hm.containsKey(root)){ root = hm.get(root); } return root; }
-