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 等部分
- 重要的算法 - 算法往往是最有技术含量的部分
- 底层交互 - 要有一定的底层技术知识,不然很难读懂
- 运行时调试 - 代码只有运行起来了才能知道具体发生了什么事