周骅的博客 - 所有文章
周骅,前端研发,目前就职于字节跳动。
介绍 scroll-driven animations
什么是 scroll-driven animations 先看这个示例,随着横向滚动条的滚动,唱片封面图出现了平滑的翻转、平移等动画效果。先设想一下,如果借助传统的 web 动画技术,我们应该如何实现这个效果。 如果使用传统的 web 动画技术,这个效果实现起来还是非常麻烦的,需
我的 2023 年度书单
消失的 13 级台阶 消失的 13 级台阶作者:高野和明出版时间:2020-05-15评分:8.6一对老夫妇惨遭杀害。一切证据都指向树原亮,他却因车祸,恰好丧失了案发前后数小时的记忆……死刑执行官南乡携手刚假释出狱的纯一调查,希望替这位丧失记忆的死刑犯洗清冤屈。但他们查到的唯一线
记录遇到的关于 regexp.test() 的一个小坑
起因是我的一段代码运行后得到了出乎意料的结果,类似于: const tokens = sentence.split(''); const index = 0; while (true) { const token = tokens[index]; if (/[a-z]/i.tes
Octalysis 游戏化框架理论
.limitImage p { max-width: 1000px !important; } 什么是游戏化 游戏化是指提取游戏中的那些引人入胜、令人着迷的元素,并应用到现实世界或产品设计的一种方法。 📖传统产品设计 以功能为中心 关注用户场景,注重效率 💥游戏化产品设计
语雀的定价决策
今天一早,就有同事转发了语雀的新的付费计划:语雀个人版新定价的细则。虽然我不是语雀的用户,但我看到这份收费计划时,直观地感觉这个设计十分糟糕。有很多方面有都问题,比如分享功能收费,协作功能不收费、暗黑模式收费等等。而我今天着重要谈的一点错误是免费计划限制苛刻的使用用量。新的语雀收
依赖注入与插件系统
很难得写点偏技术层面的东西。 在传统软件工程,特别是面向对象软件工程实践中,经常会提到“控制反转(IoC)”和“依赖注入(DI)”这样的名词。啥意思呢?解释起来其实不太容易。 我举一个不太恰当,但稍微能描述一下的类比,比如一台笔记本电脑,它需要什么功能?制造的时候并不清楚用户要怎
谈谈脱口秀大会第五季
这几天补了一下《脱口秀大会 5》,谈几点感受。最大的疑问是笑果这家公司怎么了。 首先抛开节目本身好看不好看,赛制合理不合理这些问题不论,《脱口秀大会》几乎是中国脱口秀演员线上表演的唯一方式,所以这个节目其实是很重要的。除了笑果,我在上海还看过喜剧联盒国、硬核喜剧等公司的演出,他们
郑庄公的性格分析(下)
郑庄公如何对待弟弟和母亲,多少还算家事范畴,而他如何对待周天子,则代表了他对待君臣纲常的态度。关于他不尊礼法,挑战天子的故事就更多了,第一件事就是周郑交质。 话说郑庄公与他父亲郑武公在位时都是周平王朝堂上的股肱大臣,称为卿士,相当于主政大臣。可郑庄公怎么会一天到晚窝在洛阳呢,他的
郑庄公的性格分析(上)
郑庄公是春秋早期活跃在历史舞台的人物,对于他的评价,却经常是两极分化的,有人认为他是雄心勃勃的政治家,也有人认为他是阴险歹毒的阴谋家。我将从有关郑庄公的两件代表性事件出发,分析身处历史转折点的郑庄公,他的所思所想。 说郑庄公活跃在春秋早期其实是不准确的,更准确的说法应该是春秋时代
“协作”是新一代办公软件的基石
近期比较引人注目的一件事就是 adobe 收购了 figma,虽然 figma 的高溢价导致 adobe 的股价应声下跌,但我认为对于 adobe 来说,却是转型的第一步,付出再大的代价都不可惜。 在我刚开始做前端时,设计师们是用 ai、ps 等 adobe 家的软件制作原型图,
西塘的两个世界
虽然久居上海,但从未到过西塘。西塘之于我的印象是江南水乡,古镇情调,人群熙攘。向往吗?也许吧,但也不期望有惊喜。 驱车不过一个半小时,就在午饭前赶到了西塘景区。路上车流不多,停车场也空空荡荡。大概近 40 度的高温让很多游客望而却步吧,也没多想。可一进入景区,我并没有感受到水乡的
“从列表页到详情页”的传统交互逻辑正在消亡
今天有了一个不成熟的观察——“从列表页到详情页”的传统交互逻辑正在消亡。我还没有太深入地想清楚这个问题,今天初步聊一下吧。 从前,不管是 C 端还是后台,列表页 + 详情页的组合都是非常常见的。早年的 QQ 主界面就是好友列表,点了一个好友后才打开对应的聊天窗口,这就是典型的列表
生物学带给我的思想冲击
高中时因为竞赛,我额外花了很多时间学习生物。当然并没有学多深,就是基本学完了《普通生物学》。这段经历其实对我影响很大,高考后填报志愿时,曾在选择计算机相关还是生物相关专业纠结了很久,只不过最后计算机相关专业赢了。说回学习生物的事,那段时间有几个瞬间让我有被冲击到的感觉,今天与大家
为什么看病难?
今天第一次做 CT。不如借这个机会,谈谈医疗资源的问题。 如果一个市民需要去医院看病,那么优先去三甲医院还是社区医院,优先挂专家号,还是普通门诊?如果条件允许,我想相当一部分人会优先选择三甲医院,挂专家号。我们常常认为的医疗资源紧张,其实是好医院、好医生供不应求。 先从患者的角度
聊聊混动汽车
今天再来聊聊汽车,其实也不算,准确说借汽车聊聊思考问题的方式。 最近随着华为 aito 汽车的发布,增程式混动技术又被推到了风口浪尖。余承东、李想们鼓吹增程式技术的多么多么的好,而更多的声音则站在另一边,认为增程式技术与其他混动技术相比,比如比亚迪的 DM-i,技术落后,纯粹是工
就事论事的智慧
跟大家分享一下最近读到的一些有趣的思想,希望也 带给你启发。当然如果你有更好的见解,或者不同的观点,也欢迎一起讨论。 今天想跟大家谈的是看透本质的逻辑思维,和高效平和的沟通方式,所以我给本文取名为《就事论事的智慧》。 说到就事论事,很多人就会说,这我知道呀,不就是“对事不对人”,
从“我打碎了夕阳……”谈诗歌鉴赏
今年 5 月抖音上出现了以『我打碎了夕阳』为开头的诗歌创作风潮,很有意思,涌现了不少好的作品。 聊具体作品前,我们先来破题。『我打碎了夕阳』作为诗歌的首句非常好,『打碎夕阳』这个意象极为宏大、磅礴,如果使用得当,就可能渲染出情绪的爆发。然而也有几个问题需要注意,『打碎夕阳』是一件
因果谜思
遇到问题我们会问『为什么』,一条条因果链条构成了基本逻辑。探索大千世界背后的逻辑,是人类孜孜以求的目标。然而事实上我们掌握规律比掌握底层逻辑要容易得多,看得到的现象距离看不到的机制可能相隔无比遥远。《三体》里讲过两个很有意思的『寓言』,一则是『射手假说』: 有一名神枪手,在一个靶
游戏中的排行榜与勋章
我们在做一款叫《水果大作战》的游戏,近期看到了两个相关需求,一个是勋章,一个是排行榜。不如今天就以此为话题聊聊。 排行榜与勋章都是为了赋予玩家成就感,而产生一定的内在动力去更好地完成游戏内容。不过这两者都不应该是那么地理所当然,应当去避免一些误区。 对于排行榜而言,它对于玩家的刺
我的产品观 - 2022
今天跟大家聊聊我的产品观,有许多观点来自其他人的输入,比如《俞军产品方法论》、louis 的产品效用论、黎婷的十倍体验差理论、张前川的一些分享等等。我们通过几个问题来开展我们的话题: 不懂用户,能做产品经理吗? 我们交付给用户的是什么? 产品的本质是什么? 如何理性地做感性的事?
工具软件的 block 化趋势
最早接触以 block 为基本单元组织内容的软件是文档类应用 notion,后来涌现了很多类 notion 的应用,一个很大的特点是放弃传统的富文本编辑形态,转而通过一系列基本的内容 block 提升文档的表现力、工具性和多人协作的便利性,飞书文档就是其中很好的代表。 与 mar
古德哈特定律
古德哈特定律 今天我看这个博客从 5 月 5 日到现在,不到两周的时间,已经写了 10000 字,更新的频率也超出了我原本的预期。等等,为什么我要关注字数和更新频率?这两个指标很重要吗?这能代表什么吗?回到出发点,我为什么要写博客?我只是想记录日常所思所想,也想把学到的点滴、有意
汉隆剃刀
记录一下今天看到一个有意思的思想:汉隆剃刀。 能解释为愚蠢的,就不要解释为恶意。 当生活中发生了不好的事情时,有人故意使坏其实是小概率事件,而更有可能是因为别人的愚蠢而导致的。这里的愚蠢更偏中性,可能是某人忘了、漏了、粗心错了、误会了、累了、被外力耽误了、不知情,或者纯粹因为懒。
成本与幸存者偏差
今天想聊的话题可能会比较无聊,记录一下路上开车的时候想到的一些东西。 上海封城期间,出门非常不方便,从居委开好出门证,一路上还会遇到好多警察设卡,检查核酸证明和出门证。我突然想,这些警察在查什么?肯定不是我这样的良好市民😉,也不是执行公务和运输物资的车辆。那会是什么呢?估计是不
为什么技术改进那么难推
在研发团队里,我们常常碰到技术改进推不动的情况,比如组件规范、代码规范,比如单元测试,比如新的工具链等等。这些东西明明有用啊,为什么有的人就那么被动呢? 有可能问题其实是出在这些技术改进上,从宏观上说,我们必须不断地改进方法,紧跟时代,不断精进我们的研发效率和研发质量,所以不断推
想对年轻工程师说的话
今天跟团队里几个刚毕业不久的研发同学聊天,有一些感想,整理成对年轻工程师的几点建议: 业务是大家的,成长是自己的 绝大多数研发都是投入在业务需求的开发中,很多人在其中花费了超过 100% 的工作时间,却体现不出参与感。为什么?或许是一种流水线思维。富士康产线上的装配工人能意识到手
核心用户与用户反馈
开始今天的话题前,我们先思考一个问题,我们的产品应该什么时候面向用户?初代学习灯是在2020 年 11 月发布的,但实际上软件功能与发布前 6 个月,基于 9 个月、12 个月前并无本质差异,那么中间这段时间是否是损失?我们有更多的产品/功能是仅仅快速完成了 mvp 版本,就正式
谈谈迭代与数据驱动
以我在字节这几年的感受,字节的产品性格是小步快走、数据驱动。今天我想聊聊产品迭代和数据驱动。 首先产品迭代是什么?我们把当前产品的状态(功能集合、数据指标等)记为 xxx,迭代过程记为函数 fff,那么我们就得到了这样一个迭代函数 x=f(x)x=f(x)x=f(x)。我们的目标
从小红书想到的
已经被疫情封闭在家很长时间了,生活很大的一个变化是做饭成了日常生活的一部分。很久以前,我觉得做饭特别难,我不懂盐少许是多少,也不知道油温七成热是多热。但现在突然觉得做饭简单了很多,为什么呢?不是我做得多学会了,而是我有了不粘锅和抖音/小红书。这两者让做饭的难度直线下降,基本上有手
GDG 分享 - RTC 技术在大力家教业务的应用
本文是 2022-01-15 GDG 主题分享内容的文字整理 前言 很多人可能不知道字节跳动的教育业务,其实我们在去年正式发布了“大力教育”这个品牌,产品线覆盖了几乎所有的教育相关细分领域。 『大力智能』呢是其中的教育硬件品牌。去年,与『大力教育』一同发布的,正是大力智能研发的
征服 number 类型的 input 框
在移动端 H5 页面开发中,有时候会有一些数值输入方面的需求。如果需要让用户比较方便地输入小数、负数,最简单的方式是使用 number 类型的 input 框,输入时软键盘会切换为数字键盘方便输入(ios 是带数字的全键盘,并允许 1e5 这类的表示方法)。但是在实际使用的时候会
从拥挤的兔子到伪随机数算法
阅读 《复杂》 一书时的笔记及延伸。 本文涉及到的生态学、数学、计算机科学部分都比较肤浅,如有错漏,欢迎斧正。 又是兔子 我们多少接触过这样一个 问题: 第一个月初有一对刚诞生的兔子 第二个月之后(第三个月初)它们可以生育 每月每对可生育的兔子会诞生下一对新兔子 兔子永不死去
快速排序算法的优化思路总结
前两天在 知乎 上看到了一个关于快速排序算法性能的问题,我简单总结了一个优化思路,现在在自己的博客里也贴一下吧,版权都是我的。 其实里面的大部分内容在我的另一篇博客里有讲过:深入了解 javascript 的 sort 方法 原回答:https://www.zhihu.com/q
深入了解 javascript 的 sort 方法
在 javascript 中,数组对象有一个有趣的方法 sort,它接收一个类型为函数的参数作为排序的依据。这意味着开发者只需要关注如何比较两个值的大小,而不用管“排序”这件事内部是如何实现的。不过了解一下 sort 的内部实现也不是一件坏事,何不深入了解一下呢? 算法课上,我们
让你的网站成为自定义搜索引擎
起 有一天,我在打理博客的时候,无意看到了这样的提示: “按 tab 可通过 zhouhua.info 进行搜索”?这是什么?于是我按了 tab: 看起来很高级嘛!输入“正则表达式”看看: 竟然真的有效果!到底发生了什么…… 打开 chrome 的搜索引擎管理: 我的博客怎么就被
小心别落入正则回溯陷阱
不知才哪儿看来的: 如果你有一个问题,你想到可以用正则来解决,那么你有两个问题了。 我觉得正则表达式实在是一种人难以理解的语言,比 xml 还要逆天。不过它真的很好用。正则表达式的坑在于,看到一个正则,我们很难直观地知道它要做什么;写了一个正则,我们也很难直观地想像机器是怎么处理
“===” 也有不靠谱的时候
自古js多奇葩,语言层面上有许多坑,入坑多了也就习惯了。那就再多一个坑吧。 javascript在判断两个值是否相等时,有两种方式 == 和 ===。这两者的区别我就不多说了,随便一本 js 书上都有,总之一般情形下我们有这样的结论:== 省事,但结果混乱,很多情形下近乎伪科学,
谈谈正则表达式中的 “.”
好久没更新内容了,今天分享一个小的知识点,一个正则表达式方面的很容易被人忽视的坑。 我们知道,正则表达式中,可以用 . 表示任意单个字符,但在 underscore 和 jquery 的源代码中,我们可以看到,这些著名类库的代码中,经常并不是用 . 来表示任意字符,而是使用 [\
干货!一步步实现自己的表单验证器
表单验证的需求简直太常见了。“所有用户的输入都是不可信的”这个思想指导我们在设计表单的时候,一定要进行用户输入的验证。对于用户体验而言,越早的反馈则越佳,所以表单验证的工作应该尽可能地在前端就进行(当然,前端对于后端而言也是输入端,所以后端仍然需要进行检验)。简单的表单验证完全可
巧妙判断一个单词是否有重复字母
今天上午刷到一道题,大体是写一个方法判断一个单词中是否有重复的字母(或者说一个字符串中是否有重复的字符)。我的思路是一个字符一个字符地遍历,如果发现有重复的停止: function isIsogram(str) { str = str.toLowerCase(); for (le
聊聊 rel=noreferrer 的事
背景 .scale { font-size: 2em; } 在一个页面 A 中,点击一个链接,浏览器会跳转到页面 B。那么如何描述 A 和 B 的关系呢?我们把 A 定义为 B 的 refer/referrer/referer(由于历史的原因,你看到上面这几个词都可以认为是同一个
判断回文字符串的新方法
当年去携程面试时,刘大师问了一个判断回文字符串(类似于 123454321)的方法,我是有备而来,刷刷就写了: function test(str) { return str.split('').reverse().join('') === str; } So easy。不过刘大
更优雅地绘制阴影
Box-shadow 虽然是一个 css3 的属性,但由于浏览器支持不错,且用它来营造一种立体感、层次感着实方便,这让它成为了互联网上随处可见的 css3 特效。不过我感觉想写好阴影不是一件容易的事情。至少我常常摸索半天,写出来的阴影却总让人很难受。 上周在知乎上看到了一个问答,
带 Alpha 通道的色彩叠加问题
css3 的 rgba 色彩模式、png/gif 图片的 alpha 通道、canvas 的 rgba 色彩模式、css3 的阴影、css3 的 opacity 属性等等,这些应用在网页中,有意无意间,我们的页面多了许多半透明的效果。我们知道,在没有 alpha 通道的情况下,两
在 Node.js 中使用多线程编程
在以前的博文 别说不可能,Node.js 中实现 sleep 中,我向大家介绍了 Node.js addon 的用法。今天的主题还是 addon,继续挖掘 c/c++ 的能力,弥补 Node.js 的弱点。 我曾多次提到过 Node.js 的性能问题。其实就语言本身而言,Node
学写 jquery 缓动函数
问题引入:实现如下效果 两个方块的追逐效果,使用 css3,实现起来没什么难度: <div id="container"> <div id="first"></div> <div id="second"></div> </div> #container { position: r
别说不可能,Node.js 中实现 sleep
Node.js 最让人不爽的就是其单线程特性,很多事情没法做,对 CPU 密集型的场景,性能也不够强劲。很长一段时间,我想在 javascript 语言框架下寻求一些解决方案,解决无法操作线程、性能差的问题。曾经最让我印象深刻的方案是 fibers,不过 fibers 也好,其他
必会 CSS3 技能:background-clip/background-origin
phantomjs 配合 kindlegen,kindle 看天涯不费力
长姿势
javascript 有一个鲜为人知的运算符,叫“趋向于”, 写作 --> 。可以声明一个变量 然后让它趋向于另一个数。 var x = 10; while (x --> 0) { console.log(x); } 就会打印 9,8,7,6,5,4,3,2,1,0 了 233
padding、margin 纵向取值问题
今天要说一个很基础,但被我自己忽略至今的一个简单问题:padding、margin 在纵向取值为百分数时,它们相对的是父元素的高度吗? 这个问题之所以被忽略,是因为使用场景有限。因为在布局的时候,我们通常只关注宽度,流式布局、响应式布局中,我们常常会给 padding 设置横向的
canvas 元素的宽高
设置一个元素的尺寸,推荐的做法是通过css设置其 width 和 height。不过今天我们说说一个特例:canvas。本文内容比较简单,我不做示例。 常见的设置 canvas 元素尺寸有两种方法。 给 canvas 元素设置属性,例如: <canvas width="400"
javascript 实现各种字符串搜索算法
我觉得在前端开发中过多地考虑算法没有太多实际的意义。但这仅仅是我觉得,我并没有证据证明这一点。那为何不来尝试一下,面对一个特定的任务,我将使用不同的算法来实现,看看究竟效率相差多少。今天我想通过字符串搜索这一场景来进行测试。 测试场景 主字符串就以 ABC 的一篇文章内容为例,略
另辟蹊径复制样式
技能get✓\checkmark✓ 先说一个需求,我想给一个元素应用另外一个指定元素的样式,应该怎么做?对于一个特定的项目,我想通常做法是规范代码风格,直接把 class 复制过来就可以了。但现实情况可能并不会如此简单。比如我们假定这个指定元素是不可预测的,它的样式可能由 cla
phantomjs 使用说明
phantomjs 实现了一个无界面的 webkit 浏览器。虽然没有界面,但 dom 渲染、js 运行、网络访问、canvas/svg 绘制等功能都很完备,在页面抓取、页面输出、自动化测试等方面有广泛的应用。 安装 下载phantomjs(官方下载。解压到任意目录,并将包含ph
在 Node.js 中实现阻塞
Node.js 中与生俱来的单线程编程、回调函数异步式风格让我们有时喜有时忧。先说单线程,很多人会费解于 Node.js 的单线程如何能做到高并发?这个问题不是本文重点,点到为止。澄清一点,Node.js 的单线程仅仅指 javascript 引擎是单线程的,无论如何我们没有办法
Application Cache
Application Cache 是 HTML5 为 web 应用离线使用而增加的 api,虽然都是有关存储,但与 LocalStorage、 Cookie、SessionStorage 有相当大的不同。Application Cache 存储的是一系列的请求资源,允许浏览器在
fibers in Node.js
fiber/纤程 在操作系统中,除了进程和线程外,还有一种较少应用的纤程(fiber,也叫协程)。纤程常常拿来跟线程做对比,对于操作系统而言,它们都是较轻量级的运行态。通常认为纤程比线程更为轻量,开销更小。不同之处在于,纤程是由线程或纤程创建的,纤程调度完全由用户代码控制,对系统
如何在 Node.js 环境下操作 DOM
Javascript 之所以为 Javascript,很重要的原因是浏览器为其实现了 DOM 和 BOM 接口(参考)。但在 Node.js 环境下,并没有 DOM 和 BOM,所以 html 文档与其他类型的文档并无不同,很难进行处理。而前端大量的 js 类库在 Node.js
CSS 性能优化系列之加载原理
无论是一位前端开发人员,还是一位产品设计人员,永远需要把用户体验放在第一位。只有良好的用户体验才会带来用户的持续关注和产品使用。那么,对于网站的设计来说,良好的用户体验又是如何建立的呢?因素很多,例如快速响应、良好交互、配色和谐、高易用性、风格统一等等,不过我认为有以下几个方面是
从 +new Date 说起,Javascript 的一元操作符
在偶然打开 d3 的源代码的时候,我看到了这样一段代码。 if (!Date.now) { Date.now = function () { return +new Date(); }; } 大体上可以看出这是在 Date 对象中加入一个 now 方法以获得当前时间。但是 ret
网页中元素实现水平居中的方法
网页中元素居中的需求很普遍,今天就要谈谈相对比较简单,使用场合更多的水平居中。 行级元素居中 我们知道 css 中有一个 text-align 的属性来定义子元素的水平对齐,不过它仅对行级元素生效。一种思路就是我们将想要居中的元素规定成 inline 或 inline-block