Thursday, November 4, 2021

V2EX - 技术

V2EX - 技术


作为一名“老”程序员,你会给初入职场的程序员什么忠告?

Posted: 04 Nov 2021 05:50 AM PDT

今天逛论坛逛到一个有意思的帖子:作为一个过来人,你会给初入职场的程序员什么忠告?(原帖出处: https://www.zentao.net/redirect-index-19834.html

想想我已经算是个老人了,还是个被现实蹂躏来蹂躏去的老人。 想想十年前的自己还朝气蓬勃,满腔热血,满头乌发,现在只剩满腔热血和跟不上的体力。

我会给初入职场的程序员什么忠告呢? 希望你多爱惜自己的身体,不然作为后浪的你是奔涌不起来的!

所以,作为一名"老"程序员,你会给初入职场的程序员什么忠告?

裸辞三个月的一些感想

Posted: 04 Nov 2021 05:49 AM PDT

前提:
坐标杭州,Java 工程师,一年多经验

我是从 8 月多从前公司离职的,至今离职已经有快 3 个月了吧。其实回家处理一些事情处理了 2 个月的时间。开始找工作的时间是从国庆后正式开始的。国庆后至今面了大概有 9 家,没有一个 offer 。
阿里一面就挂(自己对项目理解不深,然后思考问题没有往深了思考)
然后是一些中小公司。
比较深刻的是美登科技(这里安利一下这个公司,福利很好,团队氛围也好,面试官人也很好),每一面都有一些算法题,公司主要考察面试人的基础能力。所以常见的八股文在这里不怎么适用。这个公司真的很好,可惜自己能力不符合他们公司的要求。
然后有一家我认为八股文答得都很好了,最后 HR 面也过了。然后跟我说不合适,这个就打击到我了。
这一段时间找工作的经历让我得到了一些教训吧。当时很讨厌前公司 996 ,然后家里也有点事就裸辞了,现在到年底了,很多岗位好像也不招人了。而且裸辞渐渐的也要到三个月了,这三个月空档期可能都会成为一个简历黑点,多种情愫夹杂在心中,其实慢慢的心态已经渐渐被影响甚至崩溃了。
可能下次让我选择,就算再讨厌前公司我也不会裸辞了。只会找好下家再走,裸辞影响的经济是其次,它影响得心态实在是太严重了。慢慢的面试失败我就会怀疑自己能力,屡败屡战。今天去面试的时候,状态都不是很好。
废话了一堆,老哥们当看个笑吧~

Spring controller 的两个问题

Posted: 04 Nov 2021 05:36 AM PDT

一个 post 请求,接受参数映射 pojo ,参数的 key 和 pojo 变量名不同该怎么办?
另外,我尝试以 Map 类型接收参数,提示我是一个接口,无法实例化,那么有别的方法生成 map 吗?

给家里老人买 iphone13 性价比高吗?

Posted: 04 Nov 2021 05:34 AM PDT

大佬们,请教下:

父母用的是 iphone7 和 iphone7 plus ,已经用了 5 年了,没啥大毛病,就是容量小了点,拍视频照片+微信聊天 很容易占满(天天提醒空间不足 要删),然后就是电池,现在一天 3 充。

打算给他们换 iphone13 256GB ( pro 太贵了),不知道性价比如何呢?

iphone13 应该是手机大小比 iphone7 plus 小,但屏幕实际要比 iphone7 plus 大吧?

(不要推安卓啦,虽然性价比更高,但是想少折腾。)

Windows 11 在输入文字时是有 bug 吗?

Posted: 04 Nov 2021 05:31 AM PDT

使用自带拼音输入法,表现为:
1.文本框中输入中文,敲的拼音会突然变成英文输入,例如输入"中文",直接输入了"zhong 文",比如现在 v 站的输入文本框里就会出现,word 里也会出现。
2.右键重命名文件,文件名的文本会一直是全选的状态,无法移动光标单独编辑其中一段,只能在属性里重命名。
有遇到这种情况的吗?

感觉今年代码能力直线提升

Posted: 04 Nov 2021 05:31 AM PDT

今年看了差不多 500 多个小时视频,三四本书,每天回家都在写代码,培训出来工作 3 年一直都觉得很差劲,今年补了很多基础,真的对自己帮助太大了

使用 vmware 还是 docker 来搭建 Linux 实验环境?

Posted: 04 Nov 2021 05:31 AM PDT

本人是后端码农,工作(coding 、编译、执行、实验)需要用到 linux ,办公需要用到 windows 或者 mac(各种办公软件,IM 等)。公司不提供开发机器,我也不想弄两台机器,一台装 linux ,一台装 windows 或者 mac 。

在日常使用中,发现直接进入 docker 容器也可以进行 linux c++实验,速度快,尚未发现哪些坑。相比 vmware ,可以免去 vmware 的启动,vmware 内 linux 的启动。

在有限的实验次数、实验时间下,发现 docker linux 是可以胜任后端开发的 linux 的实验的。

请问问大家是如何不依赖外部 linux 机器的条件下,在 windows 或者 mac 上做 linux 实验的? docker 是否更方便?

ps: 1.此贴不是比较虚拟机和容器的区别,而是讨论虚拟机虚拟 linux 和容器 linux 哪个更易于做后端实验。 2.不讨论 docker 、vmware 提供的超出 linux 本身的特性。 包括但不限于:snapshoot ,网络抖动模拟。

Windows 11 下, Edge 的 tab 栏 在聚焦和非聚焦下似乎使用了两种不同的字体

Posted: 04 Nov 2021 05:15 AM PDT



上图为聚焦情况,下图为非聚焦。

可见聚焦情况下字体高度不一致,东字最后一划接触到了上方的横线,非聚焦下则字体正常。

有没有成熟一些 golang 的 mqtt broker 开源项目介绍

Posted: 04 Nov 2021 05:08 AM PDT

最近想了解 mqtt ,但好像主流的 broker 就那么几款,要么是 erlang 或是 java ,想着现在很多服务使用 golang ,找了一圈没找到比较成熟的,比如 gmqtt ,看起来介绍还不错,刚起步没多久,issue 不多,暂时不支持集群,https://github.com/DrmagicE/gmqtt.git ,不知道还有没有开源的比较成熟的 golang 的 mqtt broker ?

Python 如何搜索 hash/list 中的 json 数据

Posted: 04 Nov 2021 04:45 AM PDT

hash 的结构示例:

key: users
name: openid
value: json.dumps({ status: 2})

怎么快速搜索例如 users.xxxx.status == 2 这种条件的数据?

spring cloud gatway 性能真的那么差吗?还是我的用法不对

Posted: 04 Nov 2021 04:41 AM PDT

进行单个 http 接口的测试,
spring cloud gateway 对比 直接访问服务
QPS 下降 30%
响应时间增加 40%
这玩意还怎么用。。。

有人会写火狐的搜索插件吗?

Posted: 04 Nov 2021 04:37 AM PDT

最近被 csdn 搞得好烦,复制个简单配置字符串都不让,
我想在 所有搜索引擎里面默认加上 -csdn 选项,
搜索 hello 默认变成 -csdn hello
这样就屏蔽了 csdn 网站了
edge 等浏览器可以新加默认搜索引擎同时编辑 url 的,但是火狐不行,(我记得以前是可以的

虽说,火狐是收了搜索引擎的钱,但是不让编辑真的有点太霸道了。

火狐添加搜索引擎只能通过插件的方式(路越走越窄, 有小伙伴会写插件吗

令人惊喜的是 百度也支持这个命令。

未 root 的安卓 11 系统,有哪些好用的去广告软件,或者是类似 QuantumultX

Posted: 04 Nov 2021 04:22 AM PDT

现在用的 iqooneo5 ,开屏广告,尤其是很多 app ,切换回来,又重新来一遍开屏广告,好烦人,特别是贴吧这种的

有人和我一样在床上写代码的吗

Posted: 04 Nov 2021 04:14 AM PDT

刘禹锡看了我的房间,连夜把陋室铭删了


淘宝定制了一个床上书桌,冬天一起床披上棉被就能写代码 1a



床尾放了 xsx ,大冬天可以当暖气用,隔壁那台台式机装了 vmware exsi ,开了 n 个 ubuntu 当线上服务器 2a



床头搭了个 nas ,用 mac mini 当 devops 服务器,在家搞持续集成和自动化运维 3a



开了 zerotier ,哪怕在公司就和在家里一样,直接开发自己的项目( vscode remote 吹爆) 4a





虽然简陋,但是温馨



为啥要把书桌电脑放床上,这是当年大学养成的习惯,这样冬天写代码就不用下床了,之所以发这个是刚刚无意中找到大学时候的照片,突然想看看有多少人在床上写代码的



刚刚找到的我读大学的时候我床位的照片

5a

6a

vscode 有格式化插件能兼容 jetBrains 这种神奇的缩进吗?

Posted: 04 Nov 2021 04:02 AM PDT

image.png

接手的前端项目原本都用 jetBrains 系编写的,我用 vscode 格式化整个文件剧变不好协作呀

Azure 应用程序服务价格

Posted: 04 Nov 2021 03:32 AM PDT

可以 24 小时服务最便宜的也要 55 刀,比那些 ECS 贵太多,有没有便宜的渠道.Azure 上的应用程序能不能定时开关?会不会象上面的 sql 数据库,无法开关.

各位 Java 大佬好,先给大佬倒茶。关于 jdbc 与 mysql 交互问题

Posted: 04 Nov 2021 03:12 AM PDT

是这样我想知道 jdbc 与 mysql 交互,源码上网边看边查到 mysqlIO.class ,问题是我如果 jdbc 里面数据库名或者密码错了(虽然我知道错的),底层是怎么判断的 ,目的是要这套判断,和判断结果,套用在自己的数据上面,相当于借用他们的标准套在我们的数据库上面,以后也好形成统一。 还望各位大佬们不吝赐教,指条明路。我是菜鸡,只管喷。 祝大佬 情绪稳定,睡眠良好,头发浓密

目前代码看到这里 mysqlIO.class

void secureAuth411(Buffer packet, int packLength, String user, String password, String database, boolean writeClientParams) throws SQLException { String enc = this.getEncodingForHandshake(); if (packet == null) { packet = new Buffer(packLength); }

if (writeClientParams) {     if (this.use41Extensions) {         if (this.versionMeetsMinimum(4, 1, 1)) {             packet.writeLong(this.clientParam);             packet.writeLong((long)this.maxThreeBytes);             this.appendCharsetByteForHandshake(packet, enc);             packet.writeBytesNoNull(new byte[23]);         } else {             packet.writeLong(this.clientParam);             packet.writeLong((long)this.maxThreeBytes);         }     } else {         packet.writeInt((int)this.clientParam);         packet.writeLongInt(this.maxThreeBytes);     } } // 设置用户名 packet.writeString(user, enc, this.connection); if (password.length() != 0) {     packet.writeByte((byte)20);           try {         // 设置密码          packet.writeBytesNoNull(Security.scramble411(password, this.seed, this.connection.getPasswordCharacterEncoding()));     } catch (NoSuchAlgorithmException var11) {         throw SQLError.createSQLException(Messages.getString("MysqlIO.95") + Messages.getString("MysqlIO.96"), "S1000", this.getExceptionInterceptor());     } catch (UnsupportedEncodingException var12) {         throw SQLError.createSQLException(Messages.getString("MysqlIO.95") + Messages.getString("MysqlIO.96"), "S1000", this.getExceptionInterceptor());     } } else {     packet.writeByte((byte)0); }  // 设置数据库名 if (this.useConnectWithDb) {     packet.writeString(database, enc, this.connection); } else {     packet.writeByte((byte)0); }  if ((this.serverCapabilities & 1048576) != 0) {     this.sendConnectionAttributes(packet, enc, this.connection); } // 向 Mysql 服务器发送登录信息包(用户名、密码、此 Socket 连接默认选择的数据库) this.send(packet, packet.getPosition()); byte var10002 = this.packetSequence; this.packetSequence = (byte)(var10002 + 1); byte savePacketSequence = var10002;  // 读取 Mysql 服务器登录检验后发送的状态信息,如果成功就返回,如果登录失败则抛出异常  Buffer reply = this.checkErrorPacket(); if (reply.isLastDataPacket()) {     ++savePacketSequence;     this.packetSequence = savePacketSequence;     packet.clear();     String seed323 = this.seed.substring(0, 8);     packet.writeString(Util.newCrypt(password, seed323));     this.send(packet, packet.getPosition());     this.checkErrorPacket(); } 

}

macOS Monterey12.0.1 xcode 13.1 Simulator 打不开,卡死, 有一样的吗?

Posted: 04 Nov 2021 02:58 AM PDT

一直都是 未响应状态

就是因为打不开,所以重装了系统, 然后重装系统 ,安装 xcode 后,还打不开 Simulator

但是 有时候,却打得开, 几率很小

有一样问题的吗?

有解决办法吗?

如何遍历 dataframe 数据插入 pymysql 里?

Posted: 04 Nov 2021 02:48 AM PDT

一个 6000 行的 dataframe,遍历每行存到 sql 里.
之前都用 MongoDB 换了 sql 不会用了

安卓子系统的文件

Posted: 04 Nov 2021 02:47 AM PDT

装了个安卓版的 apple music ,感觉还行欸,只是听歌就比 itunes 强
但是文件管理器完全没法用?!先不说不能互通,碰到需要授予文件访问权限的 app 咋整(比如纯纯写作第一次启动就会要求授予权限)

大佬们,有没有什么方法限制一下微信,后台运行还关不掉真是头疼

Posted: 04 Nov 2021 02:42 AM PDT

三星 S21 刷了港版,深度休眠的 app 列表里面居然没有微信,难道港版的系统也给微信开后门了?

自己的手机居然还管不了后台应用,有没有什么方法限制一下,收不到消息无所谓

关于离线安装.deb 包的问题

Posted: 04 Nov 2021 02:28 AM PDT

在统信 uos(基于 linux 内核,硬件平台是龙芯 mips 架构)上安装 recoll(全文检索软件),但是要求只能在离线环境下安装如何解决依赖包的问题呢

问个 vscode 里使用 .clangd 的问题

Posted: 04 Nov 2021 01:53 AM PDT

根据 https://clangd.llvm.org/config ,可以在工程目录中包含 .clangd 文件的方式为 LSP 提供头文件路径信息。但是我工程里的源码可能路径深浅不一,这时就不好配了:

  • 方法 1:工程根路径下放一个 .clangd ,然后用相对路径,那我需要每遇到不同深度的源码,这里都要全部加一遍。
  • 方法 2:工程根路径下放一个 .clangd ,然后用绝对路径,那这样放在别人的环境下就不行了。
  • 方法 3:每个子项目源码目录下都单独放一个 .clangd ,可是目录太多了…

有更好的解法么?

就 CheckBox 还能玩这么多花活儿?

Posted: 04 Nov 2021 01:45 AM PDT

转一篇文章,原文地址: https://zhuanlan.zhihu.com/p/427999386

点赞关注不迷路,微信搜索"前端耳东",可加私人微信聊聊技术

卷累了吧?别背八股文了,快来看看我最近在某同性交友网站( GitHub )发现的这个有趣开源项目吧。

先上一张动态图你们自己感受一下。

没错,这是一张完全由 CheckBox 渲染出来的动态图形,它不仅可以画静态图形、动态图形,它还可以渲染图片、视频,甚至还可以用它来做小游戏。

这个项目的 GitHub 地址是checkboxland,演示 demo 地址是checkboxlandDemo

作者做这个项目的动机

具体讲这个项目的用法之前,我想先讲讲作者做这个项目的背景和动机,原文在这里(我做 checkboxland 的背景和动机),感兴趣的可以去阅读原文。

以下为原文的部分翻译总结:

"

2019 年 11 月我组织了 SparkNight 公司的 HackNight ,就在要开始这个 HackNight 的时候,我和朋友讨论到了附近的一个指示牌:

于是我意识到我有了一个完美的 hack night 项目:在 HTML 页面上用 CheckBox 来实现类似的效果。在 3 个小时候后,我和我的朋友实现了由 CheckBox 实现的数字时钟:

这确实是个有趣的项目,但是我不会让它止步于此,理论上说,我们可以使用 CheckBox 渲染一切东西对吧?

某种程度上来说,我做的那个数字时钟是比较笨拙的,因为你有很多的 CheckBox 要去控制,并且要在不同的浏览器上都能正确和一致的展示它们是比较困难的。

我一直在想那些可能会出现的动画效果,如果要是有个 JavaScript 库来帮助我轻松的做到这些就好了。

很快我有个在 Recurse Center 待一周时间的机会,于是我决定在这里把这个库做出来。当时这里的其他人都在做一些吊炸天的东西,比如神经网络或是逆向工程这种,只有我在把玩 HTML CheckBox🙃

不管怎样,我都把这个项目做出来了,它就是现在你们看到的 checkboxland ,它可以快速的产出 demo 看到效果。

埃隆马斯克曾经说过:"One of the biggest traps for smart engineers is optimizing a thing that shouldn't exist." 确实 checkboxland 就是埃隆马斯克说的那种"shouldn't exist"的事情,但是它就像泉水一样从我大脑中喷涌而出,让我不得不去做它。

将来我希望自己可以花更多时间去追求更有价值的事情,但是偶尔做做这种奇奇怪怪且有趣的事情还是很不错的,毕竟这个世界还是需要这些奇奇怪怪但是有趣的事物。

"

看完作者讲它做 checkboxland 的出发点和背景,确实很羡慕他们有很多的空余时间来实现自己的创意。

我们用 checkboxland 做点东西吧

讲完了 checkboxland 的创作背景,接下来该用它做点东西了,做东西之前先看看我们先讲讲 checkboxland 的基础用法。

基础用法

npm 安装使用

npm install checkboxland 

script 标签使用

画一个心形

画出一个简单的心形

从这个简单的例子看出来,使用 checkboxland 画图形主要是这么几步:

  1. 生成 Checkboxland 实例,传入参数:
    • dimensions:绘制区域的尺寸
    • selector:实例挂载 dom
  2. 实例 setData ,传入参数是二维数组,数组里面的 0 和 1 代表了 checkbox 是否选中

实现横向滚动字符

我们先用它画一张静态图,比如画出"前端耳东"这几个字,之前我们已经知道了画字符只要调用 setData 改变传入的 data 值就行了,所以画出静态图形的代码是:

画出的效果是这样的:

是不是感觉还不错?接下来我们给它加上横向滚动的效果

checkboxland 官方支持一个 marquee 方法,可以实现横向滚动的效果,具体使用方法可以看checkboxland.marquee

画出效果如下:

实现贪吃蛇小游戏

完整的项目地址:https://github.com/erdong-fe/checkboxland-demos,欢迎 star ,不白嫖

对于实现一个功能完备的项目来说,不管大项目小项目都不大可能一口气写好,都是一部分一部分的写好然后合成一个项目。

所以我们要做好逻辑的解耦,也就是把一大坨要实现的功能拆分为一个个的方法和类,每个方法负责什么、返回值和入参是什么,都要考虑清楚。

那么对于贪吃蛇这个小游戏,我们看看它要实现哪些功能:

  1. 绘制游戏区域和贪吃蛇
  2. 让贪吃蛇前进起来
  3. 让贪吃蛇响应键盘的控制来改变前进方向
  4. 让贪吃蛇吃到苹果长度加一,并且有新的苹果生成在游戏区域
  5. 贪吃蛇碰到游戏区域边缘的时候提示游戏失败

我们可以简单的按照上面功能的拆分,来一步一步的实现整个游戏。

绘制游戏区域和贪吃蛇

首先我们先绘制出来游戏区域和静态的贪吃蛇,这也是整个游戏的初始化。

先根据我们前面讲到的 checkboxland 基础来思考一下,要绘制游戏区域和贪吃蛇,需要哪些方法和变量?

显而易见,我们需要一个 checkboxland 实例和贪吃蛇变量,分别来记录当前游戏区域的状态和贪吃蛇的位置信息,checkboxland 实例很简单,就根据我们前面说到的基础用法来做:

贪吃蛇的位置信息我们需要用一个数组来存下:

现在游戏区域和贪吃蛇的数据都已经有了,我们需要把它们绘制出来,所以我们抽象出一个_draw 方法来专门负责绘制:

结合上面说的,我们整理一下代码,抽象出来两个主要的方法,一个是_initGame 方法负责初始化游戏区域和贪吃蛇的状态信息,一个是_draw 方法负责绘制贪吃蛇到游戏区域,完整代码如下:

效果如下:

让贪吃蛇前进起来

接下来我们让贪吃蛇前进起来。

让贪吃蛇前进起来,无非就是要做到两件事情:

  1. 修改贪吃蛇的位置信息
  2. 把修改后的位置信息绘制出来

首先我们先修改贪吃蛇的位置信息,默认它往右前进,那么我们只需要把贪吃蛇每个节点的 x 值加 1 就行了

所以,代码如下:

接下来我们要把贪吃蛇最新的位置信息画出来,我们要把_draw 方法移动到_moveSnake 方法内部来,这样子可以保证每次贪吃蛇状态发生改变时可以绘制出最新的贪吃蛇:

让贪吃蛇真正的动起来还差一步,就是需要按照一定的速度来不停的更新它的位置信息,并且不停的画出最新的贪吃蛇,所以我们用 setInterval 来实现。

因为它是在游戏初始化就要做的事情,所以这段代码可以放在_initGame 方法里面:

完整代码如下:

效果如下:

让贪吃蛇改变方向

前面我们实现了贪吃蛇前进,现在我们实现让贪吃蛇根据键盘输入来改变前进方向。

首先需要定义上下左右这四个方向的枚举:

然后,新增一个变量 direction 标识最新的方向,并且在 body 元素上绑定_onChangeDirection 方法响应键盘输入修改 direction 变量,修改 direction 时注意,如果键盘按下的新方向与当前正在进行的方向相反,仍然按照当前正在进行的方向前进:

最后,我们要让贪吃蛇根据方向改变前进方向。

改变方向这个行为,我把它分为两步:

  1. 第一步:对于除过蛇头的节点来说,它们依次在当前方向上往前移动 1 个单元即可
  2. 第二步:对于蛇头节点来说,要根据方向来调整它的坐标,比如当前方向是向右,新方向是向下,那么蛇头节点的 y 坐标就要加一,如图所示:

所以我们修改_moveSnake ,代码如下:

完整代码如下:

效果图如下:

让贪吃蛇吃到苹果

这一节我们实现让贪吃蛇吃到苹果的功能。

我们需要实现以下两个逻辑

  1. 更新贪吃蛇的位置后,判断它是否吃到了苹果;如果吃到了要更新贪吃蛇的长度并且重新生成苹果
  2. 生成苹果位置的方法

判断是否吃到苹果的逻辑很简单,只需要看蛇头节点的坐标是否和苹果的坐标重合即可;

当贪吃蛇吃到苹果时,我们只需要在蛇尾处 push 进一个新的节点即可,如下图:

代码我们直接加在_moveSnake 方法里就好,代码如下:

新增一个变量保存苹果的位置信息,并且在绘制区域的范围内生成随机数即可,不过要注意生成的苹果不能刚好被贪吃蛇节点覆盖住,代码如下:

在每次吃到苹果之后,调用_generateApple 方法重新生成苹果即可,代码如下:

整体代码如下:

效果如下:

游戏区域边缘碰撞检测

贪吃蛇的大部分功能已经实现结束了,现在还剩一个小功能,就是当贪吃蛇前进到游戏区域边缘的时候要判定游戏失败。

我们要新增一个_isSnakeCrossBorder 方法来判定贪吃蛇是否超出了游戏区域边界:

然后修改_moveSnake 方法加入边界判断方法,碰到边界后游戏重新开始:

整体代码:

效果如下:

结尾

本文主要是介绍了 checkboxland 以及它的用法,最后用做一个贪吃蛇小游戏来进一步熟悉 checkboxland 的用法以及 JavaScript 编程。

后面我会以这样在做中学的方式带来更多的文章教程,欢迎关注点赞。

放弃使用 useCallback 吧,我们有更好的方式

Posted: 04 Nov 2021 01:36 AM PDT

自从 React Hooks 面世以来,我们对其讨论便层出不穷。今天我们来谈谈 React.useCallback 这个 API 。先说结论:几乎所有场景,我们有更好的方式代替 useCallback

我们先看看 useCallback 的用法

const memoizedFn = React.useCallback(() => {   doSomething(a, b); }, [a, b]); 

React 官方把这个 API 当作 React.memo 的性能优化手段而打造。看介绍:

把内联回调函数及依赖项数组作为参数传入 useCallback ,它将返回该回调函数的 memoized 版本,该回调函数仅在某个依赖项改变时才会更新。当你把回调函数传递给经过优化的并使用引用相等性去避免非必要渲染(例如 shouldComponentUpdate )的子组件时,它将非常有用。

那我们就来从性能优化的角度看看 useCallback

示例:

const ChildComponent = React.memo(() => {   // ...   return <div>Child</div>; });  function DemoComponent() {   function handleClick() {     // 业务逻辑   }    return <ChildComponent onClick={handleClick} />; } 

DemoComponent 组件自身或跟随父组件触发 render 时,handleClick 函数会被重新创建。 每次 renderChildComponent 参数中会接受一个新的 onClick 参数,这会直接击穿 React.memo,导致性能优化失效,并联动一起 render

当然,官方文档指出,在组件内部中每次跟随 render 而重新创建函数的开销几乎可以忽略不计。若不将函数传给自组件,完全没有任何问题,而且开销更小。

接下来我们用 useCallback 包裹:

// ...  function DemoComponent() {   const handleClick = React.useCallback(() => {     // 业务逻辑   }, []);    return <ChildComponent onClick={handleClick} />; } 

这样 handleClick 就是 memoized 版本,依赖不变的话则永远返回第一次创建的函数。但每次 render 还是创建了一个新函数,只是没有使用罢了。 React.memoPureComponent 类似,它们都会对传入组件的新旧数据进行 浅比较,如果相同则不会触发渲染。

接下来我们在 useCallback 加上依赖:

function DemoComponent() {   const [count, setCount] = React.useState(0);    const handleClick = React.useCallback(() => {     // 业务逻辑     doSomething(count);   }, [count]);    // 其他逻辑操作 setState    return <ChildComponent onClick={handleClick} />; } 

我们定义了 count 状态作为 useCallback 的依赖。若 count 变化后,render 则会产生新的函数。这便会击穿 React.memo,联动子组件 render

const handleClick = React.useCallback(() => {   // 业务逻辑   doSomething(count); }, []); 

如果去除依赖,这时内部逻辑取得的 count 的值永远为初始值即 0 ,也就是拿不到最新的值。如果将内部的逻辑作为 function 提取出来作为依赖,这又会导致 useCallback 失效。

我们看看 useCallback 源码

ReactFiberHooks.new.js

// 装载阶段 function mountCallback<T>(callback: T, deps: Array<mixed> | void | null): T {   // 获取对应的 hook 节点   const hook = mountWorkInProgressHook();   // 依赖为 undefiend ,则设置为 null   const nextDeps = deps === undefined ? null : deps;   // 将当前的函数和依赖暂存   hook.memoizedState = [callback, nextDeps];   return callback; }  // 更新阶段 function updateCallback<T>(callback: T, deps: Array<mixed> | void | null): T {   const hook = updateWorkInProgressHook();   const nextDeps = deps === undefined ? null : deps;   // 获取上次暂存的 callback 和依赖   const prevState = hook.memoizedState;   if (prevState !== null) {     if (nextDeps !== null) {       const prevDeps: Array<mixed> | null = prevState[1];       // 将上次依赖和当前依赖进行浅层比较,相同的话则返回上次暂存的函数       if (areHookInputsEqual(nextDeps, prevDeps)) {         return prevState[0];       }     }   }   // 否则则返回最新的函数   hook.memoizedState = [callback, nextDeps];   return callback; } 

通过源码不难发现,useCallback 实现是通过暂存定义的函数,根据前后依赖比较是否更新暂存的函数,最后返回这个函数,从而产生闭包达到记忆化的目的。 这就直接导致了我想使用 useCallback 获取最新 state 则必须要将这个 state 加入依赖,从而产生新的函数。

大家都知道,普通 function 可以变量提升,从而可以互相调用而不用在意编写顺序。如果换成 useCallback 实现呢,在 eslint 禁用 var 的时代,先声明的 useCallback 是无法直接调用后声明的函数,更别说递归调用了。

组件卸载逻辑:

const handleClick = React.useCallback(() => {   // 业务逻辑   doSomething(count); }, [count]);  React.useEffect(() => {   return () => {     handleClick();   }; }, []); 

在组件卸载时,想调用获取最新值,是不是也拿不到最新的状态?其实这不能算 useCallback 的坑,React 设计如此。

好了,我们列出了一些无论是不是 useCallback 的问题。

  1. 记忆效果差,依赖值变化则重新创建
  2. 想要记忆效果好,又是个闭包,无法获取最新值
  3. 上下文调用顺序的问题
  4. 组件卸载时获取最新 state 的问题

我都想避免这些问题可以吗?拿来吧你!

我们先看看用法

function DemoComponent() {   const [count, setCount] = React.useState(0);    const { method1, method2, method3 } = useMethods({     method1() {       doSomething(count);     },     method2() {       // 直接调用 method1       this.method1();       // 其他逻辑     },     method3() {       setCount(3);       // 更多...     },   });    React.useEffect(() => {     return () => {       method1();     };   }, []);    return <ChildComponent onClick={method1} />; } 

用法是不是很简单?还不用写依赖,这不仅完美避开了上述所有的问题。而且还让我们的 function 聚合便于阅读。废话不多说,上源码:

export default function useMethods<T extends Record<string, (...args: any[]) => any>>(methods: T) {   const { current } = React.useRef({     methods,     func: undefined as T | undefined,   });   current.methods = methods;    // 只初始化一次   if (!current.func) {     const func = Object.create(null);     Object.keys(methods).forEach((key) => {       // 包裹 function 转发调用最新的 methods       func[key] = (...args: unknown[]) => current.methods[key].call(current.methods, ...args);     });     // 返回给使用方的变量     current.func = func;   }    return current.func as T; } 

实现很简单,利用 useRef 暂存 object,在初始化时给每个值包裹一份 function,用于转发获取最新的 function。从而既拿到最新值,又可以保证引用值在声明周期内永远不改变。 完美,就这样~

那么是不是 useCallback 没有使用场景了呢?答案是否定的,在某些场景下,我们需要通过 useCallback 暂存某个状态的闭包的值,以供需求时调用。比如消息弹出框,需要弹出当时暂存的状态信息,而不是最新的信息。

最后,推荐一下我写的状态管理 HeouseMethods 已经包含其中。后面会分享写 Heo 库的动机,欢迎大家持续关注。

能不能同时查询 mysql 和 oracle

Posted: 04 Nov 2021 01:35 AM PDT

现在线上有新老两套,oracle 11g 和 mysql 。
有没有办法能实现一句 SQL 联合查询这两个数据库?
通过 ETL 工具似乎实时性比较差?
求一个比较好的方案。可以理解为 mysql 是 oracle 上部分表的扩展,可能还需要 join 一下。
如果没有现成工具,用 python 怎么能把这个查询问题解决。

超极本电池突然损耗特别快是什么情况?

Posted: 04 Nov 2021 01:26 AM PDT

17 年买的 dell xps13 ,一直作为个人开发使用的笔记本,21 年 7 月回了老家,公司没给配电脑,这台笔记本就作为主力开发机了,今天检查了一下,发现从 6 月份开始,电池损耗的贼快,半年不到损耗了 20%,有哪位大神知道这个是什么情况吗?照这样损耗下去估计就用不了多久电池就要报废了啊(T▽T) 图片.png

求问各位老哥软考高级的系统架构设计师该怎么准备比较好?

Posted: 04 Nov 2021 01:19 AM PDT

小弟最近想搞个高级职称方便摇号,所以准备报名明年的软考。个人背景就是科班出身的小硕,最近刚开始工作。

求问各位有经验的老哥:

  1. 需要的教材是啥呀?就是官网上提的 6 块钱一本的 系统架构设计师考试大纲 吗?还有啥别的资料需要购买的吗?

  2. 培训视频有啥推荐吗?我看 B 站上有很多各种各样的培训机构的,各位老哥之前有看过感觉比较好的吗?

  3. 刷题的手机 app 有啥推荐的吗?

  4. 对于论文部分的准备有啥建议吗?有没有什么类似范文合集之类的辅导书推荐?

  5. 老哥们当初准备的时间线大致是怎么样的?

先提前谢过各位老哥了!

闲着没事用 Kotlin 写了个 Rust 风格的 Result

Posted: 04 Nov 2021 01:02 AM PDT

fun main() {     val fileUtil = FileUtil()     val result = fileUtil.openFile("ok")     val content = result match {         OK {             data         }         Error {             throw error         }.toString()     }     println(content) } 

Error 闭包那个 toString 想了好久也没想出怎么去掉。

发现 google logo 上方有一张写着 0 和 1 的图片

Posted: 04 Nov 2021 12:43 AM PDT

图片

Can't find you girlfriend

翻译了一下是

KAO

打开代码描述是: Charles K. Kao's 88th Birthday

维基查了一下发现: Sir Charles Kuen Kao (4 November 1933 – 23 September 2018).

有点意思

c++面试题,数字范围包含关系判断。

Posted: 04 Nov 2021 12:25 AM PDT

C++
给定一个 list<int> , 例如{1 ,21 ,55 ,99 ,111 ,10000 ,99999} 随机,依次递增。
再给定一个 list<pair<int, int> > 数据为 {( 1 ,8 ),( 10 ,20 ),( 27 ,100 )} 随机,依次递增,每个 pair 不存在交集。中间可以有空缺。

假定两列数据都大于 100w 条,如何快速列出第一个列表的数字存在于第二个列表中。
比如 1 ,就属于(1,8),55 属于( 27 ,100 ),21 则不属于;
有无最优解,求问大佬。

idea 这个代码悬浮的功能叫什么名字?怎么关掉?

Posted: 03 Nov 2021 11:59 PM PDT

如图

Imgur

不知道传成功了没有 ,我还是发下图片网址吧, 是 gif 图 https://imgur.com/q5rUrwp

https://imgur.com/GN5OZTH

idea 里面 git merge 把远程 merge 到本地,本地代码直接没了

Posted: 03 Nov 2021 11:23 PM PDT

本地 A 文件夹里面有个 b.file ,

我把它移动到 A/B/b.file 了,进行修改然后 commit 了

远程分支修改了 b.file ,我把修改 merge 到本地。因为我不需要远程的修改,所以我选择了保留自己的修改,结果 b.file 直接被删了

我怀疑是 idea 认为我对 b.file 的操作是「删除」操作,但问题是,我对 b.file 的操作是「移动到 A/B 目录,并进行修改」

这种怎么解决呢?

群晖 DSM 7.0.1 媒体服务器有问题?

Posted: 03 Nov 2021 11:12 PM PDT

原来用极米的投影仪,文件里能自动发现并展示群晖的媒体文件夹(基于 DLNA/UPnP?),现在没有了……

Foliate

Posted: 03 Nov 2021 10:51 PM PDT

https://johnfactotum.github.io/foliate/

一个只有 Linux 版本的,但是实现非常优雅的电子书阅读软件。

Google One 手机备份总是失败

Posted: 03 Nov 2021 09:57 PM PDT

手机红米国行,带 GMS, Play 服务和 Store 都是最新,照片备份没有任何问题,手机备份总是失败,是国内就这样,还是什么原因?

我在我的 k8s 集群里跑了一个 Minecraft 服务器

Posted: 03 Nov 2021 08:37 PM PDT

磨了两年的前端新轮子,刚刚终于把初版文档写完了!

Posted: 03 Nov 2021 05:59 PM PDT

就用下班那点时间,终于把文档补完了!!!!写文档都写了几个月!!!

ofajs - 新时代渐进式 web 前端框架

只要是开发,都会觉得简单的前端框架,没有 Vue/React/Angular 的 node+npm+webpack 学习起步三件套,而是像小程序那样开箱即用的;基于 web component 运行在现代浏览器上,没有打包操作;

希望大家能帮忙测试一下,文档有哪些不太清楚的地方,或者有 bug ,都可以指出;

有小伙伴要和我一起搞吗,用 ofajs 和 bootstrap 封装一个 UI 库,感觉会很好用。(一个人精力有限)

还有能帮忙按个 star⭐️吗,真的搞了好久了😭

ofa.js-GitHub 地址

真的磨了两年,可以翻一下我的发帖记录

前端动画效果有什么推荐的教程或者书可以学习吗?

Posted: 03 Nov 2021 12:18 PM PDT

我 React 写业务写得挺溜的,但是对实现动效完全一窍不通

Python 怎么在项目文件里隐藏自己的 API 密钥?

Posted: 03 Nov 2021 11:39 AM PDT

最近在做一个启动器,做到使用微软账号登录的部分,看到这样一段:

The next step is to get an access token from the auth code. This isn't done in the browser for security reasons.

This exchange should be done on the server-side as it requires the use of your client secret which, as the name implies, should be kept secret.

POST https://login.live.com/oauth20_token.srf  client_id=<your client id>  &client_secret=<your client secret>  &code=<auth code / the code from step 1>  &grant_type=authorization_code  &redirect_uri=<your redirect uri> 

像这种需要client_secret才能使用的认证服务,client_secret一般怎么保存(或者隐藏)?

No comments:

Post a Comment