当前位置: 首页 > news >正文

电子商务网站建设要多少钱/天津外贸seo推广

电子商务网站建设要多少钱,天津外贸seo推广,有哪些网站上可以做试卷,四川省建设人才网官网➢ LinkedBlockingQueue阻塞队列 LinkedBlockingQueue类图 LinkedBlockingQueue 中也有两个 Node 分别用来存放首尾节点,并且里面有个初始值为 0 的原子变量 count 用来记录队列元素个数,另外里面有两个ReentrantLock的独占锁,分别用来控制…

➢ LinkedBlockingQueue阻塞队列 

LinkedBlockingQueue 

LinkedBlockingQueue 中也有两个 Node 分别用来存放首尾节点,并且里面有个初始值为 0 的原子变量 count

用来记录队列元素个数,另外里面有两个ReentrantLock的独占锁,分别用来控制元素入队和出队加锁,其中takeLock

用来控制同时只有一个线程可以从队列获取元素,其他线程必须等待,putLock 控制同时只能有一个线程可以获取锁

去添加元素,其他线程必须等待。另外notEmpty和notFull用来实现入队和出队的同步。 另外由于出入队是两个非

公平独占锁,所以可以同时又一个线程入队和一个线程出队,其实这个是个生产者-消费者模型,

/** 通过take取出进行加锁、取出 */ 

private final ReentrantLock takeLock = new ReentrantLock(); 

/** 等待中的队列等待取出 */

private final Condition notEmpty = takeLock.newCondition(); 

/*通过put放置进行加锁、放置*/

private final ReentrantLock putLock = new ReentrantLock();

/** 等待中的队列等待放置 */

private final Condition notFull = putLock.newCondition(); 

/* 记录集合中的个数(计数器) */ 

private final AtomicInteger count = new AtomicInteger(0); 

队列的容量: 

//队列初始容量,Integer最大值 

public static final int   MAX_VALUE = 0x7fffffff;

public LinkedBlockingQueue() { 

 this(Integer.MAX_VALUE); 

}

 public LinkedBlockingQueue(int capacity) { 

 if (capacity <= 0) throw new IllegalArgumentException(); 

 this.capacity = capacity; 

 //初始化首尾节点 

 last = head = new Node<E>(null); 

}

如图默认队列容量为0x7fffffff;用户也可以自己指定容量。 

LinkedBlockingQueue 

ps:下面介绍LinkedBlockingQueue用到很多Lock对象。详细可以查找Lock对象的介绍 

✓  带时Offer- 

在ArrayBlockingQueue中已经简单介绍了Offer()方法,LinkedBlocking的Offer 方法类似,在此就不过多去

介绍。这次我们从介绍下带时间的Offer方法 

public boolean offer(E e, long timeout, TimeUnit unit)

 throws InterruptedException { 

 //空元素抛空指针异常 

 if (e == null) throw new NullPointerException(); 

 long nanos = unit.toNanos(timeout); 

 int c = -1;

 final ReentrantLock putLock = this.putLock; 

 final AtomicInteger count = this.count;

 //获取可被中断锁,只有一个线程克获取 

 putLock.lockInterruptibly(); 

 try {

 //如果队列满则进入循环 

 while (count.get() == capacity) { 

 //nanos<=0直接返回 

 if (nanos <= 0) 

 return false; 

 //否者调用await进行等待,超时则返回<=0(1) 

 nanos = notFull.awaitNanos(nanos); 

 }

 //await在超时时间内返回则添加元素(2) 

 enqueue(new Node<E>(e)); 

 c = count.getAndIncrement(); 

 //队列不满则激活其他等待入队线程(3) 

 if (c + 1 < capacity) 

 notFull.signal(); 

 } finally {

 //释放锁 

 putLock.unlock();

 }

 //c==0说明队列里面有一个元素,这时候唤醒出队线程(4) 

 if (c == 0)

 signalNotEmpty();

 return true;

}

private void enqueue(Node<E> node) { 

 last = last.next = node; 

}

 private void signalNotEmpty() { 

 final ReentrantLock takeLock = this.takeLock; 

 takeLock.lock();

 try {

 notEmpty.signal(); 

 } finally {

 takeLock.unlock(); 

 }

 }

✓  带时poll- 

获取并移除队首元素,在指定的时间内去轮询队列看有没有首元素有则返回,否者超时后返回null。 

public E poll(long timeout, TimeUnit unit) throws InterruptedException {   E x = null;

 int c = -1;

 long nanos = unit.toNanos(timeout); 

 final AtomicInteger count = this.count; 

 final ReentrantLock takeLock = this.takeLock; 

 //出队线程获取独占锁 

 takeLock.lockInterruptibly(); 

 try {

 //循环直到队列不为空 

 while (count.get() == 0) { 

 //超时直接返回null 

 if (nanos <= 0) 

 return null; 

 nanos = notEmpty.awaitNanos(nanos); 

 }

 //出队,计数器减一 

 x = dequeue();

 c = count.getAndDecrement(); 

 //如果出队前队列不为空则发送信号,激活其他阻塞的出队线程 

 if (c > 1)

 notEmpty.signal(); 

 } finally {

 //释放锁 

 takeLock.unlock(); 

 }

 //当前队列容量为最大值-1则激活入队线程。 

 if (c == capacity)

 signalNotFull();

 return x;

首先获取独占锁,然后进入循环当当前队列有元素才会退出循环,或者超时了,直接返回null。 

超时前退出循环后,就从队列移除元素,然后计数器减去一,如果减去1 前队列元素大于1 则说明当前移除后队

列还有元素,那么就发信号激活其他可能阻塞到当前条件信号的线程。 

最后如果减去 1 前队列元素个数=最大值,那么移除一个后会腾出一个空间来,这时候可以激活可能存在的入队阻塞线程。 

✓  put- 

与带超时时间的poll类似不同在于put时候如果当前队列满了它会一直等待其他线程调用notFull.signal才会被

唤醒。 

✓  take-费者 

与带超时时间的poll类似不同在于take时候如果当前队列空了它会一直等待其他线程调用notEmpty.signal()才

会被唤醒。 

✓  size操作- 

当前队列元素个数,如代码直接使用原子变量count获取。 

public int size() {

 return count.get();

}

✓  peek操作 

获取但是不移除当前队列的头元素,没有则返回null。 

public E peek() {

 //队列空,则返回null

 if (count.get() == 0) 

 return null;

 final ReentrantLock takeLock = this.takeLock; 

 takeLock.lock();

 try {

 Node<E> first = head.next; 

 if (first == null) 

 return null; 

 else

 return first.item; 

 } finally {

 takeLock.unlock(); 

 }

}

✓  remove操作 

删除队列里面的一个元素,有则删除返回true,没有则返回false,在删除操作时候由于要遍历队列所以加了双重

锁,也就是在删除过程中不允许入队也不允许出队操作。 

public boolean remove(Object o) { 

 if (o == null) return false; 

 //双重加锁 

 fullyLock();

 try {

 //遍历队列找则删除返回true 

 for (Node<E> trail = head, p = trail.next; 

 p != null;

 trail = p, p = p.next) { 

 if (o.equals(p.item)) { 

 unlink(p, trail); 

 return true; 

 }

 }

 //找不到返回false

 return false;

 } finally {

 //解锁 

 fullyUnlock();

 }

}

void fullyLock() {

 putLock.lock();

 takeLock.lock();

}

void fullyUnlock() {

 takeLock.unlock();

 putLock.unlock();

}

void unlink(Node<E> p, Node<E> trail) { 

 p.item = null;

 trail.next = p.next;

 if (last == p)

 last = trail;

 //如果当前队列满,删除后,也不忘记最快的唤醒等待的线程 

 if (count.getAndDecrement() == capacity) 

 notFull.signal();

}

✓  开源使 

tomcat中任务队列TaskQueue。 

类结 

可知TaskQueue继承了LinkedBlockingQueue并且泛化类型固定了为Runnalbe.重写了offer,poll,take方法。 tomcat 中有个线程池 ThreadPoolExecutor,在 NIOEndPoint 中当 acceptor 线程接受到请求后,会把任务放入队列,然后poller 线程从队列里面获取任务,然后就把任务放入线程池执行。这个ThreadPoolExecutor中的的一个参数就是TaskQueue。 

先看看ThreadPoolExecutor的参数如果是普通LinkedBlockingQueue是怎么样的执行逻辑: 当调用线程池方法  execute() 方法添加一个任务时: 

l  如果当前运行的线程数量小于  corePoolSize,则创建新线程运行该任务 

l  如果当前运行的线程数量大于或等于  corePoolSize,则将这个任务放入阻塞队列。 

l  如果当前队列满了,并且当前运行的线程数量小于  maximumPoolSize,则创建新线程运行该任务; 

l  如果当前队列满了,并且当前运行的线程数量大于或等于  maximumPoolSize,那么线程池将会抛出

RejectedExecutionException异常。 

如果线程执行完了当前任务,那么会去队列里面获取一个任务来执行,如果任务执行完了,并且当前线程数大于

corePoolSize,那么会根据线程空闲时间keepAliveTime回收一些线程保持线程池corePoolSize个线程。 

首先看下线程池中exectue添加任务时候的逻辑: 

public void execute(Runnable command) { 

 if (command == null)

 throw new NullPointerException();

 //当前工作线程个数小于core个数则开新线程执行(1) 

 int c = ctl.get();

 if (workerCountOf(c) < corePoolSize) { 

 if (addWorker(command, true)) 

 return;

 c = ctl.get();

 }

 //放入队列(2) 

 if (isRunning(c) && workQueue.offer(command)) {

 int recheck = ctl.get(); 

 if (! isRunning(recheck) && remove(command)) 

 reject(command); 

 else if (workerCountOf(recheck) == 0) 

 addWorker(null, false); 

 }

 //如果队列满了则开新线程,但是个数要不超过最大值,超过则返回false

 //然后执行reject handler(3) 

 else if (!addWorker(command, false)) 

 reject(command);

}

可知当当前工作线程个数为corePoolSize后,如果在来任务会把任务添加到队列,队列满了或者入队失败了则开启新线程。 

然后看看TaskQueue中重写的offer方法的逻辑: 

public boolean offer(Runnable o) { 

 // 如果parent为null则直接调用父类方法 

 if (parent==null) return super.offer(o); 

 //如果当前线程池中线程个数达到最大,则无条件调用父类方法 

 if (parent.getPoolSize() == parent.getMaximumPoolSize()) return super.offer(o); 

 //如果当前提交的任务小于当前线程池线程数,说明线程用不完,没必要重新开线程 

 if (parent.getSubmittedCount()<(parent.getPoolSize())) return super.offer(o);

 //如果当前线程池线程个数>core个数但是小于最大个数,则开新线程代替放入队列 

 if (parent.getPoolSize()<parent.getMaximumPoolSize()) return false; 

 //到了这里,无条件调用父类 

 return super.offer(o); 

}

可知parent.getPoolSize()<parent.getMaximumPoolSize()普通队列会把当前任务放入队列,TaskQueue则是返回false,因为这会开启新线程执行任务,当然前提是当前线程个数没有达到最大值。 

LinkedBlockingQueue安全总结 
仔细思考下阻塞队列是如何实现并发安全的维护队列链表的,先分析下简单的情况就是当队列里面有多个元素时候,由于同时只有一个线程(通过独占锁putLock实现)入队元素并且是操作last节点(,而同时只有一个出队线程(通过独占锁takeLock实现)操作head节点,所以不存在并发安全问题。 

考虑当队列为空的时候队列状态为: 

这时候假如一个线程调用了 take 方法,由于队列为空,所以 count.get()==0 所以当前线程会调用notEmpty.await()把自己挂起,并且放入 notEmpty 的条件队列,并且释放当前条件变量关联的通过takeLock.lockInterruptibly()获取的独占锁。由于释放了锁,所以这时候其他线程调用 take 时候就会通过takeLock.lockInterruptibly()获取独占锁,然后同样阻塞到notEmpty.await(),同样会被放入notEmpty的条件队列,也就说在队列为空的情况下可能会有多个线程因为调用take被放入了notEmpty的条件队列。 

这时候如果有一个线程调用了 put 方法,那么就会调用 enqueue 操作,该操作会在 last 节点后面添加新元素并且设置 last 为新节点。然后 count.getAndIncrement()先获取当前队列元个数为 0 保存到 c,然后自增 count 为 1 ,由于 c==0 所以调用 signalNotEmpty 激活notEmpty 的条件队列里面的阻塞时间最长的线程,这时候 take 中调用notEmpty.await()的线程会被激活await内部会重新去获取独占锁获取成功则返回,否者被放入AQS的阻塞队列,如果获取成功,那么count.get() >0因为可能多个线程put了,所以调用dequeue从队列获取元素(这时候一定可以获取到),然后调用c = count.getAndDecrement() 把当前计数返回后并减去1,如果c>1 说明当前队列还有其他元素,那么就调用  notEmpty.signal()去激活  notEmpty的条件队列里面的其他阻塞线程。 

考虑当队列满的时候: 

当队列满的时候调用 put 方法时候,会由于 notFull.await()当前线程被阻塞放入 notFull 管理的条件队列里面,同理可能会有多个调用put方法的线程都放到了notFull的条件队列里面。 

这时候如果有一个线程调用了take方法,调用dequeue()出队一个元素,c = count.getAndDecrement();count值减一;c==capacity;现在队列有一个空的位置,所以调用 signalNotFull()激活 notFull 条件队列里面等待最久的一个线程。 

LinkedBlockingQueue简单示例 
并发库中的BlockingQueue 是一个比较好玩的类,顾名思义,就是阻塞队列。该类主要提供了两个方法put()和take(),前者将一个对象放到队列中,如果队列已经满了,就等待直到有空闲节点;后者从head取一个对象,如果没有对象,就等待直到有可取的对象。 

下面的例子比较简单,一个读线程,用于将要处理的文件对象添加到阻塞队列中, 另外四个写线程用于取出文件对象,为了模拟写操作耗时长的特点,特让线程睡眠一段随机长度的时间。另外,该Demo也使用到了线程池和原子整型 (AtomicInteger),AtomicInteger可以在并发情况下达到原子化更新,避免使用了synchronized,而且性能非常高。由 于阻塞队列的 put 和 take 操作会阻塞,为了使线程退出,特在队列中添加了一个“标识”,算法中也叫“哨兵”,当发现这个哨兵后,写线程就退出。 

当然线程池也要显式退出了。 

package concurrent;

 import java.io.File;

 import java.io.FileFilter;

 import java.util.concurrent.BlockingQueue;

 import java.util.concurrent.ExecutorService;

 import java.util.concurrent.Executors;

 import java.util.concurrent.LinkedBlockingQueue;

 import java.util.concurrent.atomic.AtomicInteger;

 public class TestBlockingQueue {

 static long randomTime() { 

 return (long) (Math.random() * 1000); 

 } 

 public static void main(String[] args) { 

 // 能容纳100个文件 
 final BlockingQueue<File> queue = new LinkedBlockingQueue<File>(100);  // 线程池 
 final ExecutorService exec = Executors.newFixedThreadPool(5); 
 final File root = new File("F:\\JavaLib"); 

 // 完成标志 

 final File exitFile = new File("");

 // 读个数 

 final AtomicInteger rc = new AtomicInteger(); 

 // 写个数 

 final AtomicInteger wc = new AtomicInteger(); 

 // 读线程 

 Runnable read = new Runnable() { 

 public void run() {

 scanFile(root);

 scanFile(exitFile);

 } 

 public void scanFile(File file) { 

 if (file.isDirectory()) {

 File[] files = file.listFiles(new FileFilter() {

 public boolean accept(File pathname) {

 return pathname.isDirectory()

 || pathname.getPath().endsWith(".java");

 }

 });

 for (File one : files)

 scanFile(one);

 } else {

 try {

 int index = rc.incrementAndGet();

 System.out.println("Read0: " + index + " "

 + file.getPath());

 queue.put(file);

 } catch (InterruptedException e) {

 }

 }

 } 

 };

 exec.submit(read); 

 // 四个写线程 

 for (int index = 0; index < 4; index++) {

 // write thread 

 final int NO = index;

 Runnable write = new Runnable() {

 String threadName = "Write" + NO;

 public void run() {

 while (true) {

 try {

 Thread.sleep(randomTime());

 int index = wc.incrementAndGet();

 File file = queue.take();

 // 队列已经无对象 

 if (file == exitFile) {

 // 再次添加"标志",以让其他线程正常退出 

 queue.put(exitFile);

 break;

 }

 System.out.println(threadName + ": " + index + " "

 + file.getPath());

 } catch (InterruptedException e) {

 }

 }

 }

 }; 

 exec.submit(write);

 }

 exec.shutdown(); 

 }

}

相关文章:

LinkedBlockingQueue阻塞队列

➢ LinkedBlockingQueue阻塞队列 LinkedBlockingQueue类图 LinkedBlockingQueue 中也有两个 Node 分别用来存放首尾节点&#xff0c;并且里面有个初始值为 0 的原子变量 count 用来记录队列元素个数&#xff0c;另外里面有两个ReentrantLock的独占锁&#xff0c;分别用来控制…...

面试-Redis 常见问题,后续面试遇到新的在补充

面试-Redis 1.谈谈Redis 缓存穿透&#xff0c;击穿&#xff0c;雪崩及如何避免 缓存穿透&#xff1a;是指大量访问请求在访问一个不存在的key&#xff0c;由于key 不存在&#xff0c;就会去查询数据库&#xff0c;数据库中也不存在该数据&#xff0c;无法将数据存储到redis 中…...

2023年上半年数据库系统工程师上午真题及答案解析

1.计算机中, 系统总线用于( )连接。 A.接口和外设 B.运算器、控制器和寄存器 C.主存及外设部件 D.DMA控制器和中断控制器 2.在由高速缓存、主存和硬盘构成的三级存储体系中&#xff0c;CPU执行指令时需要读取数据&#xff0c;那么DMA控制器和中断CPU发出的数据地…...

设计模式概念

设计模式是软件工程领域中常用的解决问题的经验总结和最佳实践。它们提供了一套被广泛接受的解决方案&#xff0c;用于处理常见的设计问题&#xff0c;并促进可重用、可扩展和易于维护的代码。 设计模式的主要目标是提高软件的可重用性、可扩展性和灵活性&#xff0c;同时降低…...

arcpy批量对EXCE经纬度L进行投点,设置为wgs84坐标系,并利用该点计算每个区域内的核密度

以下是在 ArcPy 中批量对 Excel 经纬度 L 进行投点&#xff0c;设置为 WGS84 坐标系&#xff0c;并利用该点计算每个区域内的核密度的详细步骤&#xff1a; 1. 准备数据: 准备包含经纬度信息的 Excel 数据表格&#xff0c;我们假设文件路径为 "C:/Data/locations.xlsx&qu…...

Yolov5训练自己的数据集

先看下模型pt说明 YOLOv5s&#xff1a;这是 YOLOv5 系列中最小的模型。“s” 代表 “small”&#xff08;小&#xff09;。该模型在计算资源有限的设备上表现最佳&#xff0c;如移动设备或边缘设备。YOLOv5s 的检测速度最快&#xff0c;但准确度相对较低。 YOLOv5m&#xff1…...

Bert+FGSM中文文本分类

我上一篇博客已经分别用BertFGSM和BertPGD实现了中文文本分类&#xff0c;这篇文章与我上一篇文章BertFGSM/PGD实现中文文本分类&#xff08;Loss0.5L10.5L2)_Dr.sky_的博客-CSDN博客的不同之处在于主要在对抗训练函数和embedding添加扰动部分、模型定义部分、Loss函数传到部分…...

爬楼梯问题-从暴力递归到动态规划(java)

爬楼梯&#xff0c;每次只能爬一阶或者两阶&#xff0c;计算有多少种爬楼的情况 爬楼梯--题目描述暴力递归递归缓存动态规划暴力递归到动态规划专题 爬楼梯–题目描述 一个总共N 阶的楼梯&#xff08;N > 0&#xff09; 每次只能上一阶或者两阶。问总共有多少种爬楼方式。 示…...

浏览器如何验证SSL证书?

浏览器如何验证SSL证书&#xff1f;当前SSL证书应用越来越广泛&#xff0c;我们看见的HTTPS网站也越来越多。点击HTTPS链接签名的绿色小锁&#xff0c;我们可以看见SSL证书的详细信息。那么浏览器是如何验证SSL证书的呢? 浏览器如何验证SSL证书&#xff1f; 在浏览器的菜单中…...

Linux :: 【基础指令篇 :: 文件及目录操作:(10)】:: ll 指令 :: 查看指定目录下的文件详细信息

前言&#xff1a;本篇是 Linux 基本操作篇章的内容&#xff01; 笔者使用的环境是基于腾讯云服务器&#xff1a;CentOS 7.6 64bit。 学习集&#xff1a; C 入门到入土&#xff01;&#xff01;&#xff01;学习合集Linux 从命令到网络再到内核&#xff01;学习合集 目录索引&am…...

Java字符集/编码集

1 字符集/编码集 基础知识 计算机中储存的信息都是用二进制数表示的;我们在屏幕上看到的英文、汉字等字符是二进制数转换之后的结果 按照某种规则, 将字符存储到计算机中,称为编码。反之,将存储在计算机中的二进制数按照某种规则解析显示出来,称为解码。这里强调一下: 按照…...

Apache配置与应用

目录 虚拟web主机httpd服务支持的虚拟主机类型基于域名配置方法基于IP配置方法基于端口配置方法 apache连接保持构建Web虚拟目录与用户授权限制Apache日志分割 虚拟web主机 虚拟Web主机指的是在同一台服务器中运行多个Web站点&#xff0c;其中每一个站点实际上并不独立占用整个…...

API自动化测试【postman生成报告】

PostMan生成测试报告有两种&#xff1a; 1、控制台的模式 2、HTML的测试报告 使用到一个工具newman Node.js是前端的一个组件&#xff0c;主要可以使用它来开发异步的程序。 一、控制台的模式 1、安装node.js 双击node.js进行安装&#xff0c;安装成功后在控制台输入node …...

探索OpenAI插件:ChatWithGit,memecreator,boolio

引言 在当今的技术世界中&#xff0c;插件扮演着至关重要的角色&#xff0c;它们提供了一种简单有效的方式来扩展和增强现有的软件功能。在本文中&#xff0c;我们将探索三个OpenAI的插件&#xff1a;ChatWithGit&#xff0c;memecreator&#xff0c;和boolio&#xff0c;它们…...

linux irq

中断上下部 软中断、tasklet、工作对列 软中断优点&#xff1a;运行在软中断上下文&#xff0c;优先级比普通进程高&#xff0c;调度速度快。 缺点&#xff1a;由于处于中断上下文&#xff0c;所以不能睡眠。 相对于软中断/tasklet&#xff0c;工作对列运行在进程上下文 h…...

串口流控(CTS/RTS)使用详解

1.流控概念 在两个设备正常通信时&#xff0c;由于处理速度不同&#xff0c;就存在这样一个问题&#xff0c;有的快&#xff0c;有的慢&#xff0c;在某些情况下&#xff0c;就可能导致丢失数据的情况。 如台式机与单片机之间的通讯&#xff0c;接收端数据缓冲区已满&#xff0…...

kube-proxy模式详解

1 kube-proxy概述 kubernetes里kube-proxy支持三种模式&#xff0c;在v1.8之前我们使用的是iptables 以及 userspace两种模式&#xff0c;在kubernetes 1.8之后引入了ipvs模式&#xff0c;并且在v1.11中正式使用&#xff0c;其中iptables和ipvs都是内核态也就是基于netfilter&…...

汽车EDI:如何与Stellantis建立EDI连接?

Stellantis 是一家实力雄厚的汽车制造公司&#xff0c;由法国标致雪铁龙集团&#xff08;PSA集团&#xff09;和意大利菲亚特克莱斯勒汽车集团&#xff08;FCA集团&#xff09;合并而成&#xff0c;是世界上第四大汽车制造商&#xff0c;拥有包括标致、雪铁龙、菲亚特、克莱斯勒…...

【SCI征稿】1区计算机科学类SCI, 自引率低,对国人友好~

一、【期刊简介】 JCR1区计算机科学类SCI&EI 【期刊概况】IF: 7.0-8.0&#xff0c;JCR1区&#xff0c;中科院2区&#xff1b; 【终审周期】走期刊系统&#xff0c;3-5个月左右录用; 【检索情况】SCI&EI双检&#xff1b; 【自引率】1.30% 【征稿领域】发表人工智能…...

Vue.js优化策略与性能调优指南

导语&#xff1a;Vue.js是一款出色的前端框架&#xff0c;但在处理大规模应用或复杂场景时&#xff0c;性能问题可能会出现。本文将介绍一些Vue.js优化策略和性能调优指南&#xff0c;帮助您提升应用的性能和用户体验。 延迟加载&#xff1a;将应用的代码进行按需加载&#xff…...

HEVC环路后处理核心介绍

介绍 为什么需要环路后处理技术 hevc采用基于快的混合编码框架&#xff0c;方块效应、振铃效应、颜色偏差、图像模糊等失真效应依旧存在&#xff0c;为了降低此类失真影响&#xff0c;需要进行环路滤波技术&#xff1b; 采用的技术 去方块滤波DF&#xff0c;为了降低块效应…...

从组件化角度聊聊设计工程化

目录 设计系统 设计系统的定义 设计系统的优势 设计系统存在的问题 设计工程化 设计系统探索 设计系统落地实践 Design Token Design Token 实践 设计工程化理想方案构想 展望 参考文献 近几年围绕业务中台化的场景&#xff0c;涌现出了许多低代码平台。面对多组件…...

apache的配置和应用

文章目录 一、httpd服务支持的虚拟主机类型包括以下三种:二、构建Web虚拟目录与用户授权限制三、日志分割 虚拟Web主机指的是在同一台服务器中运行多个Web站点&#xff0c;其中每一个站点实际上并不独立占用整个服务器&#xff0c;因此被称为“虚拟”Web 主机。通过虚拟 Web 主…...

Buf 教程 - 使用 Protobuf 生成 Golang 代码和 Typescript 类型定义

简介 Buf 是一款更高效、开发者友好的 Protobuf API 管理工具&#xff0c;不仅支持代码生成&#xff0c;还支持插件和 Protobuf 格式化。 我们可以使用 Buf 替代原本基于 Protoc 的代码生成流程&#xff0c;一方面可以统一管理团队 Protoc 插件的版本、代码生成配置&#xff…...

Java 锁 面试题(ReentrantLock、synchronized)

Java 锁 面试题&#xff08;ReentrantLock、synchronized&#xff09; 1. 锁2. ReentrantLock2.1 ReentrantLock 的实现原理2.2 AQS 是什么&#xff1f;2.3 CAS 是什么&#xff1f; 3. synchronized3.1 synchronized 的实现原理3.2 synchronized 的锁升级过程3.2.1 无锁3.2.2 偏…...

Python中的缩进是什么意思?

在Python中&#xff0c;缩进是指在代码中使用空格或制表符来表示代码块的层次结构。Python使用缩进作为语法的一部分&#xff0c;以定义代码的逻辑结构和代码块的范围。缩进在Python中具有以下几个重要的方面和含义。 代码块的开始和结束&#xff1a; 缩进在Python中用于标识代…...

2023年9月数学建模:最小二乘优化、曲线拟合与函数逼近

2023年9月数学建模国赛期间提供ABCDE题思路加Matlab代码,专栏链接(赛前一个月恢复源码199,欢迎大家订阅):http://t.csdn.cn/Um9Zd 目录 1. 最小二乘优化 1.1 最小二乘优化的原理 1.2 最小二乘优化的方法...

java8内部调用无法引用值的问题

问题&#xff1a;Variable used in lambda expression should be final or effectively final 具体原因&#xff1a; 这段代码试图将 20 赋给一个局部变量&#xff0c;它无法通过编译&#xff0c;但绝非编写错误。 这实际上是语言的设计者有意为之&#xff0c;用以鼓励用户使用…...

《嵌入式系统》知识总结10:使用位带操作操纵GPIO

位操作 汇编层面 外设控制常要针对字中某个位&#xff08;Bit&#xff09;操作 以字节编址的存储器地址空间中&#xff0c;需要3步骤&#xff08;读出-修改-写回&#xff09; 1.&#xff08;从外设&#xff09;读取包含该位的字节数据 2. 设置该位为0或1、同时屏蔽其他位&am…...

leetcode 2.两数相加(链表操作)

题目描述跳转到leetcode 给你两个 非空 的链表&#xff0c;表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的&#xff0c;并且每个节点只能存储 一位 数字。 请你将两个数相加&#xff0c;并以相同形式返回一个表示和的链表。 你可以假设除了数字 0 之外&#xff0…...