一些可以参考的文档集合4

16 篇文章 0 订阅
15 篇文章 0 订阅

20220523

 

RabbitMQ 的五种消息模型_RabbitMQ_Ayue、_InfoQ写作社区RabbitMQ 提供了 6 种消息模型,但常用的是前面 5 种,第 6 种实际上为RPC,所以一般来说了解前面 5 种即可,而对于后面三种,是根据 Exchange 类型划分的。注:对下面模式的讲解https://xie.infoq.cn/article/f0cb0dc4d0e252e4573348ba2

20220520

如何基于 WebComponents 封装 UI 组件库近些年来前端组件化开发已为常态。但是都有一个缺点离不开框架本身,因为我们浏览器本身解析不了那些组件。那么有没有一种技术也可以达到这种效果呢?答案就是今天的主角 Web Components。https://mp.weixin.qq.com/s/UTGADsfmJXSg5zGik4Rb5g

日志处理

基于Clickhouse的下一代日志系统技术揭秘唯品会日志系统dragonfly 1.0基于EFK构建,随着公司的业务发展,日志应用场景逐渐遇到了一些瓶颈,ELK的架构的缺点显现,鉴于出现的问题,我们开始探索新的日志系统架构,该文章揭秘唯品会现用的基于clickhouse的日志系统技术。https://mp.weixin.qq.com/s/d2PbeLesLXKLldr4PgMy_g

一个数学公式编辑器,可以在线编辑

CortexJShttps://cortexjs.io/mathlive/

Regular Expression Tester and VisualizerRegular Expression Tester and Visualizer is a free online developer tool to test and visualize a regular expression against any string instantly with matches highlighted including a cheat sheet and reference.https://devtoolcafe.com/tools/regex#!flags=img&re=

23种设计模式

The Catalog of Design Patternshttps://refactoring.guru/design-patterns/catalog

我们的最佳实践是在一个 RUN 命令中执行更新、安装和清理操作:

RUN apt-get update && \  apt-get install -y libgirepository1.0-dev libpoppler-glib-dev && \  rm -rf /var/lib/apt/lists/*

如何使用本地Docker更好地开发?我们总结了这八条经验_语言 & 开发_David Eisinger_InfoQ精选文章如何使用本地Docker更好地开发?我们总结了这八条经验 如果你像我们一样需要运行许多不同的应用程序,那么将开发环境容器化可以极大地提高工作效率。这里有一些https://www.infoq.cn/article/Tp6424LoNHowwzLXDGLe

令人头疼的分布式事务,一次讲明白!-51CTO.COM分布式事务框架,在这些理论基础上,都进行了或多或少的修订,也有不少创新。https://developer.51cto.com/article/709407.html

一次性聊透JVM架构设计,就算八股文也得会-51CTO.COMJVM(Java Virtual Machine)其实是一套标准。通过定义虚拟机,像真实计算机一样,能够运行字节码指令。JVM的好处是可以屏蔽操作系统的细节, 使Java可以一次编写,到处运行。https://developer.51cto.com/article/709375.html

20220517

堆排序是一种选择排序,它的最坏,最好,平均时间复杂度为O(nlogn),它也是不稳定排序。

堆排序基本思想

(1)将待排序序列构造成一个大顶堆

(2)此时,整个序列的最大值就是堆顶的根节点。

(3)将其与末尾元素进行交换,此时末尾就为最大值。

(4)然后将剩余n-1个元素重新构造成一个堆,这样会得到n个元素的次小值。如此反复执行,便能得到一个有序序列了。

可以看到在构建大顶堆的过程中,元素的个数逐渐减少,最后就得到一个有序序列了。

堆排序概要1.堆排序基本介绍(1)堆排序是利用堆这种数据结构而设计的一种排序算法,堆排序是一种选择排序,它的最坏,https://mp.weixin.qq.com/s/DJvjgEF4tjIm878a-ZJ39w

实战 MySQL 高可用架构-51CTO.COM对于 MySQL 数据库作为各个业务系统的存储介质,在系统中承担着非常重要的职责,如果数据库崩了,那么对于读和写数据库的操作都会受到影响。https://www.51cto.com/article/709186.html

20220513

时序数据特征:

 

Comparing with BTree and HashTable:

  • skiplist和各种平衡树(如AVL、红黑树等)的元素是有序排列的,而哈希表不是有序的。因此,在哈希表上只能做单个key的查找,不适宜做范围查找。 所谓范围查找,指的是查找那些大小在指定的两个值之间的所有节点
  • 在做范围查找的时候,平衡树比skiplist操作要复杂。在平衡树上,我们找到指定范围的小值之后,还需要以中序遍历的顺序继续寻找其它不超过大值的节点。如果不对平衡树进行一定的改造,这里的中序遍历并不容易实现。而在skiplist上进行范围查找就非常简单,只需要在找到小值之后,对第1层链表进行若干步的遍历就可以实现
  • 平衡树的插入和删除操作可能引发子树的调整,逻辑复杂,而skiplist的插入和删除只需要修改相邻节点的指针,操作简单又快速
  • 从内存占用上来说,skiplist比平衡树更灵活一些。一般来说,平衡树每个节点包含2个指针(分别指向左右子树),而skiplist每个节点包含的指针数目平均为1/(1-p),具体取决于参数p的大小。如果像Redis里的实现一样,取p=1/4,那么平均每个节点包含1.33个指针,比平衡树更有优势
  • 查找单个key,skiplist和平衡树的时间复杂度都为O(log n),大体相当;而哈希表在保持较低的哈希值冲突概率的前提下,查找时间复杂度接近O(1),性能更高一些。所以我们平常使用的各种Map或dictionary结构,大都是基于哈希表实现的
  • 从算法实现难度上来比较,skiplist比平衡树要简单得多
  • 跳表和红黑树的插入、删除、查找效率都是O(logN),都可以顺序遍历所有元素(红黑树通过中序遍历)。红黑树更稳定一些,跳表恶化是存在概率的,虽然概率极低。
  • 跳表实现简单,但是浪费了很多空间。红黑树实现麻烦,但是没有使用额外的空间
  • 跳表区间查找很方便,redis中的zset实现区间查找就是用的跳表

插入

在这里插入图片描述

查找

在这里插入图片描述

SkipList(跳跃表)详解_才不是本人的博客-CSDN博客_skiplistIntroduction:skiplist本质上也是一种查找结构,用于解决算法中的查找问题(Searching),即根据给定的key,快速查到它所在的位置(或者对应的value)一般用于解决查找问题的数据结构分为两个大类:一个是基于各种平衡树,一个是基于哈希表。但skiplist却比较特殊,它没法归属到这两大类里面这种数据结构是由William Pugh发明的,最早出现于他在1990年发表的...https://blog.csdn.net/helloworld_ptt/article/details/105801262

 用 gdb 学 C 语言 - 知乎我写作本文的目的是,是向大家展示 gdb 这一学习 C 语言的强大工具。我将介绍一些我最常用的 gdb 命令,同时还将会演示如何用 gdb 来理解 C 语言中最令人头疼的内容:指针和数组的区别。 gdb 简介我们用这个 minim…https://zhuanlan.zhihu.com/p/483372519

浏览器二维码API

Barcode Detection API - Web APIs | MDNThe Barcode Detection API detects linear and two-dimensional barcodes in images.https://developer.mozilla.org/en-US/docs/Web/API/Barcode_Detection_API

20220512

PostgreSQL部署|基于Stream复制的手工主从切换https://mp.weixin.qq.com/s/CSkS1RvZ_MTq_3C5h_h08w

PostgreSQL部署|基于Stream复制的高可用部署https://mp.weixin.qq.com/s/5SJHeZ_YBa-JGNZbnJAX8Q

10年了,软件架构是如何一步步演进的? - 文章详情概述本文以淘宝作为例子,介绍从一百个到千万级并发情况下服务端的架构的演进过程,同时列举出每个演进阶段会遇到的相关技术,让大家对架构的演进有一个整体的认知,文章最后汇总了一些架构https://z.itpub.net/article/detail/DA93C7DCAF3D1A7324395085FC666326

设计一个支持百万用户的系统设计一个支持数百万用户的系统是非常有挑战性的, 这是一个需要不断调整和优化的过程, 接下来的内容中, 我将构建一个系统, 从单个用户开始,到最后支持数百万的用户。https://mp.weixin.qq.com/s/9ALlcAU8460OhMV2-m0Azw

数据中心机房建设都有哪些内容?IDC数据中心机房建设工程不仅仅是一个装饰工程,更重要的是一个集电工学、电子学、建筑装饰学、美学、暖通净化专https://mp.weixin.qq.com/s/6RmZIKop5O5JKoYMwoKxtQ

大型云计算数据中心机房规划设计方案获取以下系统设计方案、报价清单、CAD设计图纸等资料请加入微信社群资料导航:1、视频监控系统2、楼宇对讲系统https://mp.weixin.qq.com/s/yUb-S_sm19D0UaVKjIXW6w

1┃音视频直播系统之浏览器中通过WebRTC访问摄像头_音视频_autofelix_InfoQ写作社区一、WebRTC的由来对于前端开发小伙伴而言,如果用 JavaScript 做音视频处理在以前是不可想象的,因为首先就要考虑浏览器的性能是否跟得上音视频的采集但是 Google 作为国际顶尖科技公司,https://xie.infoq.cn/article/460f04cdfab4db1221f737acd

20220511

 面试官:SpringBoot 项目鉴权的 4 种方式说下前言\x0d\x0a传统AOP\x0d\x0a实现\x0d\x0a扩展\x0d\x0aInterceptor\x0d\x0a实现\x0d\x0a扩展\x0d\x0aArgumentResolver\x0d\x0a实现\x0d\x0a扩展\x0d\x0aFilter\x0d\x0a扩展\x0d\x0a小结https://mp.weixin.qq.com/s/NUIlWhDS7vt5RFWrqbk23g

@RestController
public class HelloController {
    @GetMapping("/hello")
    public String hello(@CurrentUserName String name) {
        return "hello "+name;
    }
}

手把手教你在 SpringBoot 中自定义参数解析器https://mp.weixin.qq.com/s/mbstcEEtwOS9ZRSSjusbfA

20220510


 

在 OpenGL 中,设置好顶点数据,设置好着色器,调用 drawcall 函数,3D 图形就被绘制出来了。

那么在这背后,GPU 做了什么工作呢?其实,从输入的顶点 3D 信息,到输出每个像素点的颜色信息,中间经过了很多步操作。这些操作按照一定的顺序构成了一条图形流水线(Graphics Pipeline),或者叫渲染管线。每个步骤的输入都依赖于前一步骤输出的结果。其中的步骤包括顶点处理(vertex processing)、图元装配(triangle assembly)、光栅化(rasterization)、片段处理(fragment processing)、测试和混合(testing and blending)几个关键步骤。

图片来源:https://graphicscompendium.com/intro/01-graphics-pipeline

在这里插入图片描述

开始: Application: Input-vertices in 3D space 物体在空间中的表示为一堆点和它的连接关系
1 Vertex Processing: Vertex Stream - Vertices positioned in screen space
顶点处理,经过一系列的变换,三维空间的点 最终变换成屏幕上的点
2 Triangle Processing: Tringle Stream - Triangles postioned in screen space
三角网处理:它们之前的连接关系并没有改变,变换后的点仍然会表示三角形,只不过这些三角形投影到屏幕中去了。
3 Rasterization: Fragment Stream - Fragments (one per covered sample)
光栅化,把原本一个连续表示的三角形,三个点连起来,把它给离散化成屏幕空间上的一堆像素,当然不一定是像素,如果用了一些msaa或者其它一些抗锯齿什么的,这些一个一个的基本的微元(片段,对应directX中就称之为像素),我们有一系列的三角形需要把它打散成像素,那么打散成像素,其过程中涉及一些遮挡的处理。
4 Fragment Processing: Shaded Fragments - Shaded fragments
对任何的Fragment做着色,就是去计算它应该长什么样子,比如说Blinn-Phong着色模型
5 FrameBuffer Operations
帧缓存操作
结束: Display: Output - image (pixels)
 

如何理解 OpenGL 中着色器、渲染管线、光栅化等概念? - 知乎这道题我们邀请了旷视科技的师宁远同学来回答~在 OpenGL 中,设置好顶点数据,设置好着色器,调用 drawca…https://www.zhihu.com/question/29163054/answer/2298413553?utm_source=wechatMessage_undefined_bottom

 线程数是有限制的,有限的线程数导致无法实现上万级别的并发连接,过多的线程切换也抢走了 CPU 的时间,从而降低了每秒能够处理的请求数量

于是为了达到高并发,你可能会选择一个异步框架,用非阻塞 API 把业务逻辑打乱到多个回调函数中,通过多路复用实现高并发。但此时就要求业务代码过度关注并发细节,需要维护很多中间状态,一旦代码逻辑出现错误就会陷入回调地狱。

因此这么做不但 Bug 率会很高,项目的开发速度也上不去,产品及时上线存在风险。如果想兼顾开发效率,又能保证高并发,协程就是最好的选择。它可以在保持异步化运行机制的同时,还能用同步的方式写代码,这既实现了高并发,又缩短了开发周期,是高性能服务未来的发展方向。

这里我们必须要指出,在并发量方面,使用「协程」的方式并不优于「非阻塞+回调」的方式,而我们之所以选择协程是因为它的编程模型更简单,类似于同步,也就是可以让我们使用同步的方式编写异步的代码。「非阻塞+回调」这种方式非常考验编程技巧,一旦出现错误,不好定位问题,容易陷入回调地狱、栈撕裂等困境。

I/O 多路复用机制是指一个线程处理多个 IO 流

为什么要有协程,协程是如何实现的?高并发的解决方案https://mp.weixin.qq.com/s/UF_lkPKPkEVwzTk0ermung

终于懂了:协程思想的起源与发展协程概念比线程概念更早出现https://mp.weixin.qq.com/s/Wy-_J9TlU3aSAJt24ZT5hw

因为这两者根本不是同一种东西。

协程是一边吃饭一边说话。

线程是一边听音乐一边写作业。

协程其本身是串行的。在任何一个时刻,同属于一个组当中的协程,只有一个协程在跑。即便你的cpu是多核的,如果不另外开多个工作线程去跑协程,那么无论你多少个协程,它们都跑在同一个核心上。

而线程,至少在概念上是完全同时的、并行的。在很久以前,当cpu只有一个核心的时候,它们的确最终也只能以类似协程的方式时分复用核心,但是在如今,它们是在多个核心上同时跑的。

所以,除了你所提到的那些之外,最大的开销在于协程是自主让渡执行时间,而且都跑在一个核心上,不需要复杂的调度算法,不需要优先级管理;而线程,其自身不让渡核心时间,还有优先级。操作系统要像指挥交通那样去指挥,所以耗时。


 

为什么协程切换的代价比线程切换低? - 知乎因为这两者根本不是同一种东西。协程是一边吃饭一边说话。线程是一边听音乐一边写作业。协程其本身是串行…https://www.zhihu.com/question/308641794/answer/571632526?utm_source=wechatMessage_undefined_bottom

volatile 能够确保一定的有序性,例如:

//这里 x、y 为非 volatile 变量
//而 flag 为 volatile 变量
x = 2;         //语句1
y = 0;         //语句2
flag = true;   //语句3
x = 4;         //语句4
y = -1;        //语句5

由于 flag 是 volatile 变量,确保了:指令 1、2 一定在语句 3 之前执行,语句 4、5 一定在语句 3 后面执行。但是 volatile 并不会确保语句 1、2 之间不进行指令重排序,语句 4、5 之间不进行指令重排序。

理解指令重排序的例子是 doule check lock(DCL)单例模式,如下所示:

public class Student {
      ...
      private static volatile Student student;
      //double check null
      public static Student getStudent() {
          if (student == null) {
              synchronized (Student.class) {
                  if (student == null) {
                      student = new Student("hello world",12);
                  }
              }
          }
          return student;
      }
     ...
  }
​

单例模式通常会要求单例字段被 volatile 修饰,这是因为 new 一个实例实际上分为三步非原子操作来完成:

memory=allocate(); //1:分配内存空间
ctorInstance();   //2:初始化对象
singleton=memory; //3:设置singleton指向刚排序的内存空间

CPU 会对上述三个操作进行指令重排序:

  • 内存分配一定要第一步执行,否则会影响语义,因此 CPU 不会对其进行指令重排;
  • 初始化对象以及设置 singleton 指向刚申请的内存空间可能会被指令重排,因为在单线程模型下这两步即使倒过来做,也没有影响。

如果单例字段不使用 volatile 修饰,那么在并发环境下就会遇到这样的问题:线程 1 先给 student 赋值上没有初始化完成的 Student 类实例。线程 2 通过单例方法得到了该实例,在调用相关方法时却发现字段尚未初始化,最终抛出了异常。

使用 volatile 修饰单例字段就能够避免上述并发安全问题,为什么?

这是因为 new 操作对应的第三步实际上是给 volatile 字段赋值,它会要求第二步必须在其之前就已经运行完毕,这就能够避免因为指令重排序而导致的单例提前暴露。

Go 没有 volatile 关键字 - 知乎Java/C++ 程序员们在写 Go 程序时,也许会有如下的疑问,为什么 Go 没有 volatile 关键字。 本文会试图帮助我们理解如下两个问题: Java 中的 volatile 有什么作用Go 为什么没有 volatile,如何在 Go 中等效实现 J…https://zhuanlan.zhihu.com/p/473178019?utm_source=wechatMessage_undefined_bottom


 

20220509

NIO 相对于 BIO 最大的改进就是使用了多路复用技术,用少量线程处理大量客户端 IO 请求,因为IO 请求等待时间相对较长,一个线程则可以同时处理多个就绪的IO.

原来你是这样的 IO 模型-51CTO.COM在网络通信中,客户端和服务端通过一个双向的通信连接实现数据的交换,连接的任意一端都可称为一个 Socket。https://developer.51cto.com/article/708374.html

20220507

实现泛型的两种最常见方式:

虚拟方法表

在编译器中实现泛型的一种方法是使用 Virtual Method Table。泛型函数被修改成只接受指针作为参数的方式。然后,这些值被分配到堆上,这些值的指针被传递给泛型函数。这样做是因为指针看起来总是一样的,不管它指向的是什么类型。

如果这些值是对象,而泛型函数需要调用这些对象的方法,它就不能再这样做了。该函数只有一个指向对象的指针,不知道它们的方法在哪里。因此,它需要一个可以查询方法的内存地址的表格:Virtual Method Table。这种所谓的动态调度已经被 Go 和 Java 等语言中的接口所使用。

Virtual Method Table 不仅可以用来实现泛型,还可以用来实现其他类型的多态性。然而,推导这些指针和调用虚拟函数要比直接调用函数慢,而且使用 Virtual Method Table 会阻止编译器进行优化

单态化

一个更简单的方法是单态化(Monomorphization),编译器为每个被调用的数据类型生成一个泛型函数的副本。

最大的优势是,Monomorphization 带来的运行时性能明显好于使用 Virtual Method Table。直接方法调用不仅更有效率,而且还能适用整个编译器的优化链。不过,这样做的代价是编译时长,为所有相关类型生成泛型函数的副本是非常耗时的。

Go 的实现

这两种方法中哪一种最适合 Go?快速编译很重要,但运行时性能也很重要。为了满足这些要求,Go 团队决定在实现泛型时混合两种方法。

Go 使用 Monomorphization,但试图减少需要生成的函数副本的数量。它不是为每个类型创建一个副本,而是为内存中的每个布局生成一个副本:int、float64、Node 和其他所谓的 "值类型" 在内存中看起来都不一样,因此泛型函数将为所有这些类型复制副本。

与值类型相反,指针和接口在内存中总是有相同的布局。编译器将为指针和接口的调用生成一个泛型函数的副本。就像 Virtual Method Table 一样,泛型函数接收指针,因此需要一个表来动态地查找方法地址。在 Go 实现中的字典与虚拟方法表的性能特点相同。

结论

这种混合方法的好处是,你在使用值类型的调用中获得了 Monomorphization 的性能优势,而只在使用指针或接口的调用中付出了 Virtual Method Table 的成本。

简单易懂的 Go 泛型使用和实现原理介绍-51CTO.COM本文是对泛型的基本思想及其在 Go 中的实现的一个比较容易理解的介绍,同时也是对围绕泛型的各种性能讨论的简单总结。https://developer.51cto.com/article/708128.html

React 首次成为头号 UI 框架,但如果我们考虑到 Vue.js 被分成了两个仓库(第二和第三版本),实际上 Vue.js 才是第一名。

最大的变化是 Svelte 的崛起,它超越 Angular 占据第三位。

越来越多的工具或组件将 Svelte 纳入目标框架中(例如我们提到的 Vite)。

Virtual DOM是纯开销

当前,Virtual DOM实现在计算新旧虚拟节点之间的差异时会产生计算成本。

即使使用非常有效的差分算法 (如list-diff2),当虚拟节点树大于虚拟节点的两位数时,差异成本也会变得显著。

树区分算法是出了名的慢。时间复杂度可以从O(n)转O(n ^ 3)取决于虚拟节点树的复杂性。这与DOM操纵相去甚远,后者是O(1)。

Virtual DOM的未来

编译器是新框架”-- 汤姆·戴尔

Ember的创建者汤姆是最早倡导为JavaScript UI库使用编译器开源狂热者之一。

现在,我们知道汤姆的赌注是正确的。JavaScript生态系统见证了Solid、Svelte等“已编译”库的兴起,它们放弃了Virtual DOM。这些库使用编译器预渲染,并在使用时生成代码来跳过不必要的渲染。

另一方面,Virtual DOM落后于这一趋势。当前的虚拟DOM库本质上与“按需” 编译器不兼容。因此,Virtual DOM的渲染速度通常是比现代“No Virtual DOM” UI库慢几个数量级。

如果我们希望Virtual DOM在未来的渲染速度上具有竞争力,那就需要重新设计Virtual DOM以允许编译器增强。

Virtual DOM的历史和未来-51CTO.COMVirtual DOM最初是由React的作者开创的,目的是使声明式UI的渲染速度更快。为了理解为什么声明式UI最初如此缓慢,我们首先需要了解过去是如何做声明式UI的。https://developer.51cto.com/article/708217.html

20220506

MySQL 8.0.28版本增强Instant DDL对列重命名的支持。

在Instant Add Column基础上实现列重命名较为简单直接。

快速DDL支持类型

  • Instant add column
    • 当一条alter语句中同时存在不支持instant的ddl时,则无法使用
    • 只能顺序加列
    • 不支持压缩表、不支持包含全文索引的表
    • 不支持临时表,临时表只能使用copy的方式执行DDL
    • 不支持那些在数据词典表空间中创建的表
  • 修改索引类型
  • 修改ENUM/SET类型的定义
    • 存储的大小不变时
    • 向后追加成员
  • 增加或删除类型为virtual的generated column
  • RENAME TABLE操作

MySQL · InnoDB · Instant DDL扩展概述http://mysql.taobao.org/monthly/2022/04/05/

MySQL · 引擎特性 · 8.0 Instant Add Column功能解析概述DDL(Data Definition Language)是数据库内部的对象进行创建、删除、修改的操作语言,主要包括:加减列、更改列类型、加减索引等类型。数据库的模式(schema)会随着业务的发展不断变化,如果没有高效的DDL功能,每一次变更都有可能影响业务,甚至产生故障。MySQL在8.0以前就已经支持O...http://mysql.taobao.org/monthly/2020/03/01/

前端文章写的不错

前端打包时 cjs、es、umd 模块有何不同 | 前端工程化三十八讲 | 大厂面试题每日一题每天至少一个前端面试题,并附以答案及讨论。有关前端,后端,graphql,devops,微服务以及软技能,促进个人职业成长,敲开大厂之门。每天五分钟,半年大厂中https://q.shanyue.tech/engineering/475.html

计算机网络实验

Jim Kurose Homepagehttps://gaia.cs.umass.edu/kurose_ross/wireshark.php

20220505

Spring Security 中的权限注解很神奇吗?https://mp.weixin.qq.com/s/TaPlws-ZLTDUnffuiw-r1Q

 ​​build​​ 命令之前提供 ​​GOOS​​ 和 ​​GOARCH​​ 这两个环境变量,来允许你构建针对不同硬件架构和操作系统的可执行文件。

GOOS=linux GOARCH=arm64 go build hello.go

查看底层汇编指令

源代码并不会直接转换为可执行文件,尽管它生成了一种中间汇编格式,然后最终被组装为可执行文件。在 Go 中,这被映射为一种中间汇编格式,而不是底层硬件汇编指令

要查看这个中间汇编格式,请在使用 ​​build​​ 命令时,提供 ​​-gcflags​​ 选项,后面跟着 ​​-S​​。这个命令将会显示使用到的汇编指令

复制

$ go build -gcflags="-S" hello.go
# command-line-arguments
"".main STEXT size=138 args=0x0 locals=0x58 funcid=0x0
        0x0000 00000 (/test/hello.go:5) TEXT    "".main(SB), ABIInternal, $88-0
        0x0000 00000 (/test/hello.go:5) MOVQ    (TLS), CX
        0x0009 00009 (/test/hello.go:5) CMPQ    SP, 16(CX)
        0x000d 00013 (/test/hello.go:5) PCDATA  $0, $-2
        0x000d 00013 (/test/hello.go:5) JLS     128

<< snip >>

你也可以使用 ​​objdump -s​​ 选项,来查看已经编译好的可执行程序的汇编指令,就像下面这样:

复制

$ ls
hello  hello.go

$ go tool objdump -s main.main hello
TEXT main.main(SB) /test/hello.go
  hello.go:5            0x4975a0                64488b0c25f8ffffff      MOVQ FS:0xfffffff8, CX                  
  hello.go:5            0x4975a9                483b6110                CMPQ 0x10(CX), SP                       
  hello.go:5            0x4975ad                7671                    JBE 0x497620                            
  hello.go:5            0x4975af                4883ec58                SUBQ $0x58, SP                          
  hello.go:6            0x4975d8                4889442448              MOVQ AX, 0x48(SP)                       

<< snip >>

我最喜欢的 Go 构建选项-51CTO.COM这些方便的 Go 构建选项可以帮助你更好地理解 Go 的编译过程。https://developer.51cto.com/article/707884.html

20220503

《对线面试官》 Java内存模型为什么存在? #12纯净版https://mp.weixin.qq.com/s/DnZElICmvVwt2-V8lmEo0w

MESI协议:是以缓存行(缓存的基本数据单位,在Intel的CPU上一般是64字节)的几个状态来命名的(全名是Modified、Exclusive、 Share or Invalid)。该协议要求在每个缓存行上维护两个状态位,使得每个数据单位可能处于M、E、S和I这四种状态之一,各种状态含义如下:

 M:被修改的。处于这一状态的数据,只在本CPU中有缓存数据,而其他CPU中没有。同时其状态相对于内存中的值来说,是已经被修改的,且没有更新到内存中。
E:独占的。处于这一状态的数据,只有在本CPU中有缓存,且其数据没有修改,即与内存中一致。
S:共享的。处于这一状态的数据在多个CPU中都有缓存,且与内存一致。
I:无效的。本CPU中的这份缓存已经无效。

一个处于M状态的缓存行,必须时刻监听所有试图读取该缓存行对应的主存地址的操作,如果监听到,则必须在此操作执行前把其缓存行中的数据写回内存。
一个处于S状态的缓存行,必须时刻监听使该缓存行无效或者独享该缓存行的请求,如果监听到,则必须把其缓存行状态设置为I。
一个处于E状态的缓存行,必须时刻监听其他试图读取该缓存行对应的主存地址的操作,如果监听到,则必须把其缓存行状态设置为S。

当CPU需要读取数据时,如果其缓存行的状态是I的,则需要从内存中读取,并把自己状态变成S,如果不是I,则可以直接读取缓存中的值,但在此之前,必须要等待其他CPU的监听结果,如其他CPU也有该数据的缓存且状态是M,则需要等待其把缓存更新到内存之后,再读取。

当CPU需要写数据时,只有在其缓存行是M或者E的时候才能执行,否则需要发出特殊的RFO指令(Read Or Ownership,这是一种总线事务),通知其他CPU置缓存无效(I),这种情况下性能开销是相对较大的。在写入完成后,修改其缓存状态为M。

所以如果一个变量在某段时间只被一个线程频繁地修改,则使用其内部缓存就完全可以办到,不涉及到总线事务,如果缓存一会被这个CPU独占、一会被那个CPU 独占,这时才会不断产生RFO指令影响到并发性能。这里说的缓存频繁被独占并不是指线程越多越容易触发,而是这里的CPU协调机制,这有点类似于有时多线程并不一定提高效率,原因是线程挂起、调度的开销比执行任务的开销还要大,这里的多CPU也是一样,如果在CPU间调度不合理,也会形成RFO指令的开销比任务开销还要大。当然,这不是编程者需要考虑的事,操作系统会有相应的内存地址的相关判断

先行发生(Happens-Before)是Java内存模型中定义的两项操作之间的偏序关系,比如说操作A先行发生于操作B,其实就是说在发生操作B之前,操作A产生的影响能被操作B观察到,“影响”包括修改了内存中共享变量的值、发送了消息、调用了方法等

Volatile如何保证线程可见性之总线锁、缓存一致性协议点击上方“猿芯”,选择“设为星标”后台回复\x26quot;1024\x26quot;,有份惊喜送给面试的你基础知识回顾下图给出了假想机的基https://mp.weixin.qq.com/s/Qg9qJpnuel6kTd-Tp7nWbQ

20220502

借助 SLF4J 中的 MDC 工具类,把操作人放在日志中,然后在日志中统一打印出来。首先在用户的拦截器中把用户的标识 Put 到 MDC 中。

如何优雅地记录操作日志?https://mp.weixin.qq.com/s/pRnrucbNX70SJyCGSQ8PQQ

20220501

所谓的有栈,无栈并不是说这个协程运行的时候有没有栈,而是说协程之间是否存在调用栈(callbackStack)

无栈协程是什么呢?其实无栈协程的本质就是一个状态机(state machine),它可以理解为在另一个角度去看问题,即同一协程协程的切换本质不过是指令指针寄存器的改变

从执行时栈的角度来看,其实所有的协程共用的都是一个栈,即系统栈,也就也不必我们自行去给协程分配栈,因为是函数调用,我们当然也不必去显示的保存寄存器的值,而且相比有栈协程把局部变量放在新开的空间上,无栈协程直接使用系统栈使得CPU cache局部性更好,同时也使得无栈协程的中断和函数返回几乎没有区别,这样也可以凸显出无栈协程的高效。

浅谈有栈协程与无栈协程 - 知乎协程相关视频解析: linux系统下协程的实现与原理剖析训练营(上) linux系统下协程的实现与原理剖析训练营(下)如今虽不敢说协程已经是红的发紫,但确实是越来越受到了大家的重视。Golang中的已经是只有goroutin…https://zhuanlan.zhihu.com/p/347445164?utm_source=wechatMessage_undefined_bottom

协程的适用在IO密集型的程序。
由于IO操作远远小于CPU的操作,
所以往往需要CPU去等IO操作。同步IO下系统需要切换线程,让操作系统可以再IO过程中执行其他的东西。
这样虽然代码是符合人类的思维习惯但是由于大量的线程切换带来了大量的性能的浪费,尤其是IO密集型的程序。
所以人们发明了异步IO。就是当数据到达的时候触发我的回调。来减少线程切换带来性能损失

https://zhuanlan.zhihu.com/p/57869129?utm_source=wechat_session&utm_medium=social&s_r=0https://zhuanlan.zhihu.com/p/57869129?utm_source=wechat_session&utm_medium=social&s_r=0

20220429

双亲委派机制 | 对线面试官Java一线大厂面试http://javainterview.gitee.io/luffy/2021/08/19/04-Java%E8%99%9A%E6%8B%9F%E6%9C%BA/02.%20%E5%8F%8C%E4%BA%B2%E5%A7%94%E6%B4%BE%E6%9C%BA%E5%88%B6/

记录锁、间隙锁与 Next-Key Lockhttps://mp.weixin.qq.com/s/Zh7GSzXJg_zt2ug3X5TwEQ

20220424

Go WebAssembly (Wasm) 简明教程 | 快速入门 | 极客兔兔本文介绍了如何使用Go 语言(golang)、WebAssembly 和 gopherjs 进行前端开发。包括注册函数,并与浏览器 JavaScript 对象交互,操作 DOM 元素,异步编程与回调函数等。最后介绍了一些进阶的 Demo(游戏,渲染等方面)和相关的项目和文档。https://geektutu.com/post/quick-go-wasm.html

上下文保存与恢复是协程的核心

#include <chrono>
#include <iostream>
#include <thread>

// rbp rbx r12 r13 r14 r15 rip rsp
uint64_t co1_regs[8] = { 0 };
uint64_t co2_regs[8] = { 0 };

uint64_t co2_stack[1024];

void switch_to(void*, void*)
{
    __asm volatile("movq %rbp, (%rdi)");
    __asm volatile("movq %rbx, 8(%rdi)");
    __asm volatile("movq %r12, 16(%rdi)");
    __asm volatile("movq %r13, 24(%rdi)");
    __asm volatile("movq %r14, 32(%rdi)");
    __asm volatile("movq %r15, 40(%rdi)");
    __asm volatile("movq 8(%rsp), %rax");
    __asm volatile("movq %rax, 48(%rdi)");
    __asm volatile("movq %rsp, 56(%rdi)");

    __asm volatile("movq 56(%rsi), %rsp");
    __asm volatile("movq 48(%rsi), %rax");
    __asm volatile("movq %rax, 8(%rsp)");
    __asm volatile("movq 40(%rsi), %r15");
    __asm volatile("movq 32(%rsi), %r14");
    __asm volatile("movq 24(%rsi), %r13");
    __asm volatile("movq 16(%rsi), %r12");
    __asm volatile("movq 8(%rsi), %rbx");
    __asm volatile("movq (%rsi), %rbp");
}

void co1_routine()
{
    for (;;)
    {
        std::cout << "co1 running" << std::endl;
        std::this_thread::sleep_for(std::chrono::milliseconds(1000));
        switch_to(co1_regs, co2_regs);
    }
}

void co2_routine()
{
    for (;;)
    {
        std::cout << "co2 running" << std::endl;
        std::this_thread::sleep_for(std::chrono::milliseconds(1000));
        switch_to(co2_regs, co1_regs);
    }
}

int main()
{
    co2_regs[0] = (uint64_t)&co2_stack[1024];
    co2_regs[6] = (uint64_t)&co2_routine;
    co2_regs[7] = co2_regs[0];

    co1_routine();
}

一个cpp协程库的前世今生(二)协程切换的原理_c++_SkyFire_InfoQ写作社区再说协程框架之前,我们先了解一下协程切换的原理是什么。下面的描述主要围绕x86_64体系架构、linux操作系统进行。阅读本节需要的基础知识阅读本节需要了解以下基础知识:各种寄存器的用途栈的结构calhttps://xie.infoq.cn/article/a9ba6f5fd4ac855de9f9be308

我对 Twitter 前10行源代码的理解_语言 & 开发_Anand Chowdhary_InfoQ精选文章我对 Twitter 前10行源代码的理解本文最初发布于CSS-Tricks博客,由InfoQ中文站翻译并分享。 过去几周,我一直在为我的家具https://www.infoq.cn/article/JVdo2TdKtkw9rhVsUX6z

前端大概要的知道 AST大厂技术 坚持周更 精选好文认识 AST定义: 在计算机科学中,抽象语法树是源代码语法结构的一种抽象表示https://mp.weixin.qq.com/s?__biz=MzkxNTIwMzU5OQ==&mid=2247493095&idx=1&sn=13396931f3b88cd419575b25ac75f174&chksm=c1601687f6179f91d8c1197f41c6439493d0871e08878fffa473800ff343fe5b409044b3d2e8&token=363949812&lang=zh_CN#rd

如何使用 JS 实现一个 HTML 解析器浏览器底层有一块非常重要的事情就是 HTML 解析器,HTML 解析器的工作是把 HTML 字符串解析为树,树上的每个节点是一个 Node,很多同学都好奇是怎么实现的,这篇文章就用 JS 来实现一个简单的 HTML 解析器。https://mp.weixin.qq.com/s/p6bF6zzoMcIfjfsVanPhWA

40行代码实现React核心Diff算法本文会砍掉处理常见情况的算法,保留处理不常见情况的算法。这样,只需要40行代码就能实现Diff的核心逻辑。https://mp.weixin.qq.com/s/wlb_CtUsoiDIZwqHV0Mm_w

20220422

一旦参透这九个电商系统架构,全能型架构师无疑了-51CTO.COM面对这么多的业务域,有没有通用技术经验可以抽取,让我们可以 以一应百。https://developer.51cto.com/article/707081.html

20220421

1、性能和一致性不能同时满足,为了性能考虑,通常会采用「最终一致性」的方案;

2、掌握缓存和数据库一致性问题,核心问题有 3 点:缓存利用率、并发、缓存 + 数据库一起成功问题;

3、失败场景下要保证一致性,常见手段就是「重试」,同步重试会影响吞吐量,所以通常会采用异步重试的方案;

4、订阅变更日志的思想,本质是把权威数据源(例如 MySQL)当做 leader 副本,让其它异质系统(例如 Redis / Elasticsearch)成为它的 follower 副本,通过同步变更日志的方式,保证 leader 和 follower 之间保持一致。

关于缓存更新的一些可借鉴套路_缓存_架构精进之路_InfoQ写作社区hello,大家好,我是张张,「架构精进之路」公号作者。一、背景目前随着缓存架构方案越来越成熟化,通常做法是引入「缓存」来提高读性能,架构模型就变成了这样:先来看一下什么时候创建缓存,前端请求的读操作https://xie.infoq.cn/article/3fb9b02fb6032c47588686226

如果系统能实现任意单一对象的单一读操作都返回最近写操作的值(A Read returns the most recently value written),则代表了这个系统实现了在技术层面对于单一对象单一操作的的最强的一致性需求

浅析分布式系统之体系结构 技术基本目标----一致性(单对象、单操作)_snlfsnef_InfoQ写作社区一致性的本质一致性定义:逻辑层面,一致性(consistency)是指一個形式系統中不蕴含矛盾(wiki)。在计算机系统的范畴之内,一致性其实是一种人们对于系统的综合需求,人们往往需要计算机的运行结果https://xie.infoq.cn/article/6cef87b1d366703f8bfa9d8c9

20220420

     深入浅析Go中三个点(...)用法

标识数组元素个数

1

stooges := [...]string{"Moe", "Larry", "Curly"} // len(stooges) == 3

var strss= []string{

        "qwr",

        "234",

        "yui",

        "cvbc",

    }

    test1(strss...) //切片被打散传入 strss... 等同于 "qwr","234","yui","cvbc"

Go命令行中的通配符

描述包文件的通配符。
在这个例子中,会单元测试当前目录和所有子目录的所有包:

1

go test ./...

这里,...意味着数组的元素个数:

https://www.jb51.net/article/224566.htmhttps://www.jb51.net/article/224566.htm

ZGC 没有分代的概念

ZGC 的内存布局说起。与 Shenandoah 和 G1一样,ZGC 也采用基于 Region 的堆内存布局,但与它们不同的是 , ZGC 的 Region 具 有 动 态 性 (动态创建和销毁 , 以及动态的区域容量大小)。在 x64硬件平台下 , ZGC 的 Region 可以具有大、中、小三类容量(如下图所示):

  • 小型 Region (Small Region ):容量固定为 2M, 存放小于 256K 的对象。
  • 中型 Region (Medium Region):容量固定为 32M,放置大于等于256K但小于4M的对象。
  • 大型 Region (Large Region): 容量不固定,可以动态变化,但必须为2MB 的整数倍,用于放置 4MB或以上的大对象。

JVM 从入门到放弃之 ZGC 垃圾收集器-51CTO.COM本文主要是从概念上描述了 ZGC 的特征和工作过程。目前大多数互联网公司还是使用 jdk 8、jdk 11 主流使用的还是 ParNew + CMS 组合或者 G1。https://developer.51cto.com/article/706899.html

go 通过"~"来表示支持类型扩展类型

否则只能接受 constraint 列表中的类型作为调用的参数,包括这些类型的别名。但对于列表中类型的衍生类型就不能接受了

 泛型真的会让程序变慢吗?(Go1.18新特性)_golang_蔡超_InfoQ写作社区基本语法定义可接受类型列表(constraint)简单来说,Go的泛型就是将参数类型定义为一个可接受类型的列表(称为constraint),直接上例子。例1: 方法定义上使用范型func Max[Thttps://xie.infoq.cn/article/2c845a2e3d527541d6946e00a

20220419

Redis是怎样通讯的?_redis_ooooooh灰灰_InfoQ写作平台模型Redis 协议模型就是简单的请求-响应模型,和平常的 Http 协议有点类似。客户端发送 Redis 命令,然后服务端处理命令并返回结果给客户端。Redis 官方说这可能是最简单的网络协议模型了https://xie.infoq.cn/article/0496d06df156ad6a9ff365d08MySQL 是怎样通讯的?_Go_ooooooh灰灰_InfoQ写作平台前言我们平常使用数据库的场景一般是程序里面代码直接连接使用,然后进行 CRUD 操作。或者使用有 GUI 界面的数据库软件来手动操作数据库, 这类软件有 DataGrip、Navicat等等...。平https://xie.infoq.cn/article/42e11a05bf40d0ee709a68bb6MySQL 协议明文连接代码实现[Go语言] · GitHubMySQL 协议明文连接代码实现[Go语言]. GitHub Gist: instantly share code, notes, and snippets.https://gist.github.com/greycodee/22f98464fece7792a83433a1fba58e2ahttps://gist.github.com/greycodee/4a102aa9ae689aea1874b1fe06190192https://gist.github.com/greycodee/4a102aa9ae689aea1874b1fe06190192

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值