作者 | 丁广辉 责编 | 张红月 出品 | CSDN(ID:CSDNnews) 工欲善其事,必先利其器。这句话放到开发者的世界里也是一样的,好的开发者也需要好的开发工具。世界上那么多开发工具,总有一些是更快捷,更好用的。StackShare是一个开发者工具及服务分享平台,成立于2013年,随着开发者们的不断加入,汇集了大量的优质工具。 在过去的2021年,StackShare统计了过千万用户分享数据,汇总了600K+的技术栈使用情况,超700万对各类工具的关注度,以及数百万的开发者的评论和投票。从而颁布了2021年StackShare第八届顶级工具奖,快来看看有没有你青睐的开发工具吧。 年度最佳新兴工具 1.FastAPI 高性能的简单,可快速编码,可用于生产的网络框架,链接:https://stackshare.io/fastapi 2.GitHub Copilot 在编辑器中获取对整行或整个函数的建议,链接:https://copilot.github.com/ 3.FiglamFigma 为团队设计的在线白板,链接:https://www.figma.com/figjam/ 4.Logtail 像查询数据库一样查询日记,链接:https://logtail.com/ 5.Coder 开发人员工作区平台,链接:https://coder.com/ 6.Charts.csscss 数据可视化框架,链接:https://chartscss.org/ 7.Counter 简单并且免费的网络分析,链接:https://counter.dev/ 8.React Query 在React和ReactNative应用程序中获取、缓存和更新数据,并且不涉及任何全局状态,链接:https://react-query.tanstack.com/ 9.vscode.dev 将VS Code引入浏览器,链接:https://vscode.dev/ 10.BookStack 一个开源的wiki平台,Confluence的替代品,链接:https://www.bookstackapp.com/ 11.ThunderClient VSCode的RestAPI客户端,轻量级的Postman替代方案,链接:https://www.thunderclient.com/ 12.Quod AI 更快的找到你需要的代码,链接:https://www.quod.ai/ 13.Dendron 在VS Code上的快速开源笔记,链接:https://wiki.dendron.so/ 14.Notion API 把概念和你每天使用的工具联系起来,链接:https://developers.notion.com/ 15.Github1s 1秒钟就能用VS Code读取GitHub代码,链接:https://github.com/conwnet/github1s 16.Ocean 容器的无服务器基础架构引擎,链接:https://spot.io/products/ocean/ 17.Magic 快速构建应用程序,可定制,无密码登录,链接:https://magic.link/… Continue reading 2021年最受程序员欢迎的开发工具TOP 100名单出炉!
[译]C++ 协程:理解 co_await 运算符
原文地址:C++ Coroutines: Understanding operator co_await 原文作者:lewissbaker 译文出自:掘金翻译计划 本文永久链接:github.com/xitu/gold-m… 译者:7Ethan 校对者:razertory,noahziheng C++ 协程:理解 co_await 运算符 在之前关于 协程理论的博客 中,我介绍了一些函数和协程在较高层次上的一些不同,但没有详细介绍 C++ 协程技术规范(N4680)中描述的语法和语义。 协程技术规范中,C++ 新增的关键新功能是能够挂起协程,并能够在之后恢复。技术规范为此提供的机制是通过新的 co_await 运算符去实现。 理解 co_await 运算符的工作原理可以帮助我们揭开协程行为的神秘面纱,并了解它们如何被暂停和挂起的。在这篇文章中,我将解释 co_await 操作符的机制,并介绍 Awaitable 和 Awaiter 类型的相关概念。 在深入讲解 co_await 之前,我想简要介绍一下协程的技术规范,以提供一些背景知识。 协程技术规范给我们提供了什么? 三个新的关键字: co_await, co_yield 和 co_return std::experimental 命名空间的几个新类型: coroutine_handle<P> coroutine_traits<Ts…> suspend_always suspend_never 一种能够让库的作者与协程交互并定制它们行为的通用机制。 一个使异步代码变得更加简单的语言工具! C++ 协程技术规范在语言中提供的工具,可以理解为协程的低级汇编语言。 这些工具很难直接以安全的方式使用,主要是供库作者使用,用于构建应用程序开发人员可以安全使用的更高级别的抽象。 未来会将这些新的低级工具交付给即将到来的语言标准(可能是 C++20),以及标准库中伴随的一些高级类型,这些高级类型封装了这些低级构建块,应用程序开发人员将可以通过一种安全的方式轻松访问协程。 编译器与库的交互… Continue reading [译]C++ 协程:理解 co_await 运算符
协程的原理(Coroutine Theory)
原文链接:https://lewissbaker.github.io/2017/09/25/coroutine-theory This is the first of a series of posts on the C++ Coroutines TS, a new language feature that is currently on track for inclusion into the C++20 language standard. 这是C++ Cooutines TS系列文章中的第一篇,这是一种新的语言特性,目前正准备纳入C++20语言标准。 In this series I will cover how the underlying mechanics of C++ Coroutines work as well as show how they can… Continue reading 协程的原理(Coroutine Theory)
搞懂异地多活,看这篇就够了
阅读本文大约需要 20 分钟。 你好,我是 Kaito。 在软件开发领域,「异地多活」是分布式系统架构设计的一座高峰,很多人经常听过它,但很少人理解其中的原理。 异地多活到底是什么?为什么需要异地多活?它到底解决了什么问题?究竟是怎么解决的? 这些疑问,想必是每个程序看到异地多活这个名词时,都想要搞明白的问题。 有幸,我曾经深度参与过一个中等互联网公司,建设异地多活系统的设计与实施过程。所以今天,我就来和你聊一聊异地多活背后的的实现原理。 认真读完这篇文章,我相信你会对异地多活架构,有更加深刻的理解。 这篇文章干货很多,希望你可以耐心读完。 01 系统可用性 要想理解异地多活,我们需要从架构设计的原则说起。 现如今,我们开发一个软件系统,对其要求越来越高,如果你了解一些「架构设计」的要求,就知道一个好的软件架构应该遵循以下 3 个原则: 高性能 高可用 易扩展 其中,高性能意味着系统拥有更大流量的处理能力,更低的响应延迟。例如 1 秒可处理 10W 并发请求,接口响应时间 5 ms 等等。 易扩展表示系统在迭代新功能时,能以最小的代价去扩展,系统遇到流量压力时,可以在不改动代码的前提下,去扩容系统。 而「高可用」这个概念,看起来很抽象,怎么理解它呢?通常用 2 个指标来衡量: 平均故障间隔 MTBF(Mean Time Between Failure):表示两次故障的间隔时间,也就是系统「正常运行」的平均时间,这个时间越长,说明系统稳定性越高 故障恢复时间 MTTR(Mean Time To Repair):表示系统发生故障后「恢复的时间」,这个值越小,故障对用户的影响越小 可用性与这两者的关系: 可用性(Availability)= MTBF / (MTBF + MTTR) * 100% 这个公式得出的结果是一个「比例」,通常我们会用「N 个 9」来描述一个系统的可用性。 从这张图你可以看到,要想达到… Continue reading 搞懂异地多活,看这篇就够了
MySQL 不走索引的一种情况
这周收到一个 sentry 报警,如下 SQL 查询超时了。 select * from order_info where uid = 5837661 order by id asc limit 1 执行show create table order_info 发现这个表其实是有加索引的 CREATE TABLE `order_info` ( `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, `uid` int(11) unsigned, `order_status` tinyint(3) DEFAULT NULL, … 省略其它字段和索引 PRIMARY KEY (`id`), KEY `idx_uid_stat` (`uid`,`order_status`), ) ENGINE=InnoDB DEFAULT CHARSET=utf8 理论上执行上述 SQL 会命中 idx_uid_stat 这个索引,但实际执行 explain 查看 explain select * from order_info where uid = 5837661 order by id asc limit 1 可以看到它的 possible_keys(此 SQL 可能涉及到的索引) 是 idx_uid_stat,但实际上(key)用的却是全表扫描 我们知道 MySQL 是基于成本来选择是基于全表扫描还是选择某个索引来执行最终的执行计划的,所以看起来是全表扫描的成本小于基于 idx_uid_stat 索引执行的成本,不过我的第一感觉很奇怪,这条 SQL 虽然是回表,但它的 limit 是 1,也就是说只选择了满足 uid = 5837661 中的其中一条语句,就算回表也只回一条记录,这种成本几乎可以忽略不计,优化器怎么会选择全表扫描呢。 为了查看 MySQL 优化器为啥选择了全表扫描,我打开了 optimizer_trace 来一探究竟 画外音:在MySQL 5.6 及之后的版本中,我们可以使用 optimizer… Continue reading MySQL 不走索引的一种情况
57张图,13个实验,干死 MySQL 锁!
你好,我是yes。 前段时间写了一篇关于 MySQL 锁的文章,一些小伙伴们在阅读之后产生了一些疑问,这些问题还挺有代表性的,所以在这里做个实验,来用事实探究一番。 那篇文章提到了记录锁(Record Locks),顾名思义锁的是记录,作用在索引上的记录。 锁是作用在索引上这句话可能不太好理解,并且对于在可重复读和读提交两个隔离级别下,关于是否命中二级索引的锁之间的阻塞也不太清晰。 这句话读着可能有点拗口,没事,我来给你看几个实验,对这一切就异常清晰了。 实验的 MySQL 版本为:5.7.26。 实验一:隔离级别为读提交,锁定非索引列的实验 先建个非常简单的表,只有主键索引,没有二级索引。 CREATE TABLE `yes` ( `id` bigint(20) NOT NULL AUTO_INCREMENT, `name` varchar(45) DEFAULT NULL, `address` varchar(45) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 隔离级别如下: 关闭自动提交事务: 已经准备好的数据: 此时,发起事务 A,执行如下语句,且事务未提交: 接着,再发起事务 B,执行如下语句: 你可能以为事务 B 不会被阻塞,因为事务 B 锁的是name=xx和事务A锁name=yes讲道理相互之间没有冲突,但是从结果来看,事务 B 被阻塞了,调用select * from innodb_lock_waits;看下谁等谁 可以看到,事务6517(B)在等待事务6516(A)。 此时,调用 SELECT * FROM innodb_locks; 查看相关锁的信息 锁的类型就是行级锁,此时的锁为 X 锁,锁的索引就是主键索引,这个结果表明的意思是事务 B(6517)想要 id 为 1 的记录锁,但是这个记录此时被事务A(6516)占有。 是的,这里的 1 其实不是指第一个记录的意思,是 id… Continue reading 57张图,13个实验,干死 MySQL 锁!
一个MySQL锁和面试官大战三十回合,我霸中霸!
我,小Y。 又来面试了,还是之前那家公司,即将和之前那个老面试官进行第二次 battle,心情还是xue微有点忐忑。 没看过第一次 battle 的同学可以看这里,一个MVCC和面试官大战三十回合 又一抹光亮闪过,面试官推门而入,我抬头望去,没错,还是那味儿。 看到面试官头上那“傲然矗立”的头发,差点又想站起来给他敬了个礼,算了先稳住,低调一点。 面试官瞥了我一眼:来吧,咱们继续面试,上次没办法,女朋友就是粘人,这次问 MySQL InnoDB 的锁喔。 我:…..(行,我知道你有女朋友了),好的面试官,您请。 面试官:MySQL InnoDB 的锁 和 MyISAM 的锁有什么区别? 我:MyISAM 只支持表锁,一锁就锁整张表,而 InnoDB 不仅支持表锁,还支持粒度更低的行锁,仅对相关的记录上锁即可,所以对于写入操作来说 InnoDB 的性能更高。 面试官:那不论表锁还是行锁,其实有分为两类的,你知道是哪两类吗? 我:你指的是 shared (S) locks 和 exclusive (X) locks 吗? S锁,称为共享锁,事务在读取记录的时候获取 S 锁,它允许多个事务同时获取 S 锁,互相之间不会冲突。 X锁,称为独占锁,事务在修改记录的时候获取 X 锁,且只允许一个事务获取 X 锁,其它事务需要阻塞等待。 所以 S 锁之间不冲突,X 锁则为独占锁,所以 X 之间会冲突, X 和 S 也会冲突。… Continue reading 一个MySQL锁和面试官大战三十回合,我霸中霸!
关于MySQL的酸与MVCC和面试官小战三十回合
我,小Y。 此刻,正坐在办公室里等待面试,心情xue微有点忐忑,不知道待会儿老面试官经不经得住我的折磨。 只见一抹光亮闪过,面试官推门而入,我抬头望去,强者的气息铺面而来,没错是那味儿。 看到面试官头上那“傲然矗立”的头发,脑海中止不住幻想他在无数个凌晨于电脑前挑灯夜码的高大形象,一种敬佩感油然而生, 竟忍不住站起来给他敬了个礼。 面试官:有病? 我:没没没,我谢顶反应综合征犯了,面试官好,我是小 Y ,请多多指教。 面试官:哦哦,确实是有病啊,没事,记得吃药就行。我看你简历写你 MySQL 挺懂的,那我先问问你 MySQL 吧。 我:好嘞,您请。 面试官:你知道什么是 MySQL 的酸吗? 这一来就这么猛的吗?脑海中一顿搜索,只能想起张含韵的我喜欢酸的甜这就是真的我之《酸酸甜甜就是我》,算了蒙一个。 我:事务? 面试官:哟,最近好多谐音梗,我特意玩了个英语单词短语梗,脑子转的挺快啊小伙子。 酸,英文 acid,说的就是事务!这都蒙对了,等下就去买彩票!趁这个机会再表现一下! 我:是啊,国外的人就有拼凑单词的习惯,其实事务主要是为了实现 C ,也就是一致性,具体是通过AID,即原子性、隔离性和持久性来达到一致性的目的,所以这四个不应该相提并论,但是他们就想拼成单词,就把它们排好序搞在一起来念。 嘿嘿,这个B装的我有点舒服,果然面试官有点惊讶。 面试官:可以呀,那你知道 MVCC 吧? 我:知道,Multi-Version Concurrency Control (多版本并发控制)。 面试官:能先简短的解释下什么是 MVCC 吗? 我:多版本并发控制,其实指的是一条记录会有多个版本,每次修改记录都会存储这条记录被修改之前的版本,多版本之间串联起来就形成了一条版本链。 这样不同时刻启动的事务可以无锁地获得不同版本的数据(普通读)。此时读(普通读)写操作不会阻塞,写操作可以继续写,无非就是多加了一个版本,历史版本记录可供已经启动的事务读取。 (为保持简短,简化了SQL语句,下文也同样简化) 面试官:那你知道事务四种隔离级别吧? 我:读未提交、读已提交、可重复读、可串行化。 面试官:MVCC 用来实现哪几个隔离级别? 我:用来实现读已提交和可重复读。首先隔离级别如果是读未提交的话,直接读最新版本的数据就行了,压根就不需要保存以前的版本。可串行化隔离级别事务都串行执行了,所以也不需要多版本,因此 MVCC 是用来实现读已提交和可重复读的。 面试官:那为什么需要 MVCC ?如果没有 MVCC 会怎样? 我:如果没有 MVCC 读写操作之间就会冲突。想象一下有一个事务1正在执行,此时一个事务2修改了记录A,还未提交,此时事务1要读取记录A,因为事务2还未提交,所以事务1无法读取最新的记录A,不然就是发生脏读的情况,所以应该读记录A被事务2修改之前的数据,但是记录A已经被事务2改了呀,所以事务1咋办?只能用锁阻塞等待事务2的提交,这种实现叫… Continue reading 关于MySQL的酸与MVCC和面试官小战三十回合
值得收藏,揭秘 MySQL 多版本并发控制实现原理
▲ 点击上方“架构精进之路”关注公众号 回复“01”领取「程序员进阶大礼包」 架构精进之路 十年研发风雨路,大厂架构师,CSDN博客专家。专注软件架构研究,技术学习与职业成长,坚持分享接地气儿的架构技术干货文章! 78篇原创内容 公众号 这是「架构精进之路」公众号的第73篇原创文章 MySQL 中多版本并发控制(MVCC),是现代数据库引擎实现中常用的处理读写冲突的手段,MVCC 作为 MySQL 高级应用特性,目的在于提高数据库高并发场景下的吞吐性能。 一、MVCC出现背景是什么? 事务的4个隔离级别以及对应的3种异常: 脏读:一个事务读取到了另外一个事务没有提交的数据; 不可重复读:在同一事务中,两次读取同一数据,得到内容不同; 幻读:同一事务中,用同样的操作读取两次,得到的记录数不相同。 在 MySQL 中,默认的隔离级别是可重复读,可以解决脏读和不可重复读的问题,但不能解决幻读问题。如果我们想要解决幻读问题,就需要采用串行化的方式,也就是将隔离级别提升到最高,但这样一来就会大幅降低数据库的事务并发能力。 而MVCC就是通过乐观锁的方式来解决不可重复读和幻读问题,它可以在大多数情况下替代行级锁,降低系统的开销。 MySQL 并发事务会引起更新丢失问题,解决办法是锁,主要分两类: 乐观锁: 其实现如同它的名字一样,是假设比较好的情况。 每次取数据的时候都认为他人不会对其修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,可以使用版本号机制和CAS算法实现。 悲观锁: 悲观锁也如同它的名字一样,总是假设比较坏的情况,每次取数据的时候都认为他人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会阻塞直到它拿到锁(共享资源每次只给一个线程使用,其它线程阻塞,用完后再把资源转让给其它线程)。 二、什么是MVCC,它解决了什么问题? MVCC 是通过数据行的多个版本管理来实现数据库的并发控制,简单来说它的思想就是保存数据的历史版本。 我们可以通过比较版本号决定数据是否显示出来(具体的规则后面会介绍到),读取数据的时候不需要加锁也可以保证事务的隔离效果。 通过 MVCC 我们可以解决以下几个问题: (1)读写之间阻塞的问题,通过 MVCC 可以让读写互相不阻塞,即读不阻塞写,写不阻塞读,这样就可以提升事务并发处理能力。 (2)降低了死锁的概率。这是因为 MVCC 采用了乐观锁的方式,读取数据时并不需要加锁,对于写操作,也只锁定必要的行。 (3)解决一致性读的问题。一致性读也被称为快照读,当我们查询数据库在某个时间点的快照时,只能看到这个时间点之前事务提交更新的结果,而不能看到这个时间点之后事务提交的更新结果。 解释一下可能难以理解的几个词汇: 快照读: 读取的是快照数据,不加锁的简单的SELECT都属于快照读(只是普通的读操作)。 当前读: 当前读就是读取最新数据,而不是历史版本的数据。 加锁的SELECT,或者对数据进行增删改都会进行当前读(包括加锁的读取和DML操作)。 三、应用举例分析 为了更好地让大家理解MVCC,我们用一个示例场景来说明。 假设有个账户金额表 user_balance,包括三个字段,分别是 username… Continue reading 值得收藏,揭秘 MySQL 多版本并发控制实现原理
IPV4中TCP内核参数
参照debian系统,查看的tcp相关配置 # 全连接队列满了,新来的连接发送rst, 1表示开启 net.ipv4.tcp_abort_on_overflow = 0 # 接受缓冲区1/2^n用来接受缓冲,换句话来说,接收窗口不表示接受buffer的大小 net.ipv4.tcp_adv_win_scale = 1 # 拥塞算法 net.ipv4.tcp_allowed_congestion_control = reno cubic net.ipv4.tcp_app_win = 31 # 自动开启crok选项 net.ipv4.tcp_autocorking = 1 net.ipv4.tcp_available_congestion_control = reno cubic net.ipv4.tcp_available_ulp = net.ipv4.tcp_base_mss = 1024 net.ipv4.tcp_challenge_ack_limit = 1000 net.ipv4.tcp_comp_sack_delay_ns = 1000000 net.ipv4.tcp_comp_sack_nr = 44 net.ipv4.tcp_congestion_control = cubic net.ipv4.tcp_dsack = 1 net.ipv4.tcp_early_demux =… Continue reading IPV4中TCP内核参数