CodingTour
ARTS #34

Algorithm

本周选择的算法题是:Rotate Array

规则如下:

Given an array, rotate the array to the right by k steps, where k is non-negative.

Example 1:

Input: [1,2,3,4,5,6,7] and k = 3
Output: [5,6,7,1,2,3,4]
Explanation:
rotate 1 steps to the right: [7,1,2,3,4,5,6]
rotate 2 steps to the right: [6,7,1,2,3,4,5]
rotate 3 steps to the right: [5,6,7,1,2,3,4]

Example 2:

Input: [-1,-100,3,99] and k = 2
Output: [3,99,-1,-100]
Explanation: 
rotate 1 steps to the right: [99,-1,-100,3]
rotate 2 steps to the right: [3,99,-1,-100]

Note:

  • Try to come up as many solutions as you can, there are at least 3 different ways to solve this problem.
  • Could you do it in-place with O(1) extra space?

Solution

我实现的方案:

Runtime:56 ms,快过 93.80%。

Memory:14 MB,低于 5.09%。

class Solution:
    def rotate(self, nums: List[int], k: int) -> None:
        """
        Do not return anything, modify nums in-place instead.
        """ 
        if k == 0: return
        i, count, k = 0, 0, k % len(nums)
        while count < len(nums):
            current = i
            value = nums[i]

            while True:
                next = (current + k) % len(nums)
                value, nums[next], current = nums[next], value, next
                count += 1

                if current == i: break

            i += 1

Review

Swift’s closure capturing mechanics

很详细的 Swift 的闭包食用指南,作者还很贴心的在文章末尾介绍了 assert 的使用场景,值得一看。

Tip

在 Python3 中随时通过代码插入断点:

import pdb

pdb.set_trace()

Share

性能设计篇之“边缘计算”

边缘计算产生的背景是数据量越来越大,而分析结果的速度需要越来越快。

边缘计算的核心价值:

  • 减少数据中心成本
  • 减少问题的数量级

一些业务场景:

  • 收集结构化的数据
  • 实时设备监控
  • 云资源聚合

边缘计算的关键技术:

  • API Gateway
  • Serverless/FaaS - 服务函数化,不用关心执行背景

高效学习:端正学习态度

学习是逆人性的,没有即时反馈,需要持续学习,过程会让人感到痛苦,并随时想找理由放弃。

主动学习相比被动学习能大幅增加学习内容的留存率,主动学习的方式:

  • 讨论
  • 实践
  • 教授他人

如何深度学习:

  • 到源头查看第一手的资料
  • 把知识连成地图,将自己的理解后述出来
  • 不断地反思和思辩,与不同年龄段的人讨论
  • 举一反三,并践行之,把知识转成技能

具体的三个步骤:

  • 知识采集 - 获取信息源头
  • 知识缝合 - 知识梳理
  • 技能转换 - 通过举一反三、实践和练习,以及传授教导,把知识转化成自己的技能

学习的目的:

  • 是为了找到方法 - 学习是为了找到通往答案的路径和方法,是为了拥有无师自通的能力
  • 是为了找到原理 - 掌握本质,将世界变得简单
  • 是为了了解自己 - 开拓自己的眼界,发现自己的不足和上升空间,让自己成长起来
  • 是为了改变自己 - 改变自己的思考方式,改变自己的思维方式,将自己的算法变得高效

高效学习:源头、原理和知识地图

如何高效学习:

  • 使用第一手的资料,这包含熟练使用英文,使用Google,在社区交流等方式
  • 信息源要靠谱
  • 要有自己的经验和思考
  • 注重基础
    • 无论软件层面怎么创新,最终都不能脱离底层的物理限制
    • 基础知识有助于学习新的知识
  • 使用知识地图
    • 为自己创建一个学习路径,树状结构,将知识点挂上去
    • 知识地图有助于更系统和全面的学习

高效学习:深度,归纳和坚持实践

如何更好的进行系统学习:

  • 了解技术的灵魂 - 技术出现的背景、初衷和要达到什么样的目的或是要解决什么样的问题
  • 了解技术的优缺点 - 技术的优势和劣势分别是什么,或者说技术的 trade-off 是什么
  • 了解技术适用的场景 - 技术不能脱离场景,一般有两个场景:业务场景和技术场景
  • 了解技术的组成部分和关键点 - 技术的核心思想和核心组件
  • 了解技术的底层 - 掌握技术的底层原理和关键实现是学习一个技术的根本
  • 了解技术之间的差异 - 不同技术之间的实现会有不同的侧重点,对于开阔思维、深入细节很重要

举一反三的能力:

  • 联想能力 - 思考同一个事物的不同的用法
  • 抽象能力 - 抽象能力需要找到解决问题的通用模型
  • 自省能力 - 站在自己的对立面来找这个解的漏洞

关于举一反三的训练:

  • 对于一个场景,制造出各种不同的问题或难题
  • 对于一个问题,努力寻找尽可能多的解,并比较这些解的优劣
  • 对于一个解,努力寻找各种不同的测试案例,以图让其健壮

关于总结,要把碎片化的信息给结构化掉,然后在结构化的信息中,找到规律,找到相通之处,找到共同之处,进行简化、归纳和总结,最终形成一种套路,一种模式,一种通用方法。

关于实践,吃自己的狗粮,自己写代码,测试自己的代码,运维自己的代码,从中理解好的软件设计,并持续改进。

高效学习:如何学习和阅读代码

本文探讨了理解代码的方式。阅读代码前:

  • 了解基础知识 - 语言和基础技术的背景知识
  • 软件功能 - 了解软件要完成的功能和特性
  • 熟悉文档 - 理解 Why
  • 代码的组织结构

阅读代码的方法列表:

  • 接口抽象定义 - 理清数据结构或业务实体之间的关系
  • 模块粘合层 - 如中间件、Promise 模式、回调、代理委托、依赖注入等部分
  • 业务流程 - 可以通过流程图或时序图来帮助理解
  • 具体实现 - 寻找代码重点
    • 代码逻辑 - 分清业务逻辑和控制逻辑
    • 出错处理 - 排除出错处理的逻辑部分,可以更加高效地阅读代码
    • 数据处理 - 非处理的主要逻辑,如 DAO、DTO 等部分
    • 重要的算法 - 算法往往是最有技术含量的部分
    • 底层交互 - 要有一定的底层技术知识,不然很难读懂
  • 运行时调试 - 代码只有运行起来了才能知道具体发生了什么事