Arganzheng's Blog

stay hungry, stay foolish

面试手撕代码(02):双指针与滑动窗口

Two Pointers and Sliding Windows: Monotonicity Turns O(n²) into O(n)

上一篇用哈希表换掉一层循环;这一篇不用额外空间,靠单调性做同一件事。两个指针都只往一个方向走,每个元素最多被每个指针经过一次,\(O(n^2)\) 的枚举就变成了 \(O(n)\)。它有三种形态:同向的滑动窗口(子串、子数组问题)、相向的对撞指针(有序数组的配对、面积、接雨水)、同向不同速的快慢指针(原地分区、链表中点)。三种形态的代码骨架都不到十行,难点全在什么时候动哪个指针——这个决定必须能用一句话证明”不动的那种情况不可能更优”。 本篇要回答的核心问题是: 滑动窗口的”右扩左收”什么时候成立、什么时候不成立?1 最小覆盖子串里”已满足的字符数”怎样让每一步都是 O(1)?2 接雨水的双指针为什么可以只看自己这一侧的最大值?3 一、识别信号 ...

面试手撕代码(01):数组、哈希与前缀和

Arrays, Hashing and Prefix Sums: Trade Space for a Loop

数组题是面试的开场题:题面短、代码短、十分钟内必须写完。它考的其实只有一件事——能不能用一张哈希表换掉一层循环。两数之和是”边查边存”,和为 K 的子数组是”前缀和 + 哈希计数”,最长连续序列是”只从起点数”,缺失的第一个正数是”把数组自己当哈希表”。四个题四种用法,背后是同一个动作:把”我之前见过什么”记下来,让第二层循环变成一次 O(1) 查询。 这一篇把哈希的四种用法、前缀和与差分这对互逆操作、以及原地哈希讲清楚,五道主讲题每道给完整的推演和 Python / Java 两个版本。 本篇要回答的核心问题是: “和为 K 的子数组个数”为什么是前缀和 + 哈希,而不是滑动窗口?1 “最长连续序列”怎样做到 O(n) 而不排序?2 “缺失的第一个正数...

面试手撕代码:从 LeetCode 中等题到 Transformer 组件(总纲)

Coding Interviews: From LeetCode Mediums to Hand-Written Transformer Components

内容简介 《面试手撕代码》是一组共十九篇的系列文章,面向要参加 AI 算法 / AI-Infra / 后端岗位面试、需要在白板或共享编辑器上当场写出能跑的代码的求职者。前十三篇覆盖 LeetCode 中等偏上难度的算法题——按解题模式而不是按数据结构的名字组织,每篇讲清一种模式怎么识别、模板长什么样、三到五道最典型的题怎样从题面推到代码、面试官会顺着问什么;后六篇覆盖 AI 岗位特有的”手撕模型组件”——attention、Transformer block、反向传播、tokenizer、采样、损失函数、经典 ML 与评测指标、以及 Infra 岗的并发与系统题。 它回答的问题是: 面试官给你一道没见过的中等题,四十分钟。你怎样在前五分钟认出它属于哪一类...

Python 中如何定义数据类并做校验:从 __init__、dataclass 到 Pydantic

在 Python 编程中,我们经常需要定义各种数据结构(如用户信息、配置项、API 请求体)。传统的写法不仅伴随着大量重复的模板代码,还面临着数据校验繁琐的痛点。 本文将带你梳理从原生 init、标准库 @dataclass 到 Pydantic 的演进过程,带你看看现代 Python 是如何优雅地处理数据建模与校验的。同时为了方便Java程序员快速上手,我们也横向对比了Java 生态(Record / Lombok / Bean Validation) 的实现差异 。 一、 Python 语法的演进:三种数据模型的构建方式 1. 传统流派:原生的 init 构造方法 在最传统的面向对象写法中,我们通过显式定义构造函数来接收并赋值属性。 class Use...

测试驱动开发

什么是TDD TDD的核心思想是先写测试用例,然后通过测试来推动整个开发的进行,包括接口的设计,代码的编写和重构。 整个TDD的过程就是红绿蓝三色循环迭代: 为什么要推行TDD 首先一个显而易见的好处就是编码阶段,通过单元测试验证我们的代码,可以方便的进行本地自测,提高代码的质量。《重构》中Matin Flower就说:一套测试就是一个强大的bug侦测机,能够大大缩减查找bug所需的时间。 但是TDD最大的好处还在于它不只是覆盖编码阶段,还对设计阶段产生重大影响。因为要提前写测试用例,意味着我们需要从接口调用方的角度使用我们定义的接口,这种角色的换位会让我们更好的设计出面向用户的友好接口。并且,为了能够单元测试该接口,在接口设计上还会考虑到接口的可...

用户行为串联方案

背景 目前商城的所有行为日志埋点上报都缺少一个唯一的用户行为ID。它的作用是串联用户行为的会话ID,用户行为包括曝光、点击、加购、下单、分享、点赞等,用户行为按时序依次产生,需要业务传递 traceId,标识点击、效果转换的动作是哪一次的曝光、点击产生的。 带来的问题就是用户行为日志没法很好的串联起来,正负样本生产和报表统计都会有偏差。 业界解决方案 1、阿里云推荐平台 1) 行为表(USER_BEHAVIOR) trace_id: 返回的推荐列表用于跟踪效果。如果对item_id 的行为不是来自推荐引导,则为NULL 2) 全流程规范 日志埋点规范在内容方面要求客户记录交易行为和准备行为,并且在记录用户行为日志时区分开这两种行为。和通...

参数服务器

Parameter Server 中文名称叫做参数服务器,是分布式机器学习框架中用来做参数同步的框架。 为什么需要引入 Parameter Server 各个 worker 之间需要共享模型参数 => 全局参数服务器 模型参数很大,超过单台机器的容纳能力 => 分布式参数服务器 训练数据太大,需要并行提速(大数据)=> 分布式参数服务器 设计要求 Efficient communication: 高效的网络通信。因为不管是模型还是样本都十分巨大,因此对网络通信的高效支持以及高配的网络设备都是大规模机器学习系统不可缺少的 Flexible consistency models: 灵活的一致性模型。不同的一致性模型其实...

机器学习中的特征工程

特征管理 特征元数据注册 特征视图、特征集、特征 数据源信息: 离线数据库、表名称等 存储引擎信息: 引擎类型、机房、IP等 存储格式信息: Key字段、Value字段等 特征更新信息: 更新周期、分区字段、分区方式等 元数据与存储系统打通(如 hive表,Redis 等) 离线特征可视化(类似于 hue) 在线特征可视化 特征的共享 共享特征库 引用计数 特征监控和...

一个java大堆引发的『血案』

现象 线上预估服务扩容新增了两台机器,同样的代码,同样的机器配置,但是有一台机器的平均时延就是比另一台机器慢一些(14ms vs. 20ms)。 1、64机器(时延慢一些的机器) JVM启动参数: /home/app/predictor-serving/jdk/jre/bin/java -Djava.util.logging.config.file=/home/app/predictor-serving/tomcat/conf/logging.properties -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -server -Xmx32g -Xms32g -XX:+Use...

使用CompletableFuture异步编程

Future vs. CompletableFuture JDK 5引入了 Future 模式。Future 接口是Java多线程 Future 模式的实现,在java.util.concurrent包中,可以来进行异步计算。 Future 模式是多线程设计常用的一种设计模式。所谓Future,顾名思义,就是结果在未来完成,先给你一个凭据。Future的接口很简单,只有五个方法: public interface Future<V> { boolean cancel(boolean mayInterruptIfRunning); boolean isCancelled(); boolean isDone(); ...

×