CodingTour
ARTS #198 | 龙船花

Algorithm

本周选择的算法题是:Maximize Score After N Operations

impl Solution {
    pub fn max_score(nums: Vec<i32>) -> i32 {
        let mut dp = vec![-1; 1 << nums.len()];
        Self::dfs(&nums, 0, &mut dp)
    }

    fn dfs(nums: &Vec<i32>, mask: usize, dp: &mut Vec<i32>) -> i32 {
        if dp[mask] != -1 { return dp[mask] }

        let mut k = nums.len();
        for i in 0 .. nums.len() {
            if mask & 1 << i != 0 { k -= 1; }
        }
        k >>= 1;
        if k == 0 { return 0 } 

        dp[mask] = 0;
        for i in 0 .. nums.len() {
            for j in i + 1 .. nums.len() {
                if mask & 1 << i != 0 || mask & 1 << j != 0 { continue }
                let mask_new = mask | 1 << i | 1 << j;
                dp[mask] = dp[mask].max(k as i32 * Self::gcd(nums[i], nums[j]) + Self::dfs(nums, mask_new, dp));
            }
        }
        
        dp[mask]
    }

    fn gcd(a: i32, b: i32) -> i32 {
        if a < b { return Self::gcd(b, a); }
        if a % b == 0 { return b }
        Self::gcd(b, a % b)
    } 

}

Review

Automate Your Busywork: Do Less, Achieve More, and Save Your Brain for the Big Stuff

从这篇文章中能看到很多感同身受的观点:

  • 整天忙碌不是因为工作太多,而是工作方式有问题

  • 人工智能不会取代人类,但使用人工智能的人会
  • 我们最好的工作应该是计算机无法完成的工作
  • 工作让你成为人,而不是生产力机器

作者对 “什么是 workflow” 也解释的非常清楚,“早晨去健身房” 只是一个行为,这个行为背后必须要做好计划,比如准备衣服、安排日程以准时到达那里,然后再准时到达办公室,这是一个为健身房做准备的完整工作流程。

我们忙碌、todo 事项太多,有可能是没有看清楚我们的 workflow 到底是什么。

Tip

两个新的函数: 深入了解 CSS 中的 :where() 和 :is() 函数

Share

什么是容器

从架构角度,可以延伸出三种类型的容器:

  • 应用容器
  • 业务容器
  • 运行容器

容器架构的完整形态应由这三部分组成。

应用容器

管理应用的生命周期,抹平应用间的差异。对应用容器来说,它们共享的是一整套基础设施,比如系统资源、DevOps、工程架构、共享组件以及配置,抹平开发环境、部署环境、接口环境等差异,并提供统一的 Sidecar 和应用级生命周期管理等。把一个新应用放入容器后,该应用初始状态下就已经具备了完整的应用生态,集成了埋点、日志等通用框架,以及稳定性解决方案等。

业务容器

业务(模块)级的生命周期管理,隔离、抹平业务间的差异。对业务容器来说,他们共享的是一套运行环境,拿复杂的美团举例,美团有独立的美团外卖产品,还有美团优选、美团买菜等产品,这些产品的背后是一条条独立的业务线,这些业务线既可以在独立的应用内闭环,也可以聚合为美团这个超级应用,既是原子化的业务组件,同时组件即应用。为了实现这一点,必须抽象出业务容器的概念,当打开美团外卖时,或者打开美团的外卖模块时,执行的业务逻辑没有任何区别(对业务层来说),并且退出功能模块或者退出整个产品,在资源回收等方面也没有差异,这些差异被业务容器抹平了,对业务来说,只需要关心业务的生命周期,并在对应的时机执行业务逻辑即可。

运行容器

运行容器是为特定场景提供的运行时环境,抹平运行时之间的差异,比如 WebView 和 FlutterView 的运行时差异,还有 FFI 要抹平的 Java、C++ 互调用差异等,它是面向具体技术生态提供的解决方案。对技术生态来说,它要把不变的部分和变化的部分隔离出来,比如不变的框架、标准层,而容易变化的是运行环境,拿 ArkUI 来说,它针对嵌入式场景提供了 JerryScript,为中等性能设备提供了 QuickJS,为高性能场景提供了 V8 引擎,这是一种基于场景的解决方案,识别到场景之间的差异性并提供最优解的同时,对业务隐藏了引擎(运行时)的差异。