• 首页
  • Web
  • 技术
  • 生活
  • 归档
  • 搜索
  • 关于
  • 使用脚本改进VSCode Markdown博客编写体验

    08-25

    背景

    本博客用的是Hexo,最近迁移了很多以前写在别处的文章过来,在迁移过程中发现最不方便的一件事情是图片的处理。

    大概的目录结构:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    - source
    - _posts 文章目录
    - hello1.md 文章
    - hello2.md 文章
    - assets 图片目录
    - hello1 与文章对应的子目录
    - 01.jpg
    - 02.jpg
    - hello2 与文章对应的子目录
    - 01.jpg
    - 02.jpg

    因为使用的是通用的工具(如VSCode)来编写Markdown,没有专门针对图片资源做额外的处理,因此在写文章的时候如果碰到需要插图,需要经历以下几步:

    1. 打开图片目录
    2. 新建与文章对应的子目录
    3. 放入图片
    4. 重命名图片
    5. 在文章中插入图片标记,类似这样![image 01](/assets/hello1/01.jpg)

    其中第1步和第5步都涉及到路径的问题,而且都需要手工进入或者手工输入,当路径比较深或者文章名称比较长的时候,既不方便也容易出错。

    ...more
  • 关于代码风格

    08-19

    2016年的旧文,之前未发表,时隔6年后整理一下发出来。

    如果从我写下第一行代码开始算的话,我写代码的历史大概已经超过20个年头了。这20多年里接触过各种各样的语言,也接触过各种各样的代码风格。当然也见证了很多代码风格引起的撕逼大战。

    对于代码风格这种事情上的架,我一般不参与吵的,觉得是一件很无聊的事情。直到今天(2016年)打开微博看到几十条评论,有点蒙圈。

    事情的起因是上周我在微博上发了一个条吐槽:

    最近面试好多人连12345这五行代码的执行顺序都讲不清楚。就算不知道5我也忍了,好多人连1234这四行代码是什么顺序跑的都搞不清楚。现在前端门槛低到这样的程度了么?(为了把它们排到第12345行上,刻意调整了代码格式,请轻拍。)

    附上了一段代码:

    1
    2
    3
    4
    5
    6
    7
    for(var i=0;
    i<3;
    i++){
    setTimeout(function(){
    console.log(i)
    },0)
    }

    然后今天收到了一堆吐槽:

    • “花括号不换行,烧死”
    • “等号两边不换行,烧死”
    • “逗号右边没加空格,烧死”

    在微博上也零碎地做了一些回复,不过还是觉得没有把想说的话说完,于是有了这篇。

    ...more
  • 2020总结

    03-13

    2020年的第一天是如何开始的已经完全没有任何印象了,现在来猜测一下,估计已经是快要开始进入回家过年的兴奋中了。然而这份兴奋还没来得及留下什么印象,就被突如其来的疫情冲散得无影无踪。

    总而言之,一个复杂的新年开始来了。

    1月23日,年二十九,武汉封城,随后湖北封省。就此开始没有走亲戚的过年,以及随后的居家办公。

    于我而言,每天看着疫情数字和武汉的各种神奇操作,焦虑和揪心都少不了。但就个人而言,却并不觉得有很不幸。目睹了身边的亲戚,因为隔离不能重返工作岗位,一边心里无比焦急,一边还要顾及过年的氛围多少需要一些自我安慰。相比之下,我能不受影响地工作,公司继续保障每个月的收入,算幸运了。

    这段日子不能说刻骨铭心,却也算得上印象深刻了。有吃有喝,还有点无所事事,能和家人在一起待这么久,也很好。

    ...more
  • 写代码是一件与确定性为伍的事情

    09-19

    我们所处的世界充满了各种各样的不确定性。但有一件事是不存在不确定性的,即写代码。

    多年以前,在我刚入行不久的时候,有一位前辈和我说过“出现问题的时候,先怀疑是自己的原因,因为机器是不会出错的,错的永远是人。”这句话我记了很久,也时不时就会翻出来回想一番,也会冒出很多更细的想法:那机器不也是人造的?机器的程序不也是人写的?就一定是自己的原因,不能是别人的原因吗?但反复想了很多年,还是觉得这句话相当有道理,即使是别人的原因,那错的也是人而不是机器。

    这其实就是写代码时的确定性,我们写的代码会被怎么运行,是非常确定的。即便它要依赖更多的底层软硬件机制,但仍然是确定的,只是找出这个确定性的过程更加复杂而已。

    一个例子

    如果你看不懂例子,跳过就好。

    背景

    项目中需要上传下载文件,使用的是某云服务的存储服务。在下载的部分,为了方便,使用Node.js封装了一个下载方法,返回一个Stream,而这个Stream本质上是由http请求库request.js请求后返回的。最后由koa框架返回这个Stream给浏览器。

    请求下载 -> 下载方法 -> request.js请求云服务 -> 返回Stream

    代码大致如下:

    1
    2
    3
    router.get('/api/download-file', async (ctx) => {
    ctx.body = Download.getPrivateStream(ctx.query.fileId);
    });

    然而,同样的代码,在不同的项目下,表现却大不一样,A项目访问图片时是直接在浏览器中显示图片,B项目访问同样的图片却变成了下载。调试工具一查看,发现它们有不一样的HTTP Header返回:

    • A项目Content-Type: image/png
    • B项目Content-Type: application/octet-stream
    ...more
  • 七月的风 八月的雨 还有九月的碎碎念

    09-16

    七八月,又是一年新朋友从校园走入职场的季节,也是又一年职场困惑季的开始。

    加班与内卷

    在996被全民声讨之后,“奋斗逼”又成为了被声讨的对象。然而很多人声音很大,却未看明白背后的关系。

    去过台湾的话,会发现台湾的朋友很敬业,在自己的岗位上怡然自得,初看非常羡慕。回来细想,这种怡然自得背后却是“看不到希望”的另一种表达。人活世上,是需要希望的。于有的人而言,努力工作升职加薪便是希望,于另一些人而言,不再相信努力工作可以升职加薪,于是觉得职场不是一个有希望的地方。

    《肖申克的救赎》是IMDB评分排名第一的电影,也是我最喜爱的电影之一。这部影片在我看来就是在讲希望。有希望就有可能,而一旦失去希望,即便你逃离了高墙大院,仍然会被自己困住。

    生活有意思的地方就在于,你可以选择相信,也可以选择不相信。有选择便是这个时代最大的幸运。我看到很多年轻朋友心中仍然有梦想、眼里仍然有星光。

    ...more
  • Urlencode踩坑日记

    03-31

    Urlencode又称百分号编码,是一种很常用的编码方式,作为前端工程师,少不了与它要打交道。不管是GET请求发送参数,还是POST请求发送body,都少不了要使用Urlencode来编码。

    而Urlencode的编码规则又特别简单:取出字符的ASCII码,转成16进制,然后前面加上百分号即可。如果是多字节的字符,则取出每一字节,按照同样的规则进行转换即可。例如问号?的ASCII码为63,转换为16进制为3F,所以%3F即为?进行Urlencode编码的结果。

    urlencode

    背景

    项目需要对外提供HTTP API接口,因此接口鉴权成为一个很重要的内容。为了确保安全,防止中间人篡改数据或进行重放攻击,双方约定的私钥不可以直接出现在请求中,因此采用请求签名的方式来鉴权。

    双方约定appKey和appSecret,其中appKey用于识别请求对象,appSecret用于请求签名。具体的方案如下:

    1. 客户端按照当前时间生成时间戳timestamp和随机数nonce
    2. 客户端按照指定的规则将HTTP请求的queryString和POST的body进行编码,得到一个字符串data
    3. 将timestamp、nonce和data按规则拼接,然后使用appSecret计算签名
    4. 将appKey、timestamp、nonce和签名一起随请求发出

    服务端在接到请求后将使用获得的数据和appSecret重新计算签名,然后判断与客户端给出的签名值是否一致,如果不一致则鉴权不通过。

    这一套鉴权机制可以有效防御一些攻击手段:

    • 使用了时间戳,可以避免过期请求被重发
    • 使用了随机数,可以避免请求被短时间重复发送
    • 签名数据包含了完整的时间戳、随机数和请求数据,保证服务端收到的确实是客户端发送的数据,避免被拦截修改
    • 签名的密钥是双方协商好的,避免请求伪造

    踩坑

    在上面的鉴权过程中,一个非常重要的点就是第2点,即将请求的queryString和POST的body进行编码,得到一个字符串。

    因为GET和POST请求中,数据都会被Urlencode编码,因此很容易想到,我们也使用Urlencode来进行这个鉴权前的编码过程。

    于是坑就这么不期而遇了。

    ...more
  • 【问答】为什么前端越来越复杂?Node.js有什么作用?

    03-18

    本文来自知乎问题:为什么要把前端搞的这么复杂,UI 组件不是很好用吗, 难道就是为了推广 nodejs 和 npm 吗?

    这个题目中有无数槽点:

    画个界面只要快就好了吗?JS类库能帮你解决渲染慢的问题?类库和组件能帮你解决所有的兼容问题?不需要高并发所以就不需要架构?

    这里的每一条都值得展开来反驳,但鉴于题主的主要疑问不在这里,就不跑题。

    这个问题的核心,抽取一下就是两个:

    1. 为什么前端越来越复杂了
    2. Node.js在前端开发中是干什么的
    ...more
  • 为什么微信的登录一定需要手机

    02-24

    来自知乎的问题,原地址https://www.zhihu.com/question/270040312/answer/1034679430。

    先说结论:微信是一个移动端通讯工具,再通俗一点,它就是一个手机软件。至于电脑版什么的,就是随手一做,如果威胁到手机版的地位,关掉都不会有人心疼的。

    知乎确实迎来新一辈的朋友了,似乎已经没有多少人知道微信诞生的背景,也没有人在乎背后的逻辑了。微信在知乎上的口碑也从一开始的神作,变成了最被唾弃的软件。

    先问几个问题:

    1. 微信10亿左右的月活用户(最近没翻财报,但大约是这个数字,量级不会错),你们猜有没有1亿人使用PC微信?
    2. 为什么你一边骂着微信,一边却离不开微信?
    ...more
  • 使用Rebase操作抹去Git仓库中的敏感信息

    11-29

    使用Git的时候,有时候会碰到需要从Git仓库中永久“抹除”某些敏感信息的情况。例如不小心提交了密码之类的信息到仓库,此时只抹掉这些信息重新提交是没有用的,因为其他人仍然可以通过Git历史看到这些敏感信息。因此需要一种方法将这些信息彻底从仓库中抹去。

    如果去网上搜索的话,能很容易找到使用branch-filter来处理的方法,例如

    1
    git filter-branch --tree-filter "find . -name '*.*' -exec sed -i '' -e 's/OLDSTRING/NEWSTRING/g' {} \;" -f

    写法有很多种,但是思路都差不多,就是遍历一遍所有的提交,对这些提交执行指定的命令(例如用sed替换指定的内容,或者移除相关文件),然后重新生成新的提交和分支。

    不过这种思路对于我来说却不太受用,原因有几个:

    1. 命令行掌握不太好,看到这种命令都不太认识,完全不敢直接放在项目中去跑
    2. 直接进行字符串级别的替换,在某些情况下不够用,例如想通过更复杂的编辑手段(新增文本、修改文本、删除文本同时操作)抹除敏感信息
    3. 直接对整个仓库/整个文件进行字符串级别的替换还是有些不放心,毕竟要修改的部分是明确的,却无法明确地指定这个命令只修改这一部分信息

    那怎么办呢?其实在这种场景下,也可以尝试使用git rebase来解决问题。

    rebase是干什么的

    rebase顾名思义,就是重新确定一个提交(一个分支)的“基”,这个“基”就是指它的祖先元素。具体的做法是,首先将提交退回到“基”所在的点,然后将之前做过的提交在这个“基”的基础上重复做一遍。相当于修改了当前分支衍生出来的基础,因此中文也被译为“变基”。

    ...more
  • Sequelize的一些小技巧

    11-10

    Sequelize.js是一个用于Node.js的数据库ORM库,支持Postgres、MySQL/MariaDB、SQLite、SQL Server等引擎。

    本文记录一些团队在使用Sequelize过程中积累的经验教训。

    介绍

    ORM即Object Relational Mapping,中文叫“对象关系映射”。简单地说就是可以将数据库的各种对象(表、字段)及关系映射为程序语言的对象和关系,从而使开发者不需要直接操作数据库,转而操作对象即可。

    例如,将表user映射为模型User后,从数据库中查询id为1的用户就可以直接调用findOne()方法:

    1
    2
    3
    4
    5
    const user = await User.findOne({
    where: {
    id: 1
    }
    });

    这样做会带来几个明显的好处:

    1. 降低开发难度:ORM都有完善的文档,几乎所有的操作只需要按文档调用指定方法即可,不需要自己拼接SQL
    2. 提升安全性:ORM会处理好SQL注入问题,不需要开发者关注
    3. 降低封装复杂度:公共逻辑可以基于ORM封装,非常方便

    下文不区分“模型”和“Model”,均指Sequelize中与数据表对应的数据模型。

    ...more
PREVNEXT

© 2012 - 2023 TooBug, powered by Hexo and hexo-theme-apollo.

粤ICP备15078043号