之前的文章集合:
一些可以参考文章集合1_xuejianxinokok的博客-CSDN博客
一些可以参考文章集合2_xuejianxinokok的博客-CSDN博客
一些可以参考的文档集合3_xuejianxinokok的博客-CSDN博客
一些可以参考的文档集合4_xuejianxinokok的博客-CSDN博客
一些可以参考的文档集合5_xuejianxinokok的博客-CSDN博客
20220715
Event delegation is a simple, but powerful leveraging of the DOM event system which allows for easier adding of functionality to dynamically created content; as well as being an interesting performance optimization.
Idea is you just need to add one event listener to the partent DOM element, instead of add one event listener for each child element.
For example,
child,addEventListener( 'click', function onClick(event) { if (event.target instanceof Element && event.target.tagName === "Button") { addButton(); }})
Problem is if you put "click" into a Span
Previous code won't work, work around can be:
child,addEventListener(//closest 是最近的意思 'click', function onClick(event) { if (event.target instanceof Element && event.target.closest('button') === "Button") { addButton(); }})
The
closest()
method traverses the Element and its parents (heading toward the document root) until it finds a node that matches the provided selector string. Will return itself or the matching ancestor. If no such element exists, it returnsnull
.
[Javascript] event.target.closest(selector) - Zhentiw - 博客园The Event Delegation Pattern Event delegation is a simple, but powerful leveraging of the DOM eventhttps://www.cnblogs.com/Answer1215/p/15162112.html
js中的自定义事件
window.addEventListener('Eaaa',function(){
console.log('who dispatch THIS event?')
}, false);
var res = window.dispatchEvent(new Event('Eaaa'))
如何简单实现一个router
export function navigate (href) {
// update url
window.history.pushState({}, "", href);
// communicate to Routes that URL has changed
const navEvent = new PopStateEvent('popstate');
window.dispatchEvent(navEvent);
}
https://github.com/ashok-khanna/react-snippets/blob/main/Router.jshttps://github.com/ashok-khanna/react-snippets/blob/main/Router.js
索引是它们自己的数据结构,它们是 Postgres 数据定义语言 (DDL) 的一部分。它们与数据表和其他对象一起存储在磁盘上。
Postgres Indexes for Newbies
20220714
HTTP/3来了!存续二十多年的TCP协议最终被抛弃!-51CTO.COMTCP 是 Internet 上使用和部署最广泛的协议之一,多年来一直被视为网络基石,随着HTTP/3正式被标准化,QUIC协议成功“上位”,UDP“取代”TCP成为基础协议,TCP究竟“输”在哪里?https://network.51cto.com/article/713998.html
在 Vite 中,我们可以使用这两个方法来动态导入文件:
该方法匹配到的文件默认是 懒加载 ,通过 动态导入 实现,构建时会 分离独立的 chunk ,是 异步导入 ,返回的是 Promise,需要做异步操作,使用方式如下:
复制
const Components = import.meta.glob('../components/**/*.vue');
// 转译后:
const Components = {
'./components/a.vue': () => import('./components/a.vue'),
'./components/b.vue': () => import('./components/b.vue')
}
该方法是 直接导入所有模块 ,并且是 同步导入 ,返回结果直接通过 for...in 循环就可以操作,使用方式如下:
复制
const Components = import.meta.globEager('../components/**/*.vue');
// 转译后:
import * as __glob__0_0 from './components/a.vue'
import * as __glob__0_1 from './components/b.vue'
const modules = {
'./components/a.vue': __glob__0_0,
'./components/b.vue': __glob__0_1
}
如果仅仅使用异步导入 Vue3 组件,也可以直接使用 Vue3 defineAsyncComponent API 来加载:
复制
// https://v3.cn.vuejs.org/api/global-api.html#defineasynccomponent
import { defineAsyncComponent } from 'vue'
const AsyncComp = defineAsyncComponent(() =>
import('./components/AsyncComponent.vue')
)
app.component('async-component', AsyncComp)
分享15个vue3全家桶开发的避坑经验-51CTO.COM本文是我最近从入门到实战 Vue3 全家桶的 3 个项目后总结避坑经验,其实很多都是文档中有介绍的,只是刚开始不熟悉。https://developer.51cto.com/article/711658.html
描述了在setup 语法下怎么emit事件
Vue3 $emit指南--包含选项API、组合API以及 setup 语法糖-51CTO.COM在 vue3 中,与组件和 prop 一样,事件名提供了自动的大小写转换。如果在子组件中触发一个以 camelCase (驼峰式命名) 命名的事件,你将可以在父组件中添加一个 kebab-case (短横线分隔命名) 的监听器。https://developer.51cto.com/article/713903.html
HTTP3是在保持QUIC稳定性的同时使用UDP来实现高速度(选择QUIC就是选择UDP), 同时又不会牺牲TLS的安全性。
HTTP2协议虽然大幅提升了HTTP/1.1的性能,然而,基于TCP实现的HTTP2遗留下3个问题:
HTTP3协议解决了这些问题:
连接迁移
TCP连接基于四元组(源IP, 源端口, 目的IP, 目的端口), 切换网络时至少会有一个因素发生变化, 导致连接发送变化. 当连接发送变化是, 如果还是用原来的TCP连接, 则会导致连接失败, 就得等到原来的连接超时后重新建立连接, 所以我们有时候发现切换到一个新的网络时, 即使网络状况良好, 但是内容还是需要加载很久. 如果实现的好, 当检测到网络变化时, 立即建立新的TCP连接, 即使这样, 建立新的连接还是需要几百毫秒时间。
QUIC不受四元组的影响, 当这四个元素发生变化时, 原连接依然维持. 原理如下:QUIC不以四元素作为表示, 而是使用一个64位的随机数, 这个随机数被称为Connection ID, 即使IP或者端口发生变化, 只要Connection ID没有变化, 那么连接依然可以维持。
TCP是个面向连接的协议, 即发送请求后需要收到ACK消息, 以确认对象已接受数据. 如果每次请求都要在收到上次请求的ACK消息后再请求, 那么效率无疑很低. 后来HTTP/1.1提出了Pipeline技术, 允许一个TCP连接同时发送多个请求. 这样就提升了传输效率。
在这样的背景下, 队头阻塞发生了. 比如, 一个TCP连接同时传输10个请求, 其中1,2,3个请求给客户端接收, 但是第四个请求丢失, 那么后面第5-10个请求都被阻塞. 需要等第四个请求处理完毕后才能被处理. 这样就浪费了带宽资源。
因此, HTTP一般又允许每个主机建立6个TCP连接, 这样可以更加充分的利用带宽资源, 但每个连接中队头阻塞的问题还是存在的。
HTTP/2的多路复用解决了上述的队头阻塞问题. 在HTTP/2中, 每个请求都被拆分为多个Frame通过一条TCP连接同时被传输, 这样即使一个请求被阻塞, 也不会影响其他的请求。
但是, HTTP/2虽然可以解决请求这一粒度下的阻塞, 但HTTP/2的基础TCP协议本身却也存在队头阻塞的问题. HTTP/2的每个请求都会被拆分成多个Frame, 不同请求的Frame组合成Stream, Stream是TCP上的逻辑传输单元, 这样HTTP/2就达到了一条连接同时发送多个请求的目标, 其中Stram1已经正确送达, Stram2中的第三个Frame丢失, TCP处理数据是有严格的前后顺序, 先发送的Frame要先被处理, 这样就会要求发送方重新发送第三个Frame, Steam3和Steam4虽然已到达但却不能被处理, 那么这时整条链路都会被阻塞。
HTTP/3正式发布,深入理解HTTP/3协议-51CTO.COM这是超文本传输协议(HTTP)的第三个主要版本,完整的 RFC 超过了 20000 字,非常详细的解释了 HTTP/3。https://developer.51cto.com/article/713935.html
20220712
用户访问过一次文章、新闻、代码详情页面,访问次数字段加 1 , 在 oschina 上这个操作是异步的,访问的时候只是将数据在内存中保存,每隔固定时间将这些数据写入数据库。
一次线上事故,我顿悟了异步的精髓-51CTO.COM在教研课程详情场景里,数据库的资源是固定的,但写操作占据大量数据库资源,导致整个系统的阻塞,但写操作并不是最核心的业务流程,它不应该占用那么多的系统资源。https://developer.51cto.com/article/713723.html
例一
在函数方法中
以前写法:
复制
public String getCity(User user) throws Exception{
if(user!=null){
if(user.getAddress()!=null){
Address address = user.getAddress();
if(address.getCity()!=null){
return address.getCity();
}
}
}
throw new Excpetion("取值错误");
}
JAVA8写法:
复制
public String getCity(User user) throws Exception{
return Optional.ofNullable(user)
.map(u-> u.getAddress())
.map(a->a.getCity())
.orElseThrow(()->new Exception("取指错误"));
}
例二
比如,在主程序中
以前写法:
复制
if(user!=null){
dosomething(user);
}
JAVA8写法:
复制
Optional.ofNullable(user)
.ifPresent(u->{
dosomething(u);
});
例三
以前写法:
复制
public User getUser(User user) throws Exception{
if(user!=null){
String name = user.getName();
if("zhangsan".equals(name)){
return user;
}
}else{
user = new User();
user.setName("zhangsan");
return user;
}
}
Java8写法:
复制
public User getUser(User user) {
return Optional.ofNullable(user)
.filter(u->"zhangsan".equals(u.getName()))
.orElseGet(()-> {
User user1 = new User();
user1.setName("zhangsan");
return user1;
});
}
巧用 Java 8 的 Optional 优雅地规避 NPE-51CTO.COM为了避免一些丑陋的写法,让丑陋的设计变得优雅。JAVA8提供了Optional类来优化这种写法,接下来的正文部分进行详细说明。https://developer.51cto.com/article/713696.html
这是vue3中composition API的入口,可以说为vue3拉开序幕
执行时机
在beforeCreate
之前执行,因此this
是不可用的,为undefined
参数
接收两个参数props
和context
props--外部组件传过来的东西
值为对象,包含组件外部传递过来,且组件内部声明接收了的属性
context--上下文对象
attrs:值为对象,包含组件外传过来但是并没有在props配置中声明的属性,相当于vue2中的this.$attrs
slots:收到的插槽的内容,相当于this.$slots
emits:分发自定义事件的函数,相当于this.$emit
使用时,使用context.emit('xx', value)
Vue3第二篇setup简介之监视与计算属性 - 掘金setup 一、setup拉开序幕 执行时机 在beforeCreate之前执行,因此this是不可用的,为undefined 参数 接收两个参数props和context props--外部组件传过https://juejin.cn/post/6985028582170968100
ref 用于包装基本类型,reactive用于包装复杂类型
vue3提供了ref方法进行简单值的监听,但并不是说ref只能传入简单值,他的底层是reactive,所以reactive有的,他都有。
ref
和toRef
都是用来构造响应式数据,两者有什么区别呢?
ref类似深拷贝,toref类似浅拷贝
ref
本质也是reactiv
,ref(obj)
等价于reactive({
value
: obj})
ref
和reactive
,所谓响应式就是界面和数据同步,能实现实时更新,也就是说 ref和reactive 的数据等同于 选项式api中的 data()函数vue
中使用ref
的值,不用通过.value
获取js
中使用ref
的值,必须通过.value
获取defineProperty
实现的,vue3中是通过ES6的Proxy
来实现的
Vue3第一篇之ref和reactive详解扩展 - 掘金一、ref和reactive 1.reactive reactive的参数必须是一个对象,包括json数据和数组都可以,否则不具有响应式 如果给reactive传递了其他对象(如时间对象),默认情况下https://juejin.cn/post/6977929393511514148
有了Composition API,我们就不会受限于这种结构,可以根据功能而不是选项来分离代码。
将逻辑从**.vue**组件文件中移出
以前,有一些例子,所有的逻辑都是在script setup 中完成的。还有一些例子是使用从.vue文件导入的可组合函数的组件。
大代码设计问题是:我们应该把所有的逻辑写在.vue文件之外吗?有利有弊。
所有的逻辑都放在 setup中 |
移到专用的.js/.ts文件 |
不需要写一个可组合的,方便直接修改 |
可扩展更强 |
重用代码时需要重构 |
不需要重构 |
更多模板 |
我是这样选择的:
围绕Vue 3 Composition API构建一个应用程序,包含一些优秀实践!-51CTO.COM这篇文章旨在展示一些有趣的方法来利用Composition API,以及如何围绕它来构造一个应用程序。https://developer.51cto.com/article/713676.html
20220708
Software Engineering at GoogleDescriptionhttps://qiangmzsx.github.io/Software-Engineering-at-Google/#/zh-cn/Foreword
Vue.js挑战 | Vue.js挑战Collection of Vue.js challengeshttps://cn-vuejs-challenges.netlify.app/questions/13-dom-portal/README.zh-CN.html
20220707
reduce是数组原型对象上的一个方法,可以帮助我们操作数组。它将另一个函数作为其参数,可以称为reducer。
reducer 有两个参数。第一个参数 param1 是最后一次 reducer 运行的结果。如果这是第一次运行 reducer,则 param1 的默认值是数组第一个元素的值。
reduce 方法循环遍历数组中的每个元素,就像在 for 循环中一样。并将循环中的当前值作为参数2。
四个JavaScript 中 array.reduce() 数组方法的使用实例-51CTO.COM
20220706
微前端架构的几种技术选型 - 掘金微前端是一种类似于微服务的架构,是一种由独立交付的多个前端应用组成整体的架构风格,将前端应用分解成一些更小、更简单的能够独立开发、测试、部署的应用,而在用户看来仍然是内聚的单个产品。https://juejin.cn/post/7113503219904430111
这些物联网设备记录的数据可能是这个样子
这些数据和时间有密切关系,随着时间的推移会不断累积,每天可以达到TB,甚至PB级
这些数据的处理方式和关系数据库有着截然不同的特点,它们被称为“时序数据”
漫画 | Oracle 被新时代抛弃了吗? - 文章详情1977年,33岁拉里·埃里森厌倦了打工的生活,和两个小伙伴一起开始创业了。拉里·埃里森曾经做过美国中情局(CIA)的项目,建立了良好的关系,这一次,他又从CIA拉来了一个咨询项目在做CIA项目期间,拉里·埃里森敏锐地意识到,商业数据库市场将会有大发展,公司要向这个领域进军。而天才的程序员鲍勃·迈纳https://z.itpub.net/article/detail/C7B10741815B7B59AED1F451A87FE5DF
websocket
HTTP keep-alive 的作用是,告知服务端持久化当前的 TCP 连接,不要立即断开,以便后续的 HTTP 请求复用它,也就是我们所说的「长连接」
HTTP 的 keep-alive 是为了让 TCP 活久一点,而 TCP 本身也有一个 keepalive(注意没有横杠哦)机制。这是 TCP 的一种检测连接状况的保活机制,keepalive 是 TCP 保活定时器:TCP 建立后,如果闲置没用,服务器不可能白等下去,闲置一段时间[可设置]后,服务器就会尝试向客户端发送侦测包,来判断 TCP 连接状况,如果没有收到对方的回答(ACK包),就会过一会[可设置]再侦测一次,如果多次[可设置]都没回答,就会丢弃这个 TCP 连接
和 HTTP 一样都是建立在 TCP 协议之上,但只需一次 HTTP 握手,就能建立持久性连接,后续就不走 HTTP 了,而是 WebSocket 特有的数据帧
全双工通信,双向数据传输
数据格式轻量,且支持发送二进制数据,支持 ws 和加密的 wss
WebSocket
与 HTTP
的关系图:
相同点: 都是一样基于TCP的,都是可靠性传输协议。都是应用层协议。
联系: WebSocket在建立握手时,数据是通过HTTP传输的。但是建立之后,在真正传输时候是不需要HTTP协议的。
下面一张图说明了 HTTP 与 WebSocket 的主要区别:
不同点:
1、 WebSocket
是双向通信协议,模拟 Socket
协议,可以双向发送或接受信息,而 HTTP
是单向的;
2、 WebSocket
是需要浏览器和服务器握手进行建立连接的,而 http
是浏览器发起向服务器的连接。
3、 虽然 HTTP/2
也具备服务器推送功能,但 HTTP/2
只能推送静态资源,无法推送指定的信息。
首先 WebSocket 是基于 HTTP 协议的,或者说借用了 HTTP 协议来完成一部分握手。
首先我们来看个典型的 WebSocket 握手
GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 13
Origin: http://example.com
熟悉 HTTP 的童鞋可能发现了,这段类似 HTTP 协议的握手请求中,多了这么几个东西。
Upgrade: websocket
Connection: Upgrade
这个就是 WebSocket
的核心了,告诉 Apache 、 Nginx
等服务器:注意啦,我发起的请求要用 WebSocket
协议,快点帮我找到对应的助理处理~而不是那个老土的 HTTP
。
Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 13
首先, Sec-WebSocket-Key 是一个 Base64 encode 的值,这个是浏览器随机生成的,告诉服务器:泥煤,不要忽悠我,我要验证你是不是真的是 WebSocket 助理。
然后, Sec_WebSocket-Protocol 是一个用户定义的字符串,用来区分同 URL 下,不同的服务所需要的协议。简单理解:今晚我要服务A,别搞错啦~
最后, Sec-WebSocket-Version 是告诉服务器所使用的 WebSocket Draft (协议版本),在最初的时候,WebSocket 协议还在 Draft 阶段,各种奇奇怪怪的协议都有,而且还有很多期奇奇怪怪不同的东西,什么 Firefox 和 Chrome 用的不是一个版本之类的,当初 WebSocket 协议太多可是一个大难题。不过现在还好,已经定下来啦~大家都使用同一个版本:服务员,我要的是13岁的噢→_→
WebSocket 中 Sec-WebSocket-Key 的生成算法是拼接服务端和客户端生成的字符串,进行SHA1哈希算法,再用base64编码。
WebSocket 协议握手是依靠 HTTP 协议的,依靠于 HTTP 响应101进行协议升级转换。
然后服务器会返回下列东西,表示已经接受到请求, 成功建立 WebSocket 啦!
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: HSmrc0sMlYUkAGmm5OPpG2HaGWk=
Sec-WebSocket-Protocol: chat
这里开始就是 HTTP 最后负责的区域了,告诉客户,我已经成功切换协议啦~
Upgrade: websocket
Connection: Upgrade
依然是固定的,告诉客户端即将升级的是 WebSocket 协议,而不是 mozillasocket
,lurnarsocket
或者 shitsocket
。
然后, Sec-WebSocket-Accept
这个则是经过服务器确认,并且加密过后的 Sec-WebSocket-Key
。服务器:好啦好啦,知道啦,给你看我的 ID CARD 来证明行了吧。
后面的, Sec-WebSocket-Protocol
则是表示最终使用的协议。至此,HTTP 已经完成它所有工作了,接下来就是完全按照 WebSocket
协议进行了。总结, WebSocket
连接的过程是:
首先,客户端发起http请求,经过3次握手后,建立起TCP连接;http
请求里存放 WebSocket
支持的版本号等信息,如:Upgrade、Connection、WebSocket-Version等;
然后,服务器收到客户端的握手请求后,同样采用HTTP协议回馈数据;
最后,客户端收到连接成功的消息后,开始借助于TCP传输信道进行全双工通信。
HTTP 必须是 1.1 GET 请求
HTTP Header 中 Connection 字段的值必须为 Upgrade
HTTP Header 中 Upgrade 字段必须为 websocket
Sec-WebSocket-Key 字段的值是采用 base64 编码的随机 16 字节字符串
Sec-WebSocket-Protocol 字段的值记录使用的子协议,比如 binary base64
Origin 表示请求来源
状态码是 101 表示 Switching Protocols
Upgrade / Connection / Sec-WebSocket-Protocol 和请求头一致
Sec-WebSocket-Accept 是通过请求头的 Sec-WebSocket-Key 生成
优点:
WebSocket协议一旦建议后,互相沟通所消耗的请求头是很小的
服务器可以向客户端推送消息了
缺点:
少部分浏览器不支持,浏览器支持的程度与方式有区别(IE10)
一文吃透 WebSocket 原理https://mp.weixin.qq.com/s/3XWIMtmnOFw03mNAYLZKtw
Websocket 被玩出了多种花样!我们利用 WebSocket 都捣鼓了什么?https://mp.weixin.qq.com/s/XermtVRpYOkBK2BoMgtEEw
假设变量a
不存在,我们希望给系统一个默认值,一般我们会使用||
运算符。但是在javascript
中空字符串,0
,false
都会执行||
运算符,所以ECMAScript2020
引入合并空运算符解决该问题,只允许在值为null
或未定义时使用默认值。
const name = '';
console.log(name || 'yd'); // yd;
console.log(name ?? 'yd'); // '';
业务代码中经常会遇到这样的情况,a
对象有个属性b
,b
也是一个对象有个属性c
,
我们需要访问c
,经常会写成a.b.c
,但是如果f
不存在时,就会出错。
const a = {
b: {
c: 123,
}
}
console.log(a.b.c); // 123;
console.log(a.f.c); // f不存在所以会报错
ECMAScript2020
定义可选链运算符解决该问题,通过在.
之前添加一个?
将键名变成可选
let person = {};
console.log(person?.profile?.age ?? 18); // 18
let p={}
undefined
console.log(p?.addr?.name || '呵呵')
--之前的写法
console.log(p&&p.addr&&p.add.name || '呵呵')
呵呵
console.log(p?.addr?.name ?? '呵呵')
呵呵
console.log(p?.addr?.name)
undefined
创建Date
对象的兼容性问题。
// window和安卓支持,ios和mac不支持
new Date('2020-11-26');
// window和安卓支持,ios和mac支持
new Date('2020/11/26');
30+ 个工作中常用到的前端小知识(干货)干货,建议收藏https://mp.weixin.qq.com/s/hp_VD0JDMox-wG7qxhpjMQ
Kafka Streams and Quarkus: Real-Time Processing Eventshttps://www.infoq.com/articles/quarkus-with-kafka-streams/
Getting Started to Quarkus Reactive Messaging with Apache Kafkahttps://www.infoq.com/articles/data-with-quarkus-kafka/
Redis 6 中的多线程是如何实现的 !-51CTO.COM事实上 Redis 也确实这么干了,在 6.0 以后的版本里,开始支持了多线程。我们今天就来领略一下 Redis 的多线程是如何实现的。https://www.51cto.com/article/713253.html
debezium 相较于 Oracle 官方付费工具 OGG,具有如下硬伤:
只能对主库 CDC,无法用于 ADG 备库(参见DBZ-3866)。由于 LogMiner 的设计初衷为对 Redo logs 的诊断工具而非专门的 CDC 工具,故并未对持续运行进行任何效率、开销等优化,直接运用于主库势必会对主库业务正常运行造成影响。这对于应用 Oracle 的典型企业(银行、电信等要求高可靠性的公司)实则不可接受。
抽取性能受限。按照Oracle官方的说法,在每秒钟几百个事务时就会遇到较大的延迟和内存问题。Debezium 框架由于其实现,实际解析速度比这个数值更低。
基于 LogMiner 和 Debezium 构建可用于生产实践的 Oracle 实时数据采集工具_架构_丁杨_InfoQ精选文章基于 LogMiner 和 Debezium 构建可用于生产实践的 Oracle 实时数据采集工具实时数据采集(又称为“变化数据捕获”ChangeDataCapture,下文又称CDC、实时抽数)在https://www.infoq.cn/article/pGakNSLI9xUfEj9HtOlT
20220705
显卡价格
物品 | 价格表 | 2022 年 6 月 | 2022 年 4 月 | 2022年1月 |
---|---|---|---|---|
英伟达 RTX 3090 Ti | 1,999 美元 | 1,459 美元 | 2,398 美元 | 不适用 |
英伟达 RTX 3090 | 1,499 美元 | 1,033 美元 | 1,837 美元 | 2,609 美元 |
英伟达 RTX 3080 Ti | 1,199 美元 | 881 美元 | 1,168 美元 | 1,874 美元 |
英伟达 RTX 3080 | 699 美元 | 701 美元 | 1,129 美元 | 1,613 美元 |
英伟达 RTX 3070 Ti | 599 美元 | 585 美元 | 772 美元 | 1,179 美元 |
英伟达 RTX 3070 | 499 美元 | 498 美元 | 773 美元 | 1,086 美元 |
英伟达 RTX 3060 Ti | 399 美元 | 434 美元 | 658 美元 | 923 美元 |
英伟达 RTX 3060 | 329 美元 | 362 美元 | 485 美元 | 711 美元 |
英伟达 RTX 3050 | 249 美元 | 294 美元 | 363 美元 | 539 美元 |
AMD RX 6900 XT | 999 美元 | 683 美元 | 961 美元 | 1,528 美元 |
AMD RX 6800 XT | 649 美元 | 630 美元 | 869 美元 | 1,269 美元 |
AMD RX 6800 | 579 美元 | 518 美元 | 796 美元 | 1,150 美元 |
AMD RX 6700 XT | 479 美元 | 387 美元 | 555 美元 | 847 美元 |
AMD RX 6600 XT | 379 美元 | 293 美元 | 421 美元 | 610 美元 |
AMD RX 6600 | 329 美元 | 247 美元 | 380 美元 | 516 美元 |
AMD RX 6500 XT | 199 美元 | 179 美元 | 209 美元 | 365 美元 |
I just bought a Nvidia RTX 3070 for MSRP because the GPU shortage is over - The VergeNvidia and AMD graphics cards are again within reach, as prices of new and used GPUs like the RTX 3080, RTX 3070, RTX 3060 Ti, and Radeon RX 6800 cards are at, approaching, or even under MSRP.https://www.theverge.com/2022/7/1/23191634/nvidia-amd-gpu-shortage-over-3080-3070-3060-radeon-rx-6900-6800
20220704
深度剖析 VS Code JavaScript Debugger 功能及实现原理希望看完本文能让你对 VS Code 的 JavaScript Debugger 有大致的理解。https://mp.weixin.qq.com/s/9FoyLqROYXaTjivbF4KUlg
用 Node.js 手写一个 DNS 服务器自己实现一个域名服务器https://mp.weixin.qq.com/s/Gl94ISY5N4BYyYmVT9-QFQ
使用 content-visibility 优化渲染性能虚拟列表,懒加载?CSS 也不在话下!https://mp.weixin.qq.com/s/o9lpl7CTwcbjM0q3QMRLTg
-- OGG微服务
docker pull lhrbest/ogg213mapg:v1.0
使用OGG for PG微服务快速双向同步RDS数据库(双主)使用OGG for PG微服务 1-- 创建专用网络 2docker network create --suhttps://mp.weixin.qq.com/s/CXlNrpEc6xLGZnRVinR7Bg
OGG微服务部署配置https://mp.weixin.qq.com/s/PzjjYnHYx1p6Z8_fBP75jw
OGG
https://mp.weixin.qq.com/mp/appmsgalbum?action=getalbum&__biz=MzUxNTYzMjA5Mg==&scene=1&album_id=1669893298603229196&count=3#wechat_redirecthttps://mp.weixin.qq.com/mp/appmsgalbum?action=getalbum&__biz=MzUxNTYzMjA5Mg==&scene=1&album_id=1669893298603229196&count=3#wechat_redirect
20220702
Harris角点 - ☆Ronny丶 - 博客园1. 不同类型的角点在现实世界中,角点对应于物体的拐角,道路的十字路口、丁字路口等。从图像分析的角度来定义角点可以有以下两种定义:角点可以是两个边缘的角点;角点是邻域内具有两个主方向的特征点;前者往往https://www.cnblogs.com/ronny/p/4009425.html
node 内置模块 child_process 下 spawn 执行 terminal 命令,包括执行 shell 脚本的 sh 脚本文件.sh
命令
下来看一个 demo,新建一个 testExecShell 测试目录,测试效果
// testExecShell/runCmd.js
const { spawn } = require('child_process');
const ls = spawn('ls', ['-lh', '/usr']); // 执行 ls -lh /usr 命令
ls.stdout.on('data', (data) => {
// ls 产生的 terminal log 在这里 console
console.log(`stdout: ${data}`);
});
ls.stderr.on('data', (data) => {
// 如果发生错误,错误从这里输出
console.error(`stderr: ${data}`);
});
ls.on('close', (code) => {
// 执行完成后正常退出就是 0
console.log(`child process exited with code ${code}`);
});
Vue + Node.js 从 0 到 1 实现自动化部署工具Vue + Node.js 从 0 到 1 实现自动化部署工具https://mp.weixin.qq.com/s/E1ZnkAK1LyxpYkRZlhH8Gw
录音和录像使用 getUserMedia
来实现,而 录屏则需要调用 getDisplayMedia
这个接口来实现。
为了能更好地区分这两种情况,可以给开发者提供 audio
, video
以及 screen
三个参数,告诉我们应该调哪个接口去获取对应的输入流数据:
在生成 blob url 的时候我们调用了 URL.createObjectURL
API 来实现,生成后的 url 长这样:
blob:http://localhost:3000/e571f5b7-13bd-4c93-bc53-0c84049deb0a
每次 URL.createObjectURL
后都会生成一个 url -> blob
的引用,这样的引用也是会占用资源内存的,所以我们可以提供一个方法来销毁这个引用。
用JS轻松实现一个录音、录像、录屏工具库https://mp.weixin.qq.com/s/2cIqRtFxciE4l3saq0q66A
20220701
对比项目 | EMQ | HiveMQ | VerneMQ | ActiveMQ | Mosquitto |
---|---|---|---|---|---|
License | 开源+商业版 | 开源+商业版 | 开源+商业版 | 开源 | 开源 |
公司/社区 | EMQ | HiveMQ | VerenMQ | Apache 基金会 | Eclipse 基金会 |
开源协议 | Apache License 2.0 | Apache License 2.0 | Apache License 2.0 | Apache License 2.0 | EPL/EDL licensed |
开发团队 | 杭州映云科技有限公司 | dc-square 股份有限公司,德国 | Octavo Labs AG,瑞士 | Apache 项目维护者 | Eclipse 开源社区 |
开发语言 | Erlang | Java | Erlang | Java | C |
项目历史 | 2012年开始开源,2016年开始商业化 | 2013 年成立,一直以闭源方式向客户提供软件,2019 年开源 | 提供基于开源的商业化定制服务 | 2004 由 LogicBlaze 创建;原本规划的 ActiveMQ 的下一代开源项目 Apollo 已经不活动(4年没有代码更新) | |
集群架构 | 支持 | 仅企业版 | 支持 | 支持 | 不支持(有伪集群实现) |
系统部署 | 物理机、虚拟机、K8S | 物理机、虚拟机、K8S | 物理机、虚拟机、K8S | 物理机、虚拟机、容器 | 物理机、虚拟机、容器 |
支持协议 | MQTT、CoAP、MQTT-SN、WebSocket、TCP、UDP、LwM2M | MQTT | MQTT | JMS、Openwire、Stomp、AMQP、MQTT、WebSocket XMPP | MQTT、WebSocket |
系统性能 | 单机性能较高,单机支持百万级并发,集群支持千万级并发 | 集群支持千万级并发 | 集群支持百万级并发 | 支持集群 | 单机10W |
MQTT | v3.1,v3.1.1,v5.0 | v3.1,v3.1.1,v5.0 | v3.1,v3.1.1,v5.0 | v3.1 | v3.1,v3.1.1,v5.0 |
边缘计算 | EMQ X Edge 支持树莓派,ARM 等架构,支持数据同步到云服务 Azure IoT Hub AWS | 不支持 | 不支持 | 不支持 | 支持(自身比较轻量) |
安全与认证 | TLS/DTLS、X.509证书、JWT、OAuth2.0、应用协议(ID/用户名/密码)、数据库与接口形式的认证与 ACL 功能(LDAP、DB、HTTP) | TLS/DTLS、X.509证书、JWT、OAuth2.0、应用协议(ID/用户名/密码)、配置文件形式的认证与 ACL 功能 | TLS/DTLS、X.509证书、配置文件形式的认证与 ACL 功能、数据库形式的认证与 ACL 功能,但支持数据库较少 | LDAP (JAAS)、Apache Shiro | 等待 |
运行持久化 | 支持将消息数据持久化至外部数据库如 Redis、MySQL、PostgreSQL、MongoDB、Cassa、Dynamo 等,需企业版,开源版宕机则丢失 | 开源企业均支持本地持久化,采用磁盘系统,支持备份,导出备份 | 支持持久化至 Google LevelDB | AMQ、KahaDB、JDBC、LevelDB | 等待 |
扩展方式 | Webhook、Trigger、Plugin 等,支持 Erlang 与 Lua、Java、Python 扩展开发,支持 Webhook 开发,侵入性不强 | Trigger、Plugin 等,使用 Java 技术栈开发,提供方便开发的 SDK | Trigger、Plugin 等,支持 Erlang 与 Lua 扩展开发 | Java 扩展 | 等待 |
数据存储 | 仅企业版适配数据库:Redis、Mysql、PostgreSQL、MongoDB、Cassandra、OpenTSDB、TimescaleDB、InfluxDB 适配消息队列:Kakfa、RabbitMQ、Pulsar 桥接模式:支持桥接至标准 MQTT 协议消息服务 开源版支持 HTTP 将数据同步、存储 |
适配数据库:无,提供 Java SDK 开发进行适配 消息队列:Kafka 桥接模式:支持桥接至标准 MQTT 协议消息服务 |
适配数据库:无,提供 Erlang 和 Lua 扩展开发 适配消息队列:无 桥接模式:支持桥接至标准 MQTT 协议消息服务 | 适配数据库:JDBC、KahaDB、LevelDB 适配消息队列:无 桥接模式:支持通过 JMS 桥接 | 等待 |
管理监控 | 支持可视化的 Dashboard,实现集群与节点的统一集中管理 支持第三方监控工具 Prometheus ,提供可视化 Grafana 界面模板 | 支持可视化的 HiveMQ Control Center,实现集群与节点统一管理 支持第三方监控工具 Prometheus ,可提供可视化 Grafana 界面 支持 InfluxDB 监控 | 内置简单状态管理可视化界面 支持第三方监控工具 Prometheus ,可提供可视化 Grafana 界面 | 支持可视化的监控界面 支持第三方监控工具 Prometheus ,可提供可视化 Grafana 界面 | 通过 MQTT 订阅系统主题 |
规则引擎 | 支持规则引擎,基于 SQL 的规则引擎给予 Broker 超越一般消息中间件的能力。除了在接受转发消息之外,规则引擎还可以解析消息的格式(企业版)。 规则引擎由消息的订阅,发布,确认的事件触发,根据消息的负载来执行相应的动作,降低应用开发的复杂度。 |
不支持 | 不支持 | 不支持 | 不支持 |
开发集成 | 支持通过 REST API 进行常用的业务管理操作如: 调整设置、获取 Broker 状态信息、进行消息发布、代理订阅与取消订阅、断开指定客户端、查看客户端列表、规则引擎管理、插件管理,提供 Java SDK、Python SDK 直接编码处理业务逻辑 | 无,提供 Java SDK 在应用系统在编码的层面操作进程,非常灵活但耦合性高 | 提供少量 REST API,用于监控与状态管理、客户端管理等。 缺乏代理订阅、业务管理等功能和 API | 提供少量队列管理 REST API | 等待 |
适用场景 | 优势在于高并发连接与高吞吐消息的服务能力,以及物联网协议栈支持的完整性;扩展能力较强,无需过多开发 | 有一定高并发连接与高吞吐消息的服务能力,物联网协议栈的完整性较弱仅支持 MQTT 协议;缺乏开箱即用的功能插件,功能必须编码使用 | 基础的并发连接与高吞吐消息的服务能力,物联网协议栈的完整性较弱仅支持 MQTT 协议;扩展能力较差,基础的业务组件支持度不够,商业成熟度不足客户量较少,缺乏开箱即用的功能插件 | 核心是消息队列系统,主要用于支持异构应用之间的消息通信,比如用于企业消息总线等;后面支持了部分物联网协议。ActiveMQ 比较适合系统既要支持传统的异构应用之间需要通信,也需要支持小型物联网接入支持的用户。 | 轻量简便的 MQTT Broker,工控、网关或小规模接入项 |
MQTT Broker 比较与选型_丨匿名用户丨的博客-CSDN博客_mqttbroker开源 MQTT Broker 对比截止 2020,物联网行业里可选的MQTT Broker有很多,除了经典的Mosquitto和AWS、Azure,百度云、阿里云、IBM等几个提供物联网MQTT接入服务的产品外,可用于商业生产的MQTT Broker还有多款。本文选取了几个热门开源的 MQTT Broker,其中部分项目提供商业支持,做简单选型对比。对比项目EMQHiveMQVerneMQActiveMQMosquittoLicense开源+https://blog.csdn.net/p1279030826/article/details/107916531
MQTT Broker 选型 - 简书broker的主要职责是接受发布者发布的所有消息,并将其过滤后分发给不同的消息订阅者。如今有很多的broker,下面就是一张关于各种broker对比的图片: 目前我用过的有m...https://www.jianshu.com/p/cf91f4bea071
Google 开源的 wire [3]框架做比较,认为没有 wire 清爽好用,这个问题的本质是两个生态的设计初衷不同。wire 注重 IOC 而非 AOP
IOC-Golang 的 AOP 原理与应用-51CTO.COMSpring 具备强大的依赖注入能力,在此基础之上,提供了适配与业务对象方法的 AOP 能力,可以通过定义切点,将拦截器封装在业务函数外部。这些 “切面”、“切点” 的概念,都是限定于 Spring 框架内,由其依赖注入(也就是 IOC)能力所管理。https://developer.51cto.com/article/712902.html
SHA-256 如何逐步工作
20220629
Del算符与梯度、散度、旋度与Laplacian - 知乎Del算符( abla ),在向量微积分和机器学习中很常用。在Latex中被称为Nabla,但在读时,一般读作“德儿”, abla = (\frac{\partial}{\partial x},\frac{\partial}{\partial y},\frac{\partial}{\partial z}) ;在…https://zhuanlan.zhihu.com/p/349328782
第一步,vertex shader。是将三维空间中数个(x,y,z)顶点放进 GPU 中。
在这一步骤中,电脑会在内部模拟出一个三维空间,并将这些顶点放置在这一空间内部。接着,投影在同一平面上,也是我们将看到的画面。同时,存下各点距离投影面的垂直距离,以便做后续的处理。
这个过程就像是本地球观看星星一般。地球的天空,就像是一个投影面,所有的星星,不管远近皆投影在同一面上。本地球的我们,抬起头来观看星星,分不出星星的远近,只能分辨出亮度。
GPU 所投影出的结果,和这个情况类似。
从地球所看到的星空,星星就像是投影到一球面上,除非使用特别的仪器,不然分不出星星和地球的距离
第二步,primitive processing。是将相关的点链接在一起,以形成图形。在一开始输入数个顶点进入 GPU 时,程序会特别注记哪些点是需要组合在一起,以形成一线或面。就像是看星座的时候一样,将相关连的星星连起来,形成特定的图案。
第三步,rasterisation。因为电脑的屏幕是由一个又一个的像素组成,因此,需要将一条连续的直线,使用绘图的演算法,以方格绘出该直线。图形也是以此方式,先标出边线,再用方格填满整个平面。
第四步,fragment shader。将格点化后的图形着上颜色。所需着上的颜色也是于输入时便被注记。在游玩游戏时,这一步相当耗费 GPU 的计算资源,因为光影的效果、物体表面材质皆是在这一步进行,这些计算决定着游戏画面的精细程度。因此在游玩游戏时,调高游戏画面品质大幅增加这一步的计算负担,降低游戏品质。
将一个三角形,用方格呈现近似原始图案,并着上颜色。一块又一块的方格,就是显示器上的像素
最后一步,testing and blending。便是将第一步所获得的投影垂直距离取出,和第四步的结果一同做最后处理。在去除被会被其他较近距离的物体挡住的物体后,让剩下的图形放进 GPU 的输出内存。之后,结果便会被送到电脑屏幕显示
解析GPU的工作原理! - 知乎在GPU出现以前,显卡和CPU的关系有点像“主仆”,简单地说这时的显卡就是画笔,根据各种有CPU发出的指令和数据进行着色,材质的填充、渲染、输出等。 较早的娱乐用的3D显卡又称“3D加速卡”,由于大部分坐标处理的…https://zhuanlan.zhihu.com/p/530141476
聊聊 Vue 的双端 Diff 算法-51CTO.COMdiff 算法是渲染器中最复杂的部分,也是面试的热点问题。今天我们就通过 Vue 的 diff 算法来探究下 diff 算法吧。https://developer.51cto.com/article/712614.html
(已开源)干货 | 用opencv的DNN模块做Yolov5目标检测https://mp.weixin.qq.com/s/-fwbg6KLIKM21F1BEat59Q
Redis提供了编程接口(programming interface)可以让你在Redis服务器端执行客户的脚本。
一个重大的变化就是从Redis 7开始,你可以选择使用Redis Functions去管理和运行你的脚本,而在此之前你只能使用EVAL命令执行Lua脚本。
通过EVAL命令执行的脚本是有缺陷的。如果在Redis服务器端执行了命令SCRIPT FLUSH,或者服务器重启,或者主节点执行了一个主备切换,那么存在于服务器端的脚本将会丢失,于是客户端的应用程序需要重新将整个的脚本再次发送到服务器。这个缺陷实际上说明,客户要执行的脚本需要客户端的应用程序去维护而不是Redis服务器端维护。所以,为了解决脚本的一系列问题,Redis在最新发布的7.0版本中提出了Functions这个概念。
Redis 7核心特性深度解析——Redis Functions从Redis 7开始,你可以选择使用Redis Functions去管理和运行你的脚本https://mp.weixin.qq.com/s/-0F1yqQ9Lzd6J-bWh2nDbg
离散函数的导数退化成了差分,一维一阶差分公式和二阶差分公式分别为:
Laplace(拉普拉斯)算子_Sagacity_1125的博客-CSDN博客_拉普拉斯算子目录原理原理Laplace算子作为边缘检测之一,和Sobel算子一样也是工程数学中常用的一种积分变换,属于空间锐化滤波操作。拉普拉斯算子(Laplace Operator)是n维欧几里德空间中的一个二阶微分算子,定义为梯度(▽f)的散度(▽·f)。拉普拉斯算子是二阶微分线性算子,在图像边缘处理中,二阶微分的边缘定位能力更强,锐化效果更好,因此在进行图像边缘处理时,直接采用二阶微分算子而不使用一阶微分。图1 一阶微分和二阶微分计算图离散函数的导数退化成了差分,一维一阶差分公式和二阶差分公式分别为:https://blog.csdn.net/Sagacity_1125/article/details/115508385
分布式锁一般有如下的特点:
互斥(Mutual Exclusion):同一时刻只能有一个线程持有锁
同步:获取锁失败可以阻塞,后续可被唤醒
可重入性:同一节点上的同一个线程如果获取了锁之后能够再次获取锁
避免死锁(Dead lock free):和J.U.C中的锁一样支持锁超时,防止死锁
容错(Fault tolerance):避免单点故障,锁服务要有⼀定容错性
面试官:Redis分布式锁基本原理是什么?有哪些核心设计需要注意?还有其他方案实现分布式锁吗?Redis分布式锁基本原理是什么?有哪些核心设计需要注意?还有其他方案实现分布式锁吗?如何选择?https://mp.weixin.qq.com/s/3efTmESLCBBcaDjCgnxJ1Q