Algorithm
本周选择的算法题是:Construct Target Array With Multiple Sums。
规则
You are given an array target of n integers. From a starting array arr consisting of n 1’s, you may perform the following procedure :
- let 
xbe the sum of all elements currently in your array. - choose index 
i, such that0 <= i < nand set the value ofarrat indexitox. - You may repeat this procedure as many times as needed.
 
Return true if it is possible to construct the target array from arr, otherwise, return false.
Example 1:
Input: target = [9,3,5]
Output: true
Explanation: Start with arr = [1, 1, 1] 
[1, 1, 1], sum = 3 choose index 1
[1, 3, 1], sum = 5 choose index 2
[1, 3, 5], sum = 9 choose index 0
[9, 3, 5] Done
Example 2:
Input: target = [1,1,1,2]
Output: false
Explanation: Impossible to create target array from [1,1,1,1].
Example 3:
Input: target = [8,5]
Output: true
Constraints:
n == target.length1 <= n <= 5 * 1041 <= target[i] <= 109
Solution
impl Solution {
    
    // TLE
    // pub fn is_possible(target: Vec<i32>) -> bool {
    //     let mut stack = vec![vec![1; target.len()]];
    //     while let Some(arr) = stack.pop() {
    //         if target == arr { return true; }
            
    //         let sum: i32 = arr.iter().sum();
    //         for i in 0..target.len() {
    //             if sum <=target[i] {
    //                 let mut new_arr = arr.clone();
    //                 new_arr[i] = sum;
    //                 stack.push(new_arr)
    //             }
    //         }
    //     }
    //     false
    // }
    pub fn is_possible(target: Vec<i32>) -> bool {
        use std::collections::BinaryHeap;
        let mut queue: BinaryHeap<i32> = BinaryHeap::new();
        let mut sum: i32 = target.iter().sum();
        target.iter().for_each(|item| queue.push(*item));
        while let Some(mut num) = queue.pop() {
            if num == 1 { return true; }
            sum -= num;
            if num <= sum || sum < 1 { return false; }
            num %= sum;
            sum += num;
            queue.push(if num > 0 { num } else { sum })
        }
        
        true
    }
}
Review
10 Key Learnings in Rust after 30,000 Lines of Code
社区里曾经有一个探讨,如果 Rust 增加一个功能,可以用一个开关关掉 borrow checker 功能,你觉得如何?虽然不太可能,但大家得到了一个共识:这个功能一定会大受欢迎。
borrow checker 让人很烦,但也可以换一个角度看它,bc 实际上会让我们“被迫”重新设计程序,当我们开始关注每一个对象、变量的对象图、职责和依赖关系时,我们自然就“得到”了 Rust。
Tip
Rust 认为,alias + mutation 是造成不安全的主要原因,于是做出了「共享不可变、可变不共享」设计,使 Rust 在解决内存安全、多线程数据竞争问题上可以使用相同的抽象,这种熟练应用经典设计解决复杂问题的方式,体现了非常强的创新、抽象能力。
Share
什么是教练?
教练是帮助团队达成目标的关键角色。
类比球队里的教练,他们帮助团队实现成功的路上做了哪些事,和球员同吃同睡?改善球员的饮食结构?制定多元化的训练,强化核心力量?…
这些都对,但关键点只有一个:拿掉卡在齿轮里的东西。这是唯一的目标。
对公司的研发团队来说,我们希望团队开发的产品:
- 线上运行稳定点(减少 P0、提高可用性)
 - 提测质量高一点(代码质量、埋点质量、性能质量)
 - 发版过程顺一点(自动化、流程、工具)
 - …
 
然而团队作为一个实体、一个系统,还没办法做的那么理想化,但正是因为团队存在种种问题,我们这些所谓的 leader、manager 才有价值,我们要跟着大家一起解决遇到的难题、bug,找到阻碍团队质量的齿轮,Lead by Myself,而不只是评估团队表现。
做好团队的质量教练,可以下面这些方法。
了解团队的人和事,找到卡在团队齿轮里的东西是什么,确定团队目标:
- 团队要关注的重点质量指标是什么,为什么它重要
 - 团队的高质量提测人比例有多少,为什么有些人会更高,如何进一步提高比例(了解动机)
 - 不存在无端消极的团队,找到病根很重要,不能停留表象,要深入其中
 
跟大家一起去解决问题,拿掉卡在齿轮里的东西:
- 可能是一个难题、一个 bug、一个人、一件事
 
持续运转:抓关键目标,让大家一起尝到甜头,让团队动起来。
教练本质工作是帮助人成为明星,他是一位陪伴者,使用提问的方式、分享的方式、建议的方式,帮助实现目标,对教练来说,做一个项目和打一场球赛没什么分别。
