背景: 一般情况下,我们使用huggingface都是从其网站上直接加载数据集进行训练,代码如下:
from datasets import load_dataset food = load_dataset("food101") 写了上面的代码,那么load_dataset函数就会自动从huggingface上面下载数据集到本地,然后缓存起来。
可对于我们自己的数据集该如何加载呢?尤其是图片数据集,对于模型来说,他需要的数据格式如下:
{'image': <PIL.JpegImagePlugin.JpegImageFile image mode=RGB size=512x512 at 0x7F52AFC8AC50>, 'label': 79} 从上述代码可以看到,image是一个PIL格式的图片,而我们本地是一个图片文件,如何将本地的图片转换成PIL的图片呢?
下面我们就来讲一讲如何加载本地数据集。
数据集目录结构 dataset --image --1.jsp --2.jsp --…… --image.json --label.json 目录结构说明 1、image文件夹
存储所有的图片
2、image.json
存储map结构的json字符串,key是图片的名称,value是图片对应的标签分类
{ "1.jpg": 0, "2.jpg": 0, "3.jpg": 1, "4.jpg": 1, "5.jpg": 4, "6.jpg": 4, "7.jpg": 2, "8.jpg": 2, "9.jpg": 3, "10.jpg": 3 } 3、label.json
存储map结构的json字符串,key是标签的名称,value是标签的分类
{ "apple": 0, "pear": 1, "strawberry": 2, "peach": 3, "chestnut": 4 } 代码 如何将上述的目录结构存储的数据转换成模型需要的格式呢?
1、什么是死锁?死锁产生的条件? 1.1、什么是死锁? 答: 在两个或者多个并发进程中,如果每个进程持有某种资源而又等待其它进程释放它或它们现在保持着的资源,在未改变这种状态之前都不能向前推进,称这一组进程产生了死锁。通俗的讲就是两个或多个进程无限期的阻塞、相互等待的一种状态。
1.2、死锁产生的四个必要条件? 互斥条件: 一个资源一次只能被一个进程使用;请求与保持条件:一个进程因请求资源而阻塞时,对已获得资源保持不放;不剥夺条件: 进程获得的资源,在未完全使用完之前,不能强行剥夺;循环等待条件: 若干进程之间形成一种头尾相接的环形等待资源关系。 1.3、如何处理死锁问题? 忽略该问题:例如鸵鸟算法,该算法可以应用在极少发生死锁的的情况下。为什么叫鸵鸟算法呢,因为传说中鸵鸟看到危险就把头埋在地底下,可能鸵鸟觉得看不到危险也就没危险了吧。跟掩耳盗铃有点像;检测死锁并且恢复;仔细地对资源进行动态分配,以避免死锁;通过破除死锁四个必要条件之一,来防止死锁产生。 2、死锁的解决办法 预防死锁: 通过破坏死锁四个必要条件之一,来防止死锁产生;避免死锁: 在资源的动态分配过程中,用某种方法防止系统进入不安全状态,从而避免发生死锁;检测死锁: 允许进程在运行过程中发生死锁,但是可以通过检测机构及时检测出死锁,然后通过合适的措施,把进程从死锁过程中解脱出来;解除死锁: 当检测系统中已经发生死锁时,就采用相应措施,将进程从死锁状态中解脱出来。忽略死锁: 比如:鸵鸟算法,当系统发生死锁时不会对用户造成多大影响,或系统很少发生死锁的场合。 3、预防死锁 3.1、破坏“不抢占”条件 答:当某个进程请求新的资源得不到满足时,便立即释放保持的所有资源,待以后需要时再重新申请。
缺点是实现复杂,抢占资源可能导致部分工作失效,反复申请和释放导致系统开销很大,也可能导致饥饿。
3.2、破坏“请求和保持”条件 答:我们必须保证:当一个进程在请求资源时,它不能持有不可抢占的系统资源。在此,有两种协议可供选择:
第一种协议: 该协议规定,所有进程在开始运行之前,必须一次性地申请其在整个运行过程中所需的全部资源。此时若系统有足够的资源分配给某进程,便可把其需要的所有资源分配给它,这样,该进程在整个运行期间,便不会再提出资源要求,从而破坏了“请求”条件。系统在分配究源时,只要有一种资源不能满足进程的要求,即使其它所需的各资源都空闲也不分配给该进程;
第一种协议虽然简单易行且安全,但是它导致资源被严重浪费,严重的降低了资源的利用率;进程会经常发生饥饿现象。 因此比较推荐第二种协议。
第二种协议: 该协议是对第一种协议的改进,它允许一个进程只获得运行初期所需的资源后,便开始运行。进程运行过程中再逐步释放已分配给自己的、且已用毕的全部资源,然后再请求新的所需资源。
3.3、破坏“循环等待”条件 答:
具体做法: 首先给系统中的资源编号,规定每个进程必须按编号递增的顺序请求资源,同类资源(即编号相同的资源) 一次性申请完;原理: 一个进程只有已占有小编号的资源时,才有资格申请更大编号的资源。按此规则,已持有大编号资源的进程不可能逆向地回来申请小编号的资源,从而就不会产生循环等待的现象,进而预防死锁的发生。 缺点 不方便增加新的设备,因为可能需要重新分配所有的编号;进程实际使用资源的顺序可能和编号递增顺序不一致,会导致资源浪费;必须按规定次序申请资源,用户编程麻烦。 在这里,我们需要解释一下,为什么产生死锁的必要条件是4个,但是在预防死锁的时候,我们没有介绍怎么破坏互斥条件,理由如下:互斥条件是非共享设备所必备的,不仅不能改变,反而还应该加以保护。
4、避免死锁(银行家算法) 答:在避免死锁的方法中,把系统的状态分为两种:安全状态(是指系统能按某种顺序如<P1,P2,…,Pn>(称<P1,P2,…Pn>序列为安全序列),来为每个进程分配其所需资源,直到最大需求,使每个进程都可顺序完成。)和不安全状态,当系统处于安全状态时,可以避免死锁的发生,反之,当系统处于不安全状态时,可能导致死锁的发生。
当有一个进程请求一个可用资源时,系统需要对该进程的请求进行计算,若将资源分配给进程后系统仍处于安全状态,才将资源分配给该进程。
5、死锁的检测与解除 答: 为了能对系统中是否已经发生了死锁进行检测,在系统中必须:
(1)保存有关资源的请求和分配信息;
(2)提供一种算法,它利用这些信息来检测系统是否进入死锁状态。
5.1、检测死锁的算法中 在资源分配图中,找出既不阻塞又非独立的进程结点Pi,在顺利的情况下,Pi可以得到所需的资源而继续运行,直至完成,然后释放它所占有的所有资源。这相当于消去它所有的请求边和分配边,使之称为孤立的结点。进程Pi所释放的资源,可以唤醒某些因等待这些资源而阻塞的进程,原来的阻塞进程可能变为非阻塞进程。然后重复上面的过程,消去请求边和分配边。若能消去图中所有的边,使得图中的进程结点变为孤立点,则称该图是可完全简化的,否则称该图是不可完全简化的。 有文献证明: 所有的简化顺序都将得到相同的不可简化图。
死锁定理表明: 如果某时刻系统的资源分配图是不可完全简化的,那么此时系统死锁
5.2、解除死锁 抢占资源: 从一个或者多个进程中抢占足够多数量的资源,分配给死锁进程,以解除死锁。终止进程法(包括终止所有死锁进程和逐个终止进程): 终止系统中的一个或多个死锁进程,纸质打破循环环路,使系统从死锁状态中解脱出来。进程回退法。
1、虚拟内存 答: 这个在我们平时使用电脑特别是 Windows 系统的时候太常见了。很多时候我们使用点开了很多占内存的软件,这些软件占用的内存可能已经远远超出了我们电脑本身具有的物理内存。为什么可以这样呢? 正是因为虚拟内存的存在,通过虚拟内存可以让程序可以拥有超过系统物理内存大小的可用内存空间。另外,虚拟内存为每个进程提供了一个一致的、私有的地址空间,它让每个进程产生了一种自己在独享主存的错觉(每个进程拥有一片连续完整的内存空间)。这样会更加有效地管理内存并减少出错。
虚拟内存是计算机系统内存管理的一种技术,我们可以手动设置自己电脑的虚拟内存。不要单纯认为虚拟内存只是“使用硬盘空间来扩展内存“的技术。虚拟内存的重要意义是它定义了一个连续的虚拟地址空间,并且 把内存扩展到硬盘空间。
2、内存管理的目的 答: 最主要的就是提高内存的利用率,所谓的提高内存利用率,就是尽可能的在内存中多存储进程,这就涉及到为进程分配内存空间了。分配的方式主要是有两种——连续分配和离散分配。
3、局部性原理 答:局部性原理是虚拟内存技术的基础,正是因为程序运行具有局部性原理,才可以只装入部分程序到内存就开始运行。
局部性原理表现在以下两个方面: 时间局部性 :如果程序中的某条指令一旦执行,不久以后该指令可能再次执行;如果某数据被访问过,不久以后该数据可能再次被访问。产生时间局部性的典型原因,是由于在程序中存在着大量的循环操作。空间局部性 :一旦程序访问了某个存储单元,在不久之后,其附近的存储单元也将被访问,即程序在一段时间内所访问的地址,可能集中在一定的范围之内,这是因为指令通常是顺序存放、顺序执行的,数据也一般是以向量、数组、表等形式簇聚存储的。 4、虚拟存储器 答:基于局部性原理,在程序装入时,可以将程序的一部分装入内存,而将其他部分留在外存,就可以启动程序执行。由于外存往往比内存大很多,所以我们运行的软件的内存大小实际上是可以比计算机系统实际的内存大小大的。在程序执行过程中,当所访问的信息不在内存时,由操作系统将所需要的部分调入内存,然后继续执行程序。另一方面,操作系统将内存中暂时不使用的内容换到外存上,从而腾出空间存放将要调入内存的信息。这样,计算机好像为用户提供了一个比实际内存大的多的存储器——虚拟存储器。
我觉得虚拟内存同样是一种时间换空间的策略,你用 CPU 的计算时间,页的调入调出花费的时间,换来了一个虚拟的更大的空间来支持程序的运行。不得不感叹,程序世界几乎不是时间换空间就是空间换时间。
5、虚拟内存的技术实现 答:虚拟内存的实现需要建立在离散分配的内存管理方式的基础上。 虚拟内存的实现有以下三种方式:
请求分页存储管理:建立在分页管理之上,为了支持虚拟存储器功能而增加了请求调页功能和页面置换功能。请求分页是目前最常用的一种实现虚拟存储器的方法。请求分页存储管理系统中,在作业开始运行之前,仅装入当前要执行的部分段即可运行。假如在作业运行的过程中发现要访问的页面不在内存,则由处理器通知操作系统按照对应的页面置换算法将相应的页面调入到主存,同时操作系统也可以将暂时不用的页面置换到外存中。请求分段存储管理:建立在分段存储管理之上,增加了请求调段功能、分段置换功能。请求分段储存管理方式就如同请求分页储存管理方式一样,在作业开始运行之前,仅装入当前要执行的部分段即可运行;在执行过程中,可使用请求调入中断动态装入要访问但又不在内存的程序段;当内存空间已满,而又需要装入新的段时,根据置换功能适当调出某个段,以便腾出空间而装入新的段。请求段页式存储管理 请求分页与分页存储管理,两者有何不同呢? 请求分页存储管理建立在分页管理之上。他们的根本区别是是否将程序全部所需的全部地址空间都装入主存,这也是请求分页存储管理可以提供虚拟内存的原因,我们在上面已经分析过了。它们之间的根本区别在于是否将一作业的全部地址空间同时装入主存。请求分页存储管理不要求将作业全部地址空间同时装入主存。基于这一点,请求分页存储管理可以提供虚存,而分页存储管理却不能提供虚存。 6、什么是页面置换算法 答:进程运行时,若其访问的页面不在内存而需将其调入,但内存已无空闲空间时,就需要从内存中调出一页程序或数据,送入磁盘的对换区,其中选择调出页面的算法就称为页面置换算法。
好的页面置换算法应有较低的页面更换频率,也就是说,应将以后不会再访问或者以后较长时间内不会再访问的页面先调出。
7、为什么要使用页面置换算法 答:当进程运行时,要访问的页面不在内存,则出现缺页中断,需要把该页面调入内存,如果内存中没有空闲物理块,则需要进行页面置换.页面置换算法依据一定策略,把物理块中的某个页面置换出去,送到磁盘交换区,在空出的一个物理块中装入导致缺页中断的页面。
8、最佳置换算法 答:FIFO算法是基于队列实现的,不是堆栈类算法,即未来永远不会再使用的页面 or 未来最长时间不再被访问的页面。该算法保证了可以获得最低缺页率,但无法预知未来页面的使用情况,因此目前无法实现,但通常用来评价其他算法。
优点:可保证最低缺页率。缺点 置换的页面可以是很久以前使用过但现已不再使用的初始化模块;所置换的页面可能包含一个被大量使用的变量,它早就初始化了,但仍在不断使用。对页面的访问时间无法预知,故该算法无法实现。 9、先进先出(FIFO)页面置换算法 答:该算法总是淘汰最先进入内存的页面,即选择在内存中驻留时间最久的页面予以淘汰。这种页面置换算法确保对于给定数量的帧会产生最低的可能的缺页错误率。
FIFO 和 OPT 算法的区别: 在于除了在时间上向后或向前看之外,FIFO算法使用的是页面调入内存的时间,OPT算法使用的是页面将来使用的时间。
优点: 实现简单缺点:往往与进程实际运行的规律不相符。有些页面,如存放全局变量、常用函数的页面,在整个进程的运行过程中将会被频繁访问。如果频繁将其换进换出,则会产生“抖动”现象,因此,这种算法在实际中应用很少。 10、最近最久未使用(LRU)算法 答:LRU 是堆栈类的算法,堆栈类算法不可能出现Belay异常。该算法以过去预测未来,选择之前最长时间未使用的页面置换。但是由于利用“过去”作为“未来”的近似这一做法并非完全可靠,因此有时会造成缺页率非常高,导致效率会非常低。
Belady现象的描述: 一个进程P要访问M个页,OS分配N(N<M)个内存页面给进程P;对一个访问序列S,发生缺页次数为PE(S,N)。当N增大(且N小于M)时,PE(S, N)时而增大,时而减小。FIFO是最早出现的页置换算法之一。Belady现象的原因是FIFO算法的置换特征与进程访问内存的动态特征是矛盾的,即被置换的页面并不是进程不会访问的,因而FIFO并不是一个好的置换算法。
优点: 由于考虑程序访问的时间局部性,一般能有较好的性能。实际应用多。缺点: 实现需要较多的硬件支持,会增加硬件成本。 11、Clock 置换算法 答:Clock置换算法是一种LRU的近似算法。由于LRU算法需要较多的硬件支持,采用Clock算法只需相对较少的硬件支持。Clock也称之为最近未用算法NRU。
优点: 可减少磁盘的I/O操作数缺点: 实现该算法本身的开销将有所增加 11.1、执行过程 答:只需为每页设置一位访问位,再将内存中的所有页面都通过链接指针链接成一个循环队列。当某页被访问时,其访问位被置1。在选择页面淘汰时,只需检查页的访问位,如果是0,就选择该页换出;若为1,则重新将它置为0,暂时不换出,而给该页第二次驻留内存的机会,再按照FIFO算法检查下一个页面。当检查到队列中的最后一个页面时,若其访问位仍为1,则再返回到队首去检查第一个页面。由于该算法是循环地检查各页面的使用情况,故称为Clock算法。
11.2、改进型Clock置换算法: 答:由访问位A和修改位M可以组合成下面四种类型的页面:
1类(A=0, M=0): 表示该页最近既未被访问, 又未被修改, 是最佳淘汰页。2类(A=0, M=1): 表示该页最近未被访问, 但已被修改, 并不是很好的淘汰页。3类(A=1, M=0): 最近已被访问, 但未被修改, 该页有可能再被访问。4类(A=1, M=1): 最近已被访问且被修改, 该页可能再被访问。 12、最少使用置换算法 答:为每个页面配置一个计数器,一旦某页被访问,则将其计数器的值加1,在需要选择一页置换时,则将选择其计数器值最小的页面,即内存中访问次数最少的页面进行淘汰。
配置 Docker Host URI
注意,这里要用 http://!!!如果按照提示里用了 tcp:// 则会报错,异常信息如下:
2023-11-13 16:28:42.683+0000 [id=34] WARNING o.e.j.s.h.ContextHandler$Context#log: Error while serving http://10.8.4.57:8080/manage/descriptorByName/org.jenkinsci.plugins.docker.swarm.DockerSwarmCloud/validateTestDockerApiConnection java.lang.NullPointerException at org.jenkinsci.plugins.docker.swarm.docker.api.request.ApiRequest.<init>(ApiRequest.java:71) at org.jenkinsci.plugins.docker.swarm.docker.api.ping.PingRequest.<init>(PingRequest.java:10) at org.jenkinsci.plugins.docker.swarm.DockerSwarmCloud$DescriptorImpl.doValidateTestDockerApiConnection(DockerSwarmCloud.java:139) at java.base/java.lang.invoke.MethodHandle.invokeWithArguments(Unknown Source) at org.kohsuke.stapler.Function$MethodFunction.invoke(Function.java:397) 2023-11-13 16:44:26.516+0000 [id=275] INFO o.j.p.cloudstats.CloudStatistics#logTypeNotSupported: No support for cloud-stats plugin by class org.jenkinsci.plugins.docker.swarm.DockerSwarmComputer [ERROR] [11/13/2023 16:44:26.856] [swarm-plugin-akka.actor.default-dispatcher-111] [akka://swarm-plugin/user/agt-_by_dockerswarm-2] unexpected url: tcp://10.8.4.57:2375/services/create java.lang.IllegalArgumentException: unexpected url: tcp://10.8.4.57:2375/services/create at okhttp3.Request$Builder.url(Request.java:143) at org.jenkinsci.plugins.docker.swarm.docker.api.request.ApiRequest.toOkHttpRequest(ApiRequest.java:156) at org.jenkinsci.plugins.docker.swarm.docker.api.request.ApiRequest.execute(ApiRequest.java:162) at org.jenkinsci.plugins.docker.swarm.DockerSwarmAgentLauncherActor.createService(DockerSwarmAgentLauncherActor.java:79) at org.jenkinsci.plugins.docker.swarm.DockerSwarmAgentLauncherActor.lambda$createReceive$1(DockerSwarmAgentLauncherActor.java:50) at akka.japi.pf.UnitCaseStatement.apply(CaseStatements.scala:24) [ERROR] [11/13/2023 16:46:14.530] [swarm-plugin-akka.
多态是面向对象编程(OOP)中的一个重要概念,它能够增加代码的灵活性和可维护性。多态的主要思想是同一个方法名在不同的类中有不同的实现,或者说同一个接口可以有多个不同的实现方式。让我们通过一个生动的例子来说明多态的用途。
假设有一个图形类,其中包括圆形和矩形两个子类。每个图形都有一个计算面积的方法,但是计算面积的方式在圆形和矩形之间是不同的。
class Shape { // 通用代码 } class Circle extends Shape { private $radius; public function __construct($radius) { $this->radius = $radius; } public function calculateArea() { return pi() * $this->radius * $this->radius; } } class Rectangle extends Shape { private $width; private $height; public function __construct($width, $height) { $this->width = $width; $this->height = $height; } public function calculateArea() { return $this->width * $this->height; } } 现在,如果我们要计算一组图形的总面积,可以使用多态。我们可以定义一个通用的函数,该函数接受一个Shape对象数组,并计算它们的总面积。
function calculateTotalArea(array $shapes) { $totalArea = 0; foreach ($shapes as $shape) { $totalArea += $shape->calculateArea(); } return $totalArea; } 现在我们可以创建圆形和矩形对象,将它们放入数组中,然后使用calculateTotalArea函数计算它们的总面积,而无需关心具体是哪种图形。
Stable Diffusion教程 本文是我在B站学习SD时做的笔记,大家有时间的话可以去学习一下这个教程,讲的很详细,是一个比较系统的教学,UP:Nenly同学
stable diffusion的安装 stable diffusion 百宝书_shenmingik的博客-CSDN博客
一、提示词分类和书写方式 正向提示词和反向提示词
提示词要用英文书写,可以有道翻译
书写方式可以以词组的方式进行书写
词组之间需要间隔符号,就是使用英文逗号
1.提示词分类 内容提示词 人物及主体特征
场景特征
环境光照
画幅视角
服饰穿搭 white dress
室内、室外 indoor/outdoor
白天黑夜 day/night
距离 close-up,distant
发型发色 blonde hair,long hair
大场景 forest,city,street
特定时段 morning,sunset
人物比例 full body,upper body
五官特征 small eyes,big moutn
小细节 tree,bush,white flower
光环境sunlight,bright,dark
观察视角from above,view of back
面部表情 smiling
天空blue sky,starry sky
镜头类型 wide angle,Sony A7 Ⅲ
肢体动作 stretching arms
画质提示词 画质提示词
画风提示词
通用高画质
需要在配置项中添加
try_files $uri $uri/ /index.html;
一.作业目标:
依托前面的设计,实现点击item能够显示出新的view
二.关键代码解析及技术说明:
1.创建一个新的activity:itemActiviy新建一个空的ItemActivity2和对应的activity_Item2.xml来实现新的界面布局
activity_item2设计如下:
activityi_item2对应的是点击item后显示的页面,接下来要设计ItemActivity2文件
public class ItemActivity2 extends AppCompatActivity { private TextView itemTextView; private Button backButton; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_item2); Intent intent = getIntent(); String itemData = intent.getStringExtra("itemData"); itemTextView = findViewById(R.id.itemTextView); itemTextView.setText(itemData); backButton = findViewById(R.id.button8); backButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { finish(); } }); } } 在这段代码, super.onCreate(savedInstanceState) 执行父类的 onCreate 方法。
setContentView(R.layout.activity_item2) 方法:将与 ItemActivity2 相关联的布局文件加载到当前的 Activity 中。
getIntent 方法:获取传递过来的 Intent 对象,然后从 Intent 中提取名为 "
1、安装驱动 下载地址:http://ws.it0355.com/a/202101/07/a27013.htm
双击exe文件安装驱动:
检查驱动运行正常:
http://www.winwin7.com/soft/xtbd-12727.html vc库安装
习题题目: 编写一个程序,输入运算符和两个操作数,输出计算结果。例如
+100 3.14
*4 5
将操作符读入到一个称为operation 的字符串,用一个if语句判断哪个操作是用户希望
的,例如if (operation==“+”)。 将操作数读入到double 类型的变量 量。实现+、-、*、/(很 明显,分别代表加、减、乘、除)几种运算。
问题分析: 1.需要指引用户输入①运算符②分别输入两个double类型数字。如果输入类型错误,需提示重新输入。
2.根据不同的输入符,进行两数的运算。
输入校验调用函数: double类型输入校验函数
double input_double() { double num = 0; cout << "请输入一个数"; cin >> num; while (cin.fail() or cin.get() != '\n') { cout << "请仅输入数字\n"; cin.clear(); cin.ignore(1024, '\n'); cin >> num; } return num; } char类型输入校验函数
char input_char() { char ch; cout << "请输入一位字符:\n"; ch = cin.get(); while (cin.get()!='\n') { cout << "
本期目录 1. 导入核心库2. 初始化分布式进程组3. 包装模型4. 分发输入数据5. 保存模型参数6. 运行分布式训练7. DDP完整训练代码 本章的重点是学习如何使用 PyTorch 中的 Distributed Data Parallel (DDP) 库进行高效的分布式并行训练。以提高模型的训练速度。 1. 导入核心库 DDP 多卡训练需要导入的库有:
库作用torch.multiprocessing as mp原生Python多进程库的封装器from torch.utils.data.distributed import DistributedSampler上节所说的DistributedSampler,划分不同的输入数据到GPUfrom torch.nn.parallel import DistributedDataParallel as DDP主角,核心,DDP 模块from torch.distributed import init_process_group, destroy_process_group两个函数,前一个初始化分布式进程组,后一个销毁分布式进程组 2. 初始化分布式进程组 Distributed Process Group 分布式进程组。它包含在所有 GPUs 上的所有的进程。因为 DDP 是基于多进程 (multi-process) 进行并行计算,每个 GPU 对应一个进程,所以必须先创建并定义进程组,以便进程之间可以互相发现并相互通信。
首先来写一个函数 ddp_setup() :
import torch import os from torch.utils.data import Dataset, DataLoader # 以下是分布式DDP需要导入的核心库 import torch.multiprocessing as mp from torch.
在vue3项目中使用el-upload实现文件上传 template <el-dialog :title="upload.title" v-model="upload.open" width="400px" append-to-body> <el-upload ref="uploadRef" :limit="1" accept=".xlsx, .xls" :headers="upload.headers" :action="upload.url + '?updateSupport=' + upload.updateSupport" :disabled="upload.isUploading" :on-progress="handleFileUploadProgress" :on-success="handleFileSuccess" :auto-upload="false" drag> <el-icon class="el-icon--upload"><upload-filled /></el-icon> <div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div> <template #tip> <div class="el-upload__tip text-center"> <div class="el-upload__tip"><el-checkbox v-model="upload.updateSupport" />是否更新已经存在的用户数据</div> <span>仅允许导入xls、xlsx格式文件。</span> <el-link type="primary" :underline="false" style="font-size: 12px; vert - List item ical-align: baseline" @click="importTemplate">下载模板</el-link> </div> </template> </el-upload> <template #footer> <div class="dialog-footer"> <el-button type="primary" @click="submitFileForm">确 定</el-button> <el-button @click="upload.open = false">取 消</el-button> </div> </template> </el-dialog> 相关属性说明
系统部署在物理机上,开机后一直pxe不进系统,怀疑GRUB丢失。
查看bios 里 采用uefi 启动方式,
无硬盘系统引导选项,
且BMC设置为硬盘永久启动也无效。
挂载光驱ISO进入救援模式,sda为系统盘,重装grub报错
grub2-install:error:/usr/lib/grub/x86_64-efi/modinfo.sh
挂载光驱iso
使用yum从光盘中安装 yum install grub2-efi* 报错即可解决。
查看/boot/grub2/grub.cfg 发现有配置文件,如果不存在
grub2-mkconfig -o /boot/grub2/grub.cfg 重新生成。
参考
https://blog.csdn.net/qq_32437331/article/details/127907035
文章目录 rl-agent Get startInstallationUsageMonitoring 具体代码 学习一下rl-agents的项目结构以及代码实现思路。
source: https://github.com/eleurent/rl-agents
rl-agent Get start Installation pip install --user git+https://github.com/eleurent/rl-agents Usage rl-agents中的大部分例子可以通过cd到scripts文件夹 cd scripts,执行 python experiments.py命令实现。
Usage: experiments evaluate <environment> <agent> (--train|--test) [--episodes <count>] [--seed <str>] [--analyze] experiments benchmark <benchmark> (--train|--test) [--processes <count>] [--episodes <count>] [--seed <str>] experiments -h | --help Options: -h --help Show this screen. --analyze Automatically analyze the experiment results. --episodes <count> Number of episodes [default: 5]. --processes <count> Number of running processes [default: 4].
暴力破解之密码字典 暴力破解多用于密码攻击领域,即使用各种不同的密码组合反复进行验证,直到 找出正确的密码 这种方式也称为“密码穷举”,用来尝试的所有密码集合称为"密码字典” 从理论上来说,任何密码都可以使用这种方法来破解,只不过越复杂的密码需要 的破解时间也越长 生成密码字典工具crunch 语法: 示例: 通过文件管理系统找到生成的密码字典 暴力破解之hydra 海德拉(Hydra):希腊神话中的九头蛇 Hydra用法 RDP(Remote Desktop Protocol,远程桌面协议) 在Win7上运行mstsc 目标主机Win2003开启远程桌面(端口号3389) 爆破3389密码 进入到hydra文件夹,按住shift ,同时点击鼠标右键,点击“从此处打开终 端” 输入: hydra ‐l administrator ‐P pass123.txt 192.168.111.138 rdp
最近在做单点登录系统时,部分场景需要使用 Cookie 保存信息,浏览器频繁给出警告某些 Cookie 滥用推荐的“SameSite“属性
使用以下代码设置 Cookie 的同时设置 SameSite 属性即可
ResponseCookie responseCookie = ResponseCookie.from(key, value) // 设置 HttpOnly .httpOnly(true) // 设置 SameSite 为 Lax,不依赖浏览器默认行为 .sameSite("Lax") // 设置 Cookie 路径为网站根路径 .path("/") // 设置过期时间(单位:秒) .maxAge(maxAge) // 为 https 访问开启 secure .secure(request.isSecure()) .build(); response.addHeader(HttpHeaders.SET_COOKIE, responseCookie.toString()); 注意!这里必须使用 addHeader() 而不是 setHeader(),惨痛的教训
具体看这篇文章:
记一次 新增 / 删除 Cookie 未生效的 BUG
马达加斯加是位于非洲南部一个国家,虽然经济是比较落后的一个国家,但是一直以来跟中国的关系都还不错,生产生活资料也是比较依赖进口的,市场潜力还是不错的。今天就来给大家分享一下马达加斯加的相关攻略。大家点赞收藏+关注慢慢看。
文章目录:
1.马达加斯加国家概况
2.马达加斯加节日与礼仪
3.马达加斯加注意事项
4.马达加斯加市场开发
5.马达加斯加国家冷知识
一、马达加斯加国家概况 【国 名】马达加斯加共和国(The Republic of Madagascar)
【面 积】59.2万平方公里。位于印度洋西部的非洲岛国,隔莫桑比克海峡与非洲大陆相望。马达加斯加岛全岛由火山岩构成,作为非洲第一、世界第四大的岛屿
【人 口】马达加斯加全国人口总数约2892万(2023年)。马达加斯加总人口的99%以上为马达加斯加人,此外还有印巴裔、法裔、科摩罗裔等人口,其中,印巴裔法籍侨民(Karanes)在马达加斯加工商界占据重要地位。华侨和华裔约6万人,主要分布在塔那那利佛和塔马塔夫。
【信 仰】在马达加斯加,约52%的人信奉原始宗教;41%的人信奉基督教;7%的人(主要分布在北部和东部沿海地区)信奉伊斯兰教。
【首 都】塔那那利佛(马语:Antananarivo;法语:Tananarive),马语意为“千人勇士城”,是全国政治、经济和文化中心。人口约320万,年平均气温18.3°C。
【资 源】马达加斯加主要矿产资源有石墨、铬铁、铝矾土、石英、云母、镍矿、钛铁、铁矿、锰、铅、锌、煤等,其中石墨储量居非洲首位。此外还有较丰富的宝石、半宝石资源以及大理石、花岗岩和动植物化石等。河流湍急,水力发电潜力大。森林面积12.3万平方公里,约占国土面积的21%,珍稀动植物种类繁多,包括珍稀植物塔那拉爵床。 一些动植物为马达加斯加独有。
【工 业】马工业基础十分薄弱,主要有炼油、发电、纺织和服装加工、农产品加工、饮料、烟草、造纸、制革、建材等。采矿业是马达加斯加经济发展的重要增长点。马达加斯加较大的矿业项目有QMM钛铁矿、Ambatovy镍钴矿、Kraoma铬矿项目等。
【农 业】马达加斯加第一产业(农林牧渔)增加值约占GDP的24.1%,主要农产品包括稻谷、玉米、木薯以及香草等香料。大米是马达加斯加人的首要主食。
【旅游业】旅游资源丰富,但服务设施不足。上世纪90年代以来,马将旅游业列为重点发展行业,鼓励外商投资旅游业。1997年改革签证制度,允许游客申请落地签证,同时取消旅馆对外国游客高收费的作法。游客主要来自法国(50%以上)、留尼汪、美国、英国、瑞士、德国和意大利等。主要旅游点是努西贝岛、圣玛丽岛。
【对外贸易】主要进口石油、车辆、机械设备、药品、日用消费品及食品等。主要出口咖啡、虾、铬矿石、香草、丁香、棉纺织品等。主要贸易伙伴是法国、美国、中国、欧盟、南非、南共体、东南亚部分国家和印度洋诸岛国等
二、马达加斯加节日与礼仪 *节日
新年1月1日
妇女节3月8日
烈士节3月29日
复活节4月4日
劳动节5月1日
耶稣升天节5月13日
圣灵降临节周一5月13日
独立日6月26日
圣母升天节8月15日
万圣节11月1日
共和国日12月11日
圣诞节12月25日
*社交礼仪与风俗禁忌
马达加斯加以农业为主。出口商品为咖啡,鱼类等。马达加斯加人喜爱鲜明的色彩,到这里从事商务活动,可准备印有法文字样的名片。初到马达加斯加,可送给与你做生意的人一点礼物,像精美的工艺品及日常用品都可以。这里的妇女是传统纺织的能手。一种名为兰巴的民族服装,形同印度,孟加拉妇女身披的沙丽,它是用棉麻等混织而成。在马达加斯加,妇女以发型来显示美,土著民族同样重发饰,女人们将头发梳成髻,涂上油膏。由于马达加斯加人尊重长辈,因此旅游者不论坐车,行路,参观等,均应注意新人当地习俗,处处礼让年长者。到马达加斯加旅行的人,可带上一些一美元的纸币作小费,送给为你提供直接服务的人员。 马达加斯加人的名字一般较长。由于马达加斯加许多人信奉基督教,他们的名字往往由一个马达加斯加名字加一个宗教名字组成。马达加斯加的国树是“旅人蕉”、国石是“孔雀石”马达加斯加还有随意改名的习俗,人生不同阶段有不同的名字。比如,生了孩子,做父母的除了给孩子取名外,有的还会给自己改名。在马达加斯加,男婚女嫁,老人殉葬时,都要杀牛摆宴招待宾客。有人死了,家人在死者坟前立一个牛头模型,表示死者生前的荣耀和保佑其死后灵魂的超度。马达加斯加盛行一夫多妻制。在马达加斯加,死亡被看成是向更美好世界的超升。葬礼时,年轻女子在屋外伴着传统乐曲的节奏唱歌。马达加斯加人忌讳代表着死亡和灾祸的黑色。在马达加斯加,星期二,星期四为禁忌日。 *餐饮礼仪与禁忌
马达加斯加岛上的居民喜吃大米,主食是玉米和牛肉,也喜欢吃海产品。当地生产的华尼拉成品是一种绝佳的食品香料,可用于制作糕点,饮料等食品。这种香料已成为马达加斯加出口换汇的重要产品。马达加斯加青年举止大方。为了培养自己的勇气,他们不吃牛膝,据说吃了就会膝盖变软。新年前一周不准吃肉,除夕晚餐只准吃一些禽类。 三、马达加斯加市场注意事项 1、清关文件要求
1)海运提单/货代提单
2)商业发票(Commercial Invoice),如果发票为英文文本,进口商应另备法文译本,发票中应详细描述商品的重量(净重、毛重);尺寸或体积;出口商姓名、签名;包装型号及数量;及货物标号;对货物的准确、详细、完整的描述;单价和总价;海运、保险或意外损失费。
3)装箱单(Packing List),包装清单需要包装、重量清单一式3份,清单中需要详细描述每种包装中所装物品名称、数量、毛重、净重、每件货物的价值,同时需要注明送货工具、方式。
4)装载清单,均需盖章,注明日期、物品的毛重、净重、尺寸或体积、商标、进口商姓名、签字。为了海关迅速验货,物品的货运商标、载货清单号、容器、发票应相符。装载单位由货运公司和公务机关签署。航空运输有专门的航空装载单。
5)BSC是法语 Bordereau de Suivl des Cargaisons 的缩写,货物追踪号的意思,英语就是 CTN(Cargo tracking note)所有从马达加斯加进口的货物都需要提前申请办理BSC(电子货物跟踪单),并取得对应的电子货物跟踪单号码BSC Number(BSC No.)。部分船公司需要收到此BSC NO.
此项报错原因一有可能是npm版本与node版本不符导致,例如node版本是12,如果把npm版本升到10,10版本的npm并不能在12版本的node上运行,这时候执行命令install npm@6.14.10 -g降低npm版本即可
如果无法降低版本有可能是原因二,作者之前用的node18版本,删除的时候没删干净,现在node12版本,npm有可能冲突,这时候执行命令where npm,找到多余的npm删除
目录 Docker简介系统环境检查Docker常用命令帮助命令镜像命令容器生命周期命令容器操作命令仓库命令命令小结 数据卷命令Dockerfile问题 Docker视频学习推荐 here Docker简介 镜像(image)
docker镜像就好比是一个模板,可以通过这个模板来创建容器服务,创建数量不限镜像层级结构
容器(container)
docker利用容器技术,独立运行一个或者一组应用,通过镜像来创建。类似于一个简易的Linux系统虚拟机&Docker对比
如下面的对比图中,是两个非常轻量级的docker容器在运行
仓库(repository)
仓库是存放镜像的地方,分为私有仓库和公有仓库。目前国外和国内均有仓库地址,如国内的阿里云。 从无到有的过程
系统环境检查 检查Linux内核版本 OS requirements:To install Docker Engine, you need a maintained version of CentOS 7. Archived versions aren’t supported or tested.
[root@localhost ~]# uname -r 4.18.0-147.el8.x86_64 查询系统版本信息 [root@localhost ~]# cat /etc/os-release NAME="CentOS Linux" VERSION="8 (Core)" ID="centos" ID_LIKE="rhel fedora" VERSION_ID="8" PLATFORM_ID="platform:el8" PRETTY_NAME="CentOS Linux 8 (Core)" ANSI_COLOR="0;31" CPE_NAME="cpe:/o:centos:centos:8" HOME_URL="https://www.centos.org/" BUG_REPORT_URL="https://bugs.centos.org/" CENTOS_MANTISBT_PROJECT="CentOS-8" CENTOS_MANTISBT_PROJECT_VERSION="8" REDHAT_SUPPORT_PRODUCT="centos" REDHAT_SUPPORT_PRODUCT_VERSION="8" 查看Docker官方安装文档
点击here查看Centos安装文档首先卸载旧的Docker [root@localhost ~]# yum remove docker \ docker-client \ docker-client-latest \ docker-common \ docker-latest \ docker-latest-logrotate \ docker-logrotate \ docker-engine 方式一 仓库安装
● 在《数据结构与算法分析(C语言描述)》关于栈的应用里有后缀表达式和中缀到后缀的转换。看完之后觉得似乎有实现的可能,磨了很久终于实现了出来(小菜鸡一枚)。
1、后缀表达式 思路:1、输入后缀表达式。2、设置一个栈。3、将未遇到运算符的数字全部存入栈内。4、遇到运算符将栈内最上面的两个数弹出,通过该运算符计算后再存入栈内。5、依次循环。
#include<stdio.h> #include<stdlib.h> #define MAXSIZE 100 typedef int SElemType; typedef struct { SElemType *base; SElemType *top; int stacksize; } SqStack; int InitStack(SqStack &S) { S.base = new SElemType[MAXSIZE]; if (!S.base) return 0; S.top = S.base; S.stacksize = MAXSIZE; return 1; } int Push(SqStack &S, SElemType e) { if (S.top - S.base == S.stacksize) return 0; *S.top++ = e; return 1; } int Pop(SqStack &S, SElemType &e) { if (S.
解决方案 1、问题2、设计3、流程 看了大部分的消息中心解决方案,发现大家的中心思想都大差不差,区别基本都是在符合自身业务场景的做了一些定制化处理。本文为我对消息中心基本骨架的知识梳理,亦在帮助大家对消息中心设计有一个基本的理解。
1、问题 业务上可能会遇到的问题:
消息不支持配置化消息不支持多语言消息掌握能力(查看率、点击率、转化率等) 技术可能上遇到问题:
发送消息接口不统一(配置化后台、三方中间件、硬编码消息)发送消息需要指定的参数过多没有进行对外部接口的限流处理消息数据管理分析(失败率、延迟率、一键撤回) 2、设计 可将消息中心抽象为三部分:
发送消息渠道部分:
消息渠道:针对不同渠道发送的消息,对渠道进行配置,如短信、邮件、钉钉消息、企微消息 发送消息记录部分:
消息场景:维护消息的场景类型,即对消息绑定一个场景,场景编码全局唯一,调用方指定场景编码用于定位具体消息消息任务:消息中心接收到的上游传递的参数记录。由于一个消息场景可以被消息记录:经过一系列处理后真实消息的发送记录,根据业务场景可扩展 发送消息模板配置部分:
消息基础模板:可用于处理公共样式,简化消息模板配置消息模板:配置待发送消息的消息模板,参数值以占位符形式提供,消息模板在配置时需要绑定消息场景、以及消息渠道。 注意,由于一个消息场景可以被多个消息模板配置,所以上面提到的消息任务和消息记录不是一对一的
3、流程 上游指定消息场景中的消息编码和用户调用接口。消息中心接收到消息后,根据请求中的场景编码查询出所有配置的消息模板。每一个消息模板对应一条待发送得消息,在每一条要发送的消息中,首先完成对当前场景的规则的校验,校验通过后获取消息模板配置的渠道,发送具体的消息给对应得用户。
整体流程:
环境配置 本系统采用phpstudy开发平台,采用PHP和MySQL数据库进行开发,开发工具为HBuilder。phpStudy是一个PHP调试环境的程序集成最新的
Apache+PHP+MySQL+phpMyAdmin,一次性安装,无须配置即可使用,是非常方便、好用的PHP调试环境。(其他平台均可)@@@文末有获取方式免费获取
————————————————
含sql文件
主要功能 管理员登录
验证码验证
添加用户信息
修改用户信息
批量删除用户信息
信息分页显示
表格数据文件下载
主要语言 PHP MySQL JavaScript CSS Layui框架
运行截图 数据列表
<?php for($i = 0; $i < count($arr2); $i++){?> <tr> <td class="id"><?php echo $arr2[$i]['id'];?></td> <td> <form class="layui-form" action=""> <input type="checkbox" class="checkbox" lay-skin="primary"> </form> </td> <td><?php echo $i+1;?></td> <td><?php echo $arr2[$i]['name'];?></td> <td><?php echo $arr2[$i]['sex'];?></td> <td><?php echo $arr2[$i]['age'];?></td> <td><?php echo $arr2[$i]['phone_number'];?></td> <td> <a title="修改" href="javascript:;" onclick="show('修改信息','update.php?id=<?php echo $arr2[$i]['id'];?>')"><i class="layui-icon layui-icon-edit" style="color: #1E9FFF;"
文章目录 一、线程模型二、解码和编码三、序列化四、零拷贝五、背压 NIO有一个非常重要的组件——多路复用器,其底层有3种经典模型,分别是epoll、select和poll。与传统IO相比,一个多路复用器可以处理多个Socket连接,而传统IO对每个连接都需要一条线程去同步阻塞处理。NIO有了多路复用器后只需要一条线程即可管理多个Socket连接的接入和读写事件。
Netty的多路复用器默认调用的模型是epoll模型,它除了JDK自带的epoll模型的封装,还额外封装了一套,这两者都是epoll模型的封装,只是JDK的epoll模型是水平触发的,而Netty采用JNI重写的边缘触发。
一、线程模型 对于服务器端而言有两个线程组,Boss线程组和Worker线程组。其中Boss线程组一般只开启一条线程(除非一个Netty服务同时监听多个端口),Worker线程数默认是CPU核数的两倍。Boss线程主要监听SocketChannel的OP_ACCEPT事件和客户端的连接。
**当Boss线程监听到有SocketChannel连接接入时,会把SocketChannel包装成NioSocketChannel,并注册到Worker线程的Selector中,同时监听其OP_WRITE和OP_READ事件。**当Worker线程监听到某个SocketChannel有就绪的读IO事件时,就会进行以下操作:
向内存池中分配内存,读取IO数据流将读取后的ByteBuf传递给解码器Handler进行解码,若能解码出完整的请求数据包,就会把请求数据包交给业务逻辑处理Handler经过业务逻辑处理Handler后,在返回响应结果前,交给编码器进行数据加工最终写到缓冲区,并由IO Worker线程将缓冲区的数据输出到网络中并传输给客户端 二、解码和编码 使用Java NIO来实现TCP网络通讯,需要对TCP连接中的问题进行进行全面的考虑,如拆包和粘包导致的半包问题和序列化等。对于这些问题,Netty都进行了很好的处理。
客户端给服务端发送消息并受到服务端返回的结果共经历了以下6步:
TCP是面向字节流传输的协议,它把客户端提交的请求数据看作一连串的无结构的字节流,并不知道所传送的字节流的含义,也并不关心有多少数据流入TCP输出缓冲区中
**每次发多少数据到网络中与当前网络的拥塞情况和服务端返回的TCP窗口的大小有关,涉及TCP的流量控制和拥塞控制,并且与Netty的反压有关。**如果客户端发送到TCP输出缓冲区的数据块太多,那么TCP会分割成多次将其传送出去,如果太少,则会等待积累足够多的字节后发送出去。很明显TCP这种传输机制会产生粘包问题
当服务端读取TCP输入缓冲区中的数据时,需要进行拆包处理,并解决粘包和拆包的问题,比较常见的方案有以下3种:
将换行符号或特殊标识符号加入数据包中,如HTTP和FTP等(LineBasedFrameDecoder)将消息分为head和body,head中包含body长度的字段, 一般前面4个字节是body的长度值,用int表示,但也有像Dubbo协议那种head中除了body长度外还有版本号、请求类型和请求id等(LengthFieldPrepender/LengthFieldBasedFrameDecoder)固定数据包的长度,如固定100字节,不足补空格(FixedLengthFrameDeocder) 步骤4-6和步骤1-3相似。TCP的这些机制与Netty的编码和解码有很大的关系。**Netty采用模板设计模式实现了一套编码和解码架构,高度抽象,底层解决TCP的粘包和拆包的问题。**编码器和解码器大部分都有共同的编码和解码父类,即MessageToMessageEncoder与ByteToMessageDecoder。
ByteToMessageDecoder父类在读取TCP缓冲区的数据并解码后,将剩余的数据放入了半包字节容器中,具体解码方案由子类负责。在解码的过程会遇到读半包,无法解码的数据会保存在读半包字节容器中,等待下次读取数据后继续解码。编码的逻辑比较简单,MessageToMessageEncoder父类定义了整个编码的流程,并实现了对已读内存的释放,具体的编码格式由子类负责。
Netty的编码和解码除了解决TCP协议的粘包和拆包问题,还有一些编解码器做了很多额外的事情,如StringEncode(把字符串转换为字节流)、ProtobufDecoder(对Protobuf序列化数据进行解码);还有各种常用的协议编解码器,如HTTP2、Websocket等。
三、序列化 当客户端向服务器端发送数据时,如果发送的是一个Java对象,由于网络只能传输二进制数据流,所以Java对象无法直接在网络中传输,则必须对Java对象的内容进行流化,只有流化后的对象才能在网络中传输。序列化就是将Java对象转换成二进制流数据的过程,而这种转化的方式多种多样:
Java自带序列化:简单但较少使用,因为性能低,序列化后码流太大,且无法跨语言进行反序列化为了解决Java自带序列化的缺点,会引入比较流行的序列化方式,如Protobuf、Kryo、JSON等。由于JSON格式化数据可读性好,且浏览器对JSON数据的支持性非常好,所以一般的Web应用都会选择它。另外,市场上有Fastjson,Jackson等工具包,使得Java对象转成JSON也非常方便。但是JSON序列化后的数据体积较大,不适合网络传输和海量数据存储。Protobuf和Kryo序列化后的体积与JSON相比要小很多 Protobuf是Google提供的一个具有高效协议数据交换格式的工具库,其具有更高的转化效率,且时间效率和攻坚效率都是JSON的3-5倍。对于一个Java对象,转换成JSON格式时会写进去一些无用的信息,如{},""等,当类的属性非常多并且包含各种对象组合时,开销会非常大。
而Protobuf对这些字段属性进行了额外处理,同类的每个属性名采用Tag值进行表示,这个Tag值在Protobuf中采用了varint编码, 当类的属性个数小于128时,每个属性名只需要1B来表示即可,同时属性值的长度也只占用1B。Protobuf对值也进行了各种编码,不同类型的数据值采用不同的编码技术,以尽量减小占用的存储空间。可以将Protobuf序列化后的数据想象成下面的格式:
tag|length|value|tag|length|value
Protobuf序列化除了占用空间小,性能还非常好,主要是它带有属性值长度,无需进行字符串匹配,这个长度值只用1B的存储空间。另外JSON都是字符串解析,而Protobuf根据不同的数据类型有不同的大小,如bool类型只需要读取1B的数据。
Protobuf的缺点如下:
从Protobuf序列化后的数据中发现,Protobuf序列化不会把Java类序列化进去,当遇到对象的一个属性是泛型且有继承的情况时,Protobuf序列化无法正确地对其进行反序列化,还原子类信息Protobuf需要编写.proto文件,比较麻烦,此时可以使用Protostuff来解决。Protostuff是Protobuf的升级版,无需编写.proto文件,只需要在对象属性中加入@Tag注解即可可读性差,只能通过程序反序列化解析查看具体内容 Protobuf一般用于公司内部服务信息的交换,对于数据量比较大、对象属性不是泛型且有继承的数据的场景比较合适。
四、零拷贝 零拷贝是Netty的一个特性,主要发生在操作数据上,无需将Buffer从一个内存区域拷贝到另一个内存区域,少一次拷贝,CPU效率就会提升。Netty的零拷贝主要应用在以下三种场景:
Netty接收和发送ByteBuffer采用的都是堆外直接内存,使用堆外直接内存进行Socket的读写,无需进行字节缓冲区的二次拷贝。如果使用传统的堆内存进行Socket的读写,则JVM会将堆内存Buffer数据拷贝到堆外直接内存中,然后才写入Socket中。与堆外直接内存相比,使用传统的堆内存,在消息的发送过程中多了一次缓冲区的数据拷贝在网络传输中,一条消息很可能会被分割成多个数据包进行发送,只有当收到一个完整的数据包后才能完成解码工作。Netty通过组合内存的方式把这些内存数据包逻辑组合到一块,而不是对每个数据块进行一次拷贝,这类似于数据库中的视图。CompositeByteBuf是Netty在此零拷贝方案中的组合Buffer传统拷贝文件的方法需要先把文件采用FileInputStream文件输入流读取到一个临时的byte[]数组中,然后通过FileOutputStream文件输出流把临时的byte[]数据内容写入目的文件中。当拷贝大文件时,频繁的内存拷贝操作会消耗大量的系统资源。Netty底层运用Java NIO的FileChannel.transfer()方法,该方法依赖操作系统实现零拷贝,可以直接将文件缓冲区的数据发送到目标Channel中,避免了传统的通过循环写方式导致的内存数据拷贝问题 五、背压 所谓背压,是进行流量控制的一种方案。背压就是消费者需要多少,生产者就生产多少。这有点类似于TCP里的流量控制,接收方根据自己的接收窗口的情况来控制发送方的发送速率。
这种方案只对于cold Observable有效。cold Observable是那些允许降低速率的发送源,比如两台机器传一个文件,速率可大可小,即使降低到每秒几个字节,只要时间足够长,还是能够完成的。相反的例子就是音视频直播,速率低于某个值整个功能就没法用了(这种类似于hot Observable)。
假如我们的底层使用Netty作为网络通信框架,业务流程在将业务数据发送到对端之前,实际先要将数据发送到Netty的缓冲区中,然后再从Netty的缓冲区发送到TCP的缓冲区,最后再到对端。业务数据不可能无限制向Netty缓冲区写入数据,TCP缓冲区也不可能无限制写入数据。Netty通过高低水位控制向Netty缓冲区写入数据的多少,从而实现整个链路的背压。
它的大体流程就是向Netty缓冲区写入数据的时候,会判断写入的数据总量是否超过了设置的高水位值,如果超过了就设置通道(Channel)不可写状态。当Netty缓冲区中的数据写入到TCP缓冲区之后,Netty缓冲区的数据量变少,当低于低水位值的时候就设置通过(Channel)可写状态。
Netty默认设置的高水位为64KB,低水位为32KB。可以通过ChannelOption进行设置。
bootstrap.childOption(ChannelOption.WRITE_BUFFER_WATER_MARK, new WriteBufferWaterMark(32 * 1024, 64 * 1024)); // 或 bootstrap.childOption(ChannelOption.WRITE_BUFFER_LOW_WATER_MARK, config.getMemorySegmentSize() + 1); bootstrap.childOption(ChannelOption.WRITE_BUFFER_HIGH_WATER_MARK, 2 * config.getMemorySegmentSize());
解决IDEA内存占用过高问题 1、忽略指定文件创建索引占用内存2、禁用或者卸载不常用的插件或者检查3、修改vm内存参数 往往对于笔记本过电脑内存不够来说的用户,idea占用内存是很高的,打开idea内存直接飙升,因此我做了以下处理。 1、忽略指定文件创建索引占用内存 针对全栈的人来说,项目中的前端依赖包文件过多,因此扫描索引占用内存过高,主要node_modules文件夹导致的
ctrl+alt+s打开设置>搜索文件类型
2、禁用或者卸载不常用的插件或者检查 3、修改vm内存参数 复制粘贴以下配置
-Xms2048m -Xmx4096m -Xverify:none -XX:+DisableExplicitGC -XX:ReservedCodeCacheSize=720m -XX:SoftRefLRUPolicyMSPerMB=50 -ea -Dsun.io.useCanonCaches=false -Djava.net.preferIPv4Stack=true -Djdk.http.auth.tunneling.disabledSchemes="" -XX:+HeapDumpOnOutOfMemoryError -XX:-OmitStackTraceInFastThrow -XX:CICompilerCount=2 -XX:TieredStopAtLevel=1 -XX:MaxInlineLevel=3 -XX:Tier4MinInvocationThreshold=100000 -XX:Tier4InvocationThreshold=110000 -XX:Tier4CompileThreshold=120000 更改之后idea内存会慢慢慢慢慢慢慢慢慢慢慢慢往上增加,用电脑管家、360加速球这种清理内存的加速一下,就能清理idea内存,ide内存会从0MB开始,告别卡顿。
这里我给大家推荐Mem Reduct软件https://www.henrypp.org/product/memreduct
不用下载流氓软件导致系统肿瘤不常用的功能,不二之选
目录 文章目录 目录1.什么是BottomSheet1、BottomSheetBeahvior**3.1 BottomSheetBehavior的几种状态****3.2 BottomSheetBehavior的简单使用** 2.BottomSheetDialog3.BottomSheetDialogFragment 1.什么是BottomSheet BottomSheet是一种从屏幕底部向上滑出一个对话框的效果,可以用来显示内容或者提供与用户相关的操作,在开发过程中十分常见,Bottom Sheet 具体实现主要包含:BottomSheetBeahvior 、BottomSheetDialog、BottomSheetDialogFragment,这三个组件均可以实现半屏弹出效果,区别点在于接入和使用方式上的差异
三个组件的概述
BottomSheetBeahvior 一般直接作用在view上,一般在xml布局文件中直接对view设置属性,轻量级、代码入侵低、灵活性高,适用于复杂页面下的半屏弹出效果。app:layout_behavior=“@string/bottom_sheet_behavior”BottomSheetDialog 的使用和对话框的使用基本上是一样的。通过setContentView()设定布局,调用show()展示即可。因为必须要使用Dialog,使用上局限相对多,因此一般适用于底部弹出的轻交互弹窗,如底部说明弹窗等。BottomSheetDialogFragment 的使用同普通的Fragment一样,可以将交互和UI写到Fragment内,适合一些有简单交互的弹窗场景,如底部分享弹窗面板等。 1、BottomSheetBeahvior Behavior是Android Support Design库里面新增的布局概念,主要的作用是用来协调CoordinatorLayout布局(Jetpack中的一个FrameLayout优化(第一行代码中只是简单说了他是FrameLayout优化没有进一步拓展))直接Child Views之间布局及交互行为的,包含拖拽、滑动等各种手势行为。
CoordinatorLayout布局:一个可协调子视图(Child Views)之间交互行为的布局容器。而Behavior则定义了每个子视图(Child View)与CoordinatorLayout之间的特定交互行为。这里注意Behavior只能应用于CoordinatorLayout布局中的子视图,而且需要CoordinatorLayout配合使用,以实现预期的效果.
从名字即可以看出,BottomSheetBehavior继承CoordinatorLayout.Behavior,借用behavior的布局和事件分发能力来实现底部弹出动画及手势拖拽效果。下面首先分析下bottomsheet初始弹出时是如何实现弹出动画。一个简单的半屏滑动布局如下:
3.1 BottomSheetBehavior的几种状态 STATE_HIDDEN :隐藏状态,关联的View此时并不是GONE,而是此时在屏幕最下方之外,此时只是无法肉眼看到 STATE_COLLAPSED :折叠状态,一般是一种半屏形态 STATE_EXPANDED:完全展开,完全展开的高度是可配置,默认即屏幕高度。类似地图首页一般完全展开态的高度配置为距离屏幕高差一小截距离。 STATE_DRAGGING:拖拽状态,标识人为手势拖拽中(手指未离开屏幕)STATE_SETTLING :视图从脱离手指自由滑动到最终停下的这一小段时间,与STATE_DRAGGING差异在于当前并没有手指在拖拽。主要表达两种场景:初始弹出时动画状态、手指手动拖拽释放后的滑动状态。 这些图片来自CSDN探索BottomSheet的背后秘密,这位博主讲的十分细致需要一些知识积累,如果你看完发现有些东西不足以满足你的需要,你可以看看这位博主的内容,我这里仅仅讲解了如何简单使用
3.2 BottomSheetBehavior的简单使用 1.设置CoordinatorLayout作为父布局,并设置需要弹出的View的layout_behavior为BottomSheetBehavior。
<?xml version="1.0" encoding="utf-8"?> <androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:paddingTop="24dp"> <Button android:id="@+id/button_1" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Button 1" android:padding="16dp" android:layout_margin="8dp" android:textColor="@android:color/white" android:background="@android:color/holo_green_dark"/> <Button android:id="@+id/button_2" android:layout_width="match_parent" android:layout_height="wrap_content" android:padding="16dp" android:layout_margin="8dp" android:text="
很久很久以前,在一个宁静的小村庄中,住着一位名叫牛顿的年轻学者。牛顿对于周围的一切都充满好奇心,他喜欢仰望星空、观察植物生长,并经常思考自然界中的各种奥秘。
有一天,当他坐在庄园的苹果树下阅读书籍时,一颗成熟的苹果突然从树上掉了下来。这个平凡的瞬间却在牛顿心中掀起了一场奇妙的思考风暴。他开始思考为什么苹果会落下,为什么不会漂浮在空中。这个简单的问题引导他走向了数学的奇妙领域。
于是,牛顿决定用数学的语言来揭示这个现象的奥秘。他开始思考运动和变化的本质,最终他创造出了微积分,这是一种独特的数学工具,通过它人们可以理解运动中的变化。为了更好地理解,我们来看一个例子:
假设一个小球从空中落下,牛顿用微积分的概念描述了小球下落的过程。他引入了导数的概念,表示小球下落的速度。通过对速度的积分,他得到了下落的距离。这使得我们可以准确地预测小球在任意时间的位置和速度。
随着时间的推移,牛顿的好奇心并未止步于苹果的落地。他将微积分应用到了更广泛的领域。例如,他用微积分解释了光的折射和反射,帮助我们理解了彩虹的形成。他还通过微积分描述了行星的运动轨迹,这为后来的开普勒定律奠定了基础。
微积分是一门数学理论,它的实际应用通常是通过数学软件或编程语言来实现。在实际编程中,主要涉及到导数和积分的计算。下面是一个简单的例子,使用Python中的SymPy库进行微积分计算。
首先,安装了SymPy库。如果没有安装,可以使用以下命令进行安装:
pip install sympy 然后,可以使用下面的Python代码来进行导数和积分的计算:
import sympy as sp # 定义变量和函数 x = sp.symbols('x') f = x**2 + 3*x + 2 # 计算导数 derivative = sp.diff(f, x) print(f"导数: {derivative}") # 计算定积分 integral = sp.integrate(f, x) print(f"积分: {integral}") 上述代码中,我们首先使用sp.symbols定义了变量x,然后定义了一个函数f,其中包含了一些代数表达式。接着,使用sp.diff计算了函数的导数,使用sp.integrate计算了函数的积分。最后,输出了导数和积分的结果。
牛顿的发现不仅仅是一时的奇迹,更是一场源自对自然的深入观察和对问题的不懈追求的冒险。他的奇思妙想不仅为我们打开了理解世界的新大门,也为数学和物理学的发展做出了卓越的贡献。在他的足迹中,人们学会了更深刻地理解自然界的运行规律,也理解了数学的力量是如何推动科学的不断进步。
需求指标: 五个相关的统计指标
1.统计每个国家在2015的死亡人数并按照死亡人数降序排序
2.统计某个国家在该数据集中每年的死亡人数并按照死亡人数降序排序
3.统计每个国家上传的总数据量筛选前十条进行查看
4.通过虚拟机监听端口模拟发送国家死亡人数的json数据并进行实时处理统计得到关于年份的数据条数
5.
目录
需求指标:
数据来源:
数据处理:
统计指标
I :统计每个国家在2015的死亡人数并按照死亡人数降序排序
II :统计某个国家在该数据集中每年的死亡人数并按照死亡人数降序排序
III :统计每个国家上传的总数据量筛选前十条进行查看
IIII :通过虚拟机监听端口模拟发送国家死亡人数的json数据并进行实时处理统计得到关于年份的总数据条数
IIIII :考虑时间单位的不同处理先数据集中挑选时间单位为月的数据,不考虑人民基数写一个自定义函数判断该国家的当前月份人民健康状况(自定)
总结:
考虑时间单位的不同处理先数据集中挑选时间单位为月的数据,不考虑人民基数写一个自定义函数判断该国家的当前月份人民健康状况(自定)
数据来源: 爱数科
数据科学科研和教学一体化平台 (idatascience.cn)
数据处理: 从网站中下载的数据为csv格式需要进行转换我们使用CSV转JSON - 在线转换文档文件转成JSON格式的数据集文件方便使用spark处理数据
统计指标 I :统计每个国家在2015的死亡人数并按照死亡人数降序排序 package com.lzzy; import org.apache.spark.sql.AnalysisException; import org.apache.spark.sql.Dataset; import org.apache.spark.sql.Row; import org.apache.spark.sql.SparkSession; public class I { public static void main(String[] args) throws AnalysisException { SparkSession ss = SparkSession.builder().appName("I").master("local").getOrCreate(); Dataset<Row> data = ss.read().json("D:\\spark\\Global mortality analysis\\1.json"); // data.show(); data.
代码圈复杂度 1、目的2、前言3、简介4、案例5、降低6、插件7、总结 1、目的 区别于常规的高内聚、低耦合、抽象、封装这种定性的指标,我想通过对软件架构可维护性的可量化的指标的分享,帮助大家在日常的开发工作中,有一个更为广阔的视角去审视我们编写的代码。即编写代码时,如果相关量化指标数据升高且超过一定的阈值,那么反问自己一下,当前的编码逻辑方便阅读吗?
2、前言 软件架构是软件开发和维护过程中的一个重要制品,是软件需求和设计、实现之间的桥梁。软件架构的开发和维护是基于架构软件软件生命周期中的重要环节,与之相关的步骤包括导出架构需求、架构开发、架构文档化、架构分析、架构实现和架构维护。软件架构的维护与演化密不可分,维护需要对软件架构的演化过程进行追踪和控制,以保障软件架构的演化过程能够满足需求(亦有说法将架构维护作为架构演化的一个部分)
那么如何衡量软件架构的可维护性呢?官方给出了六个指标。
其中圈复杂度 (CCN) 度量整个架构的独立执行路径的条数,该结果值即为待评估架构的最终度量结果;而对于扇入扇出度 (FFC) 、模块间耦合度 (CBO) 、模块的响应 (RFC) 、紧内聚度 (TCC) 、松内聚度 (LCC) 个度量指标,它们针对每个组件进行度量,则待评估架构的最终度量结果为所有组件结果的平均值。
3、简介 由于在组件图中组件是独立的,每个组件代表一个系统或子系统中的封装单位,封装了完整的事务处理行为,组件图能够通过组件之间的控制依赖关系来体现整个系统的组成结构。对架构的组件图进行圈复杂度的度量,可以对整个系统的复杂程度做出初步评估,在设计早期发现问题和做出调整,并预测待评估系统的测试复杂度,及早规避风险,提高软件质量。圈复杂度高的程序往往是最容易出现错误的程序,实践表明程序规模以 CCN小于等于10 为宜。
圈复杂度 = 程序控制流图中分支节点数 + 1,其它计算方法不做过多说明。
4、案例 以项目中的代码片段为例
圈复杂度为37的方法
圈复杂度为10的方法
圈复杂度为5的方法
我们不难发现,圈复杂度越高的代码,往往方法也越长,在阅读代码逻辑时,过长的方法(一屏装不下)和流程细节很影响阅读体验。
5、降低 于其说是降低代码圈复杂度的方法,不如说是常见的代码优化手段:
将条件判定提炼出独立函数将大函数拆成小函数以明确函数取代参数多态方式替代条件式移除控制标记… 更多优化方法可以参考《重构》、《代码整洁之道》等书籍
优化的本质是,该抽象抽象,该封装封装,在面向对象语言(Java)的大背景下,代码首先应该考虑如何自下而上面向对象的设计,而不是考虑如何自上而下的流程编码。
6、插件 metricsreloaded
Method metrics:
ev(G)(Essential Complexity (ev(G)):基本复杂度是用来衡量程序非结构化程度的,非结构成分降低了程序的质量,增加了代码的维护难度,使程序难于理解。因此,基本复杂度高意味着非结构化程度高,难以模块化和维护。实际上,消除了一个错误有时会引起其他的错误。Iv(G)(Module Design Complexity (iv(G))):模块设计复杂度是用来衡量模块判定结构,即模块和其他模块的调用关系。软件模块设计复杂度高意味模块耦合度高,这将导致模块难于隔离、维护和复用。模块设计复杂度是从模块流程图中移去那些不包含调用子模块的判定和循环结构后得出的圈复杂度,因此模块设计复杂度不能大于圈复杂度,通常是远小于圈复杂度。v(G)(Cyclomatic Complexity (v(G))):衡量圈复杂度,数量上表现为独立路径的条数,即合理的预防错误所需测试的最少路径条数,圈复杂度大说明程序代码可能质量低且难于测试和维护,经验表明,程序的可能错误和高的圈复杂度有着很大关系。 Class metrics:
OCavg:代表类的方法的平均循环复杂度WMC:总循环复杂度 Package metrics:包复杂度
v(G)avg:圈复杂度v(G)tot:总复杂度 Module metrics:模块复杂度
同上 Project metrics:项目复杂度
同上 7、总结 再次说明我们的目的不是去追求降圈复杂度的代码,因为过低的圈代码复杂度也不是最佳实践。而是要以有利架构维护的前提下,尽可能的提高代码的可读性。在开头的分享目的中提到,圈复杂度这一量化指标的提出,是帮助我们去审视编写的代码是否具有可读性。那么如何审视呢?
编写新业务流程时,当我们意识到方法过长或者圈复杂度过高时,应该考虑到需要对执行的流程进行抽象,至于抽象的方法是否需要满足xx设计、是否需要考虑未来的扩展,如果开发时间不允许,完全可以定义为private方法,而这个方法大概率也只有你自己会用。换个思路,将流程式的代码片段放在主逻辑中,也没有想要给给别人用。维护业务时,当我们意识到新增的业务流程会影响原流程的圈复杂度,并且圈复杂度超过了可接受的值,那么维护相关的代码则需要考虑是否需要抽象,抽象程度同理 屎山代码往往不是一个人造成的,而我们能做的也只有做好自己
测试驱动的开发 与 较低圈复杂度值 之间存在着紧密联系。
1.换源 mv /etc/apt/sources.list /etc/apt/sourses.list.backup vi /etc/apt/sources.list deb http://mirrors.aliyun.com/ubuntu/ bionic main restricted universe multiverse deb http://mirrors.aliyun.com/ubuntu/ bionic-security main restricted universe multiverse deb http://mirrors.aliyun.com/ubuntu/ bionic-updates main restricted universe multiverse deb http://mirrors.aliyun.com/ubuntu/ bionic-proposed main restricted universe multiverse deb http://mirrors.aliyun.com/ubuntu/ bionic-backports main restricted universe multiverse deb-src http://mirrors.aliyun.com/ubuntu/ bionic main restricted universe multiverse deb-src http://mirrors.aliyun.com/ubuntu/ bionic-security main restricted universe multiverse deb-src http://mirrors.aliyun.com/ubuntu/ bionic-updates main restricted universe multiverse deb-src http://mirrors.aliyun.com/ubuntu/ bionic-proposed main restricted universe multiverse deb-src http://mirrors.
item_get_sales接口可以用于获取淘宝天猫的商品销量详情。以下是获取商品销量详情的步骤:
注册淘宝开放平台账号,并创建一个应用。在应用中获取到API密钥,用于后续的调用身份验证和签名认证。根据需要选择适合的接口,例如item_get_sales接口。根据接口的调用规则,构造请求参数,包括商品ID和其他必要的参数。使用请求参数调用item_get_sales接口。解析返回的JSON数据,获取商品销量详情。 注意事项:
在使用item_get_sales接口时,需要遵守淘宝开放平台的相关规定和开发者规范,不得进行恶意操作或滥用。需要防范潜在的安全风险,如防范恶意请求、数据泄露等。根据实际需求选择适合的接口和参数,确保获取到准确的商品销量详情信息。如果接口返回数据异常或不符合预期,需要及时处理和解决,例如进行提醒或自动处理。在使用API接口时,需要注意请求频率限制,即单位时间内允许发送的请求数量有限,需要控制请求的频率,避免超出限制。需要注意数据的隐私和保密性,不得将敏感信息泄露给第三方或者用于非法用途。在使用API接口时,需要仔细阅读相关的文档和指南,了解接口的使用方法和规范,避免因误解或误用导致的问题。
要获得淘宝商品评论,您需要使用淘宝开放平台的API接口。具体步骤如下:
在淘宝开放平台注册一个开发者账号,并创建一个应用。在创建应用时,需要填写相关信息,包括应用名称、描述、类型等。在淘宝开放平台的API管理页面,可以找到商品评论API的相关接口。根据需要选择不同的接口,例如“淘宝商品评论列表接口”或“淘宝商品评论内容接口”。在选择接口后,需要了解接口的调用方式、参数列表等信息。这些信息可以在淘宝开放平台的API文档中找到。根据接口的调用方式和参数列表,编写代码进行调用。在调用时,需要使用淘宝开放平台提供的AppKey和AppSecret等信息,进行身份验证和签名认证。调用完成后,可以解析返回的JSON格式数据,获取商品评论的信息。 需要注意的是,在使用淘宝商品评论API时,需要遵守淘宝开放平台的相关规定和开发者规范,不得进行恶意操作或滥用。同时,需要防范潜在的安全风险,如防范恶意请求、数据泄露等。
数据实例
Result Object: --------------------------------------- { "items": { "totalpage": "1", "total_results": "4", "page_size": 3, "page": "1", "item": [ { "rate_content": "太漂亮了 本来买的时候犹豫很久很久很久 从来没有买过黄色的 觉得不好配衣服也觉得图片一般 犹豫了有一天终于下定决心去买一个试试 结果太太太太让我惊喜了 太漂亮了 很亮鞋子特别舒服 我买的大一点 也很舒服 还挺好配衣服的 后悔就买一双了 现在我家都是她家的鞋子了 绝对的YYDS", "rate_date": "2022-08-23", "pics": [], "display_user_nick": "梦**1", "auction_sku": "颜色分类:黄色【内里:超细纤维】;尺码:36", "add_feedback": "感谢您选择了我们,一直很担心您觉得我们做得不够好,怕您觉得我们的回复不够详细,又或者责怪我们的质检时不够仔细,但是在大部分时间里我们的团队真的已经尽了全力,希望您收到包裹的时候都能满意开心~", "add_feedback_images": null, "create_time_interval": null, "read_count": "0", "rate_id": "1184973493639", "like_count": "0", "user_star_pic": "https://img.alicdn.com/imgextra/i4/O1CN019QZnaG1U1LtUAPn6e_!!6000000002457-2-tps-92-45.png" }, { "rate_content": "面料材质:材质有一点点硬,版型不错,整体还凑合,对得起这个价格 ", "rate_date": "2021-11-16", "pics": [ "//img.alicdn.com/imgextra/i3/0/O1CN01TrfEtd2M3Ag2ClelC_!!0-rate.jpg" ], "
文章目录 前言最大熵强化学习不同动作空间下的最大熵强化学习基于能量的模型软价值函数最大熵策略 Soft Q-learningSoft Q-IterationSoft Q-Learning近似采样与SVGD伪代码 Soft Actor-Critic伪代码代码实践连续动作空间离散动作空间 参考与推荐 前言 之前的章节提到过在线策略算法的采样效率比较低,我们通常更倾向于使用离线策略算法。然而,虽然 DDPG 是离线策略算法,但是它的训练非常不稳定,收敛性较差,对超参数比较敏感,也难以适应不同的复杂环境。2018 年,一个更加稳定的离线策略算法 Soft Actor-Critic(SAC)被提出。SAC 的前身是 Soft Q-learning,它们都属于最大熵强化学习的范畴。Soft Q-learning 不存在一个显式的策略函数,而是使用一个函数 Q Q Q的波尔兹曼分布,在连续空间下求解非常麻烦。于是 SAC 提出使用一个 Actor 表示策略函数,从而解决这个问题。目前,在无模型的强化学习算法中,SAC 是一个非常高效的算法,它学习一个随机性策略,在不少标准环境中取得了领先的成绩。
最大熵强化学习 熵是策略中随机性的一种度量,设 x x x为随机变量,概率密度函数为 P P P,熵 H H H的计算式为: H ( p ) = E x ∼ p [ − log p ( x ) ] H(p)=\mathbb{E}_{x\sim p}[-\log p(x)] H(p)=Ex∼p[−logp(x)]在强化学习中,我们可以使用 H ( π ( ⋅ ∣ s ) ) H(\pi(\cdot|s)) H(π(⋅∣s))来表示策略 π \pi π在状态 s s s下的随机程度。最大熵强化学习(maximum entropy RL)的思想就是除了要最大化累积奖励,还要使得策略更加随机,除此之外还要增加算法的鲁棒性以及提升策略的预训练效果。
chatgpt:
https://chat.xutongbao.top/
截至我知识的最后更新时间(2023年),原生的 fetch API 在大多数浏览器中并没有内置的默认超时时间。这意味着如果你没有明确地设置一个超时期限,fetch 请求可能会永远挂起(或者直到浏览器决定停止尝试为止)。
如果你需要设置超时,你可以自己实现一个超时机制。以下是一个在JavaScript中使用 fetch API 时设置超时的例子:
const fetchWithTimeout = (resource, options = {}) => { const { timeout = 8000 } = options; // 设置默认超时时间为8000ms const controller = new AbortController(); const id = setTimeout(() => controller.abort(), timeout); const response = fetch(resource, { ...options, signal: controller.signal }).then((response) => { clearTimeout(id); return response; }).catch((error) => { clearTimeout(id); throw error; }); return response; }; // 使用这个函数进行fetch请求并设置超时 fetchWithTimeout('https://your-api-endpoint.com', { timeout: 5000 }) // 设置5秒的超时 .
淘宝/天猫获得淘宝商品详情的具体用途如下:
电商平台运营:电商平台需要收集商品的详细信息,包括商品名称、描述、价格、规格、图片等,以便展示给用户进行购买决策。通过采集商品详情,电商平台可以提供丰富的商品信息给用户,并增加用户购买的便利性,提升用户体验。价格比较:通过采集不同电商平台或线下店铺的商品详情,可以进行价格比较,帮助消费者找到最合适的购买渠道,节省购物成本。数据分析和市场研究:采集商品详情可以提供大量的商品数据,通过对这些数据进行分析和挖掘,可以了解市场上不同商品的销售情况、价格趋势、受欢迎程度等信息,为企业制定销售策略和市场调研提供参考依据。库存管理:企业可以通过采集商品详情及时了解库存情况,及时补充缺货商品,避免因缺货而导致销售损失。商品评价和反馈分析:采集商品详情中的用户评价和反馈数据,可以帮助企业了解消费者对商品的满意度和意见,改进产品质量和服务,提升用户体验。
淘宝商品详情API可以运用在以下几个方面:
电子商务平台:商品详情API接口可以提供商品的基本信息,如名称、描述、价格、图片等,帮助电子商务平台展示和推荐商品。此外,还可以提供商品的库存信息、销售数据、评论信息等,帮助平台进行数据分析和管理。零售电商APP:商品详情API接口可以提供商品的详细信息,帮助APP展示商品的图片、规格、参数等,以及提供购买、加入购物车等功能。此外,还可以提供商品的推荐信息,例如相关产品、搭配推荐等,帮助用户进行购物决策。搜索引擎:商品详情API接口可以提供商品的基本信息和元数据,帮助搜索引擎对商品进行索引和展示。例如,用户在搜索引擎中搜索某个商品时,可以展示来自不同电子商务平台的商品详情信息。广告系统:商品详情API接口可以提供商品的基本信息和元数据,帮助广告系统进行广告投放和推荐。例如,可以将商品信息与广告受众进行匹配,实现精准广告投放。价格比较工具:通过采集不同电商平台或线下店铺的商品详情,可以进行价格比较,帮助消费者找到最合适的购买渠道,节省购物成本。数据分析和市场研究:采集商品详情可以提供大量的商品数据,通过对这些数据进行分析和挖掘,可以了解市场上不同商品的销售情况、价格趋势、受欢迎程度等信息,为企业制定销售策略和市场调研提供参考依据。 总的来说,这些信息对于商家和开发者来说是非常有价值的,可以帮助他们更好地了解市场需求和消费者行为,优化销售策略和提高市场竞争力。同时,对于消费者来说,也可以提高购物的便利性和效率。
接口地址 https://chat.xutongbao.top/api/light/chat/createChatCompletion
请求方式 post
请求参数 model可选值:
“gpt-3.5-turbo-1106”、 “gpt-3.5-turbo-16k” 、 “gpt-4”、“gpt-4-1106-preview”。 默认值为: “gpt-3.5-turbo-1106”
token获取方式:
访问:https://chat.xutongbao.top/
使用邮箱注册账号
点击【我的】
点击【API】
前端发起请求的方法 fetch
示例代码 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Document</title> </head> <body> <textarea id="input"></textarea> <div> <button onclick="handleSend()">发送</button> </div> <div id="result"></div> <script> async function handleSend() { let messageHot = '' document.getElementById('result').innerHTML = '' let content = document.getElementById('input').value document.getElementById('input').value = '' const response = await fetch( `https://chat.xutongbao.top/api/light/chat/createChatCompletion`, { method: 'post', headers: { 'Content-Type': 'application/json', Accept: 'text/event-stream', }, body: JSON.
%% mesh函数:绘制出在某一区间内完整的网格图 %% mesh(X,Y,Z)的用法,其中X是n维向量,Y是m维向量,Z是m*n维的矩阵 X = [1,2,4] Y = [3,5] Z = [4,8,10;5,9,13] mesh(X,Y,Z) % (X(j), Y(i), Z(i,j))是线框网格线的交点的坐标 xlabel('x轴'); ylabel('y轴'); zlabel('z轴'); % 加上坐标轴的标签 % 三维旋转和数据游标的使用,以及X-Y视图的切换(在三维旋转状态下点击鼠标右键) % 数据游标默认只能添加一个,按住Alt键不动,可以添加多个数据游标 % 插入颜色栏,可显示色阶 %% mesh(Z)的用法,其中Z是m*n维的矩阵 Z = [4,8,10;5,9,13] mesh(Z) xlabel('x轴'); ylabel('y轴'); zlabel('z轴'); % 加上坐标轴的标签 % 等价于 X = 1:3 Y = 1:2 Z = [4,8,10;5,9,13] mesh(X,Y,Z) xlabel('x轴'); ylabel('y轴'); zlabel('z轴'); % 加上坐标轴的标签 %% 思考:如果X中元素不是按照从小到大排序的,图像会是什么样子? X = [1,10,4] Y = [3,5] Z = [4,8,10;5,9,13] mesh(X,Y,Z) hidden off % 可以看到背部的图像,不会遮挡(默认是看不到的) xlabel('x轴'); ylabel('y轴'); zlabel('z轴'); % 加上坐标轴的标签 % 如果觉得背部的图像显示的颜色太深了,可以更改透明度 mesh(X,Y,Z) alpha(0.
文章目录 一、Executor接口二、ExecutorService接口三、ThreadPoolExecutor类1、状态2、Worker3、扩展 四、ForkJoinPool类1、工作窃取算法2、Fork/Join的设计3、执行原理 五、ScheduledThreadPool类1、ScheduledExecutorService2、比较Timer 六、Executors类 Executor 框架是 Java5 之后引进的,在 Java 5 之后,通过 Executor 来启动线程比使用 Thread 的 start 方法更好,除了更易管理,效率更好(用线程池实现,节约开销)。 Executor 框架不仅包括了线程池的管理,还提供了线程工厂、队列以及拒绝策略等,Executor 框架让并发编程变得更加简单。
Executor框架的组成:
任务(Runnable/Callable):任务通过Runnable接口或Callable接口进行定义。Runnable接口或Callable接口实现类都可以被 ThreadPoolExecutor执行任务的执行(Executor):任务执行机制的核心接口 Executor,以及继承自Executor接口的ExecutorService接口。ThreadPoolExecutor实现了ExecutorService接口异步的计算结果(Future):Future接口以及Future接口的实现类FutureTask类都可以代表异步计算的结果。当我们把Runnable接口或Callable接口的实现类提交给ThreadPoolExecutor执行后就会返回一个Future对象 一、Executor接口 线程池简化了线程的管理工作, 并且JUC提供了一种灵活的线程池实现来作为Executor框架的一部分。在Java类库中,任务执行的主要抽象不是Thread而是Executor,Executor只定义了execute一个方法,是最顶层的接口。
/** * Executes the given command at some time in the future. The command * may execute in a new thread, in a pooled thread, or in the calling * thread, at the discretion of the {@code Executor} implementation. * * @param command the runnable task * @throws RejectedExecutionException if this task cannot be * accepted for execution * @throws NullPointerException if command is null */ void execute(Runnable command); execute方法接受一个Runnable参数,这个方法定义为在未来的某个时间执行传入的方法,方法的运行可以在一个新的线程,在线程池或者在调用的线程中,该方法无法接收到线程的执行结果(当然Runnable接口本身也没有返回值)。
临时修改,只作用于当前打开的窗口 进入cmd窗口后,直接执行 chcp 65001执行完后,cmd的编码格式就是UTF-8 永久修改,修改注册表 在运行中输入 regedit,找到 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Command Processor,然后 “右键-新建”,选择 “字符串值”,“名称” 列填写 autorun,数值数据填写 chcp 65001,注意中间有个空格。添加成功后,再次在运行中输入 cmd,就会自动把编码格式设置为 UTF-8
示例
列表是元素的集合,存储在一个变量中。列表中存储的元素类型没有限制,下面是列表的一个简单例子。
students = ['bernice', 'arron', 'cody'] for student in students: print("Hello, " + student.title() + "!") 命名和定义列表
因为列表是对象的集合,所以给它们一个复数的名称是很好的做法。如果列表中的每一项都是一个 car, 就命名列表为 'cars'。这样给你了一种直接的方式代表列表('cars'),(’dog‘)指代列表项。
在 Python 中,用中括号定义一个列表。如下所示:
dogs = ['border collie', 'australian cattle dog', 'labrador retriever'] 访问列表元素
列表中的元素通过位置来标识,从零开始。访问列表中的第一个元素,如下所示:
dogs = ['border collie', 'australian cattle dog', 'labrador retriever'] dog = dogs[0] print(dog.title()) 括号中的数字为列表的索引(index)。因为列表索引从0开始,列表元素的索引总是比它的位置小。因此 Python 被称为 zero-indexed 语言(诸如 C, Java)。
因此访问第二个元素,我们需要用索引1,以此类推。
dog = dogs[1] print(dog.title()) 访问列表中最后一个元素
访问列表中的最后一个元素,可以用索引 -1。
dog = dogs[-1] print(dog.title()) 访问倒数第二个,倒数第三个也可以用这种语法。
什么是栈? 一种特殊的线性表,只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈顶,另一端称为栈底。栈中的数据元素遵守后进先出(LIFO - Last In First Out)的原则。
从数据结构的角度来看,栈 就是一种数据结构。
压栈 和 出栈
压栈:栈的插入操作叫做进栈/压栈/入栈,入数据在栈顶。出栈:栈的删除操作叫做出栈。出数据在栈顶。 Java 虚拟机栈 Java 虚拟机 JVM 可分五个部分
方法区:存放类定义信息、字节码、常量等数据,在Sun HotSpot JVM中,这块也称为Perm Gen。
堆:创建的对象信息将放入堆中,堆内部如何实现各虚拟机各不相同,对于Sun HotSpot JVM来说又分为Young Gen和Tenured Gen,更详细描述参见《[Java性能剖析]Sun JVM内存管理和垃圾回收 》
Java栈:对于每个执行线程,会分配一个Java栈,JVM在执行过程当中,每执行一个方法,都会为方法在当前栈中增加一个栈帧,每个栈帧的信息与具体实现相关,但一般会由3部分组成:变量区,方法参数和本地变量会放入这个位置,大小是固定的,在进行方法时会先分配好,在类定义中,会由max local来指定这块区的大小;方法信息区,会包括当前类常量池的入口地址等信息,这块大小也是固定的;操作栈,与Intel体系架构中的运算使用寄存器来进行不一样,JVM的字节码的方法调用、运算等需要的参数,都是通过操作栈来传递的。在类定义中,会由max stack指定最大的操作栈。关于Java栈的更详细描述参见《Java 栈内存介绍 》
本地方法栈:对本地方法的调用,并不会使用Java栈而是使用本地方法栈,本地方法栈的组成取决于所使用的平台和操作系统.
PC寄存器/程序计数器:对于每个执行线程会分配一个PC寄存器,寄存器中存放当前字节码的执行位置 栈帧 在调用函数的时候,我们会为这个函数在java虚拟机栈中开辟一块内存,叫做栈帧。 栈的使用 1.入栈 和 出栈的顺序 中缀 和 后缀 表达式的表现形式 中缀表达式:最常见的表达式,就是我们平常使用的: a + b、a - c、a * b、a/b。
还可以加括号 (5 + 4) * 3 - 2。
后缀表达式:就拿中缀的式子【(5 + 4) * 3 - 2】来说,它的后缀表达式为 54+ 3 * 2 -
pymssql._pymssql.OperationalError: (20009, b’DB-Lib error message 20009, severity 9:\nUnable to conn
severity 9:\nAdaptive Server connection failed
打开sql server 配置管理器。
将TPC/IP 启用
import pyodbc
Replace ‘server_name’, ‘database_name’, ‘username’, and ‘password’ with your server name, database name, username, and password conn = pyodbc.connect(‘DRIVER={ODBC Driver 17 for SQL Server};SERVER=server_name;DATABASE=database_name;UID=username;PWD=password’) cursor = conn.cursor()# Replace ‘table_name’ with the name of your table cursor.execute(‘SELECT * FROM table_name’) for row in cursor: print(row) Close the connectionconn.close()
一.简介 1.1 什么是stable diffusion
Stable Diffusion译为稳定扩散,是一个开源的图像生成AI系统,由Anthropic公司开发,我们可以通过文字描述生成图片,让AI根据我们的想象画出一幅图来,也可以通过图像生成图片,将现实世界中的照片经过AI处理变成二次元画风
其原理是增加噪声,去除噪声的过程,如下图所示(截图来自B站,Nenly同学)
1.2 组成部分
模型: 通过大量素材训练得到的模型,模型决定出图风格,如果训练的是二次元素材,就出二次元风格的,写实风就出写实风格
模型下载网站:
奇维泰
抱脸
Art提示词: 由英文单词组成,半角逗号隔开,分为正向提示词和反向提示词,正向输入想生成图片的一些特征,即图片中想要呈现的东西,反向提示词就是告诉AI,图片中不想要出现的东西迭代步数: 默认20,也就是AI处理图片的次数,值越高图片质量越精细,速度越慢采样方法: 是一种用于模拟随机过程的方法,它可以模拟具有长尾分布的随机变量。该方法的主要思想是将随机变量分解为稳定分布和正态分布的组合,然后使用随机数生成器来模拟这些分布。
… 二.如何使用 2.1 在线AI生成网站
https://www.liblib.ai 国内的生成网站,无需梯子,每天免费生成100次https://dreamstudio.ai 需要梯子,积分制,首次赠送100,生图1次消耗3~4积分https://lexica.art 需要梯子,只支持模型Lexica Aperture v2,生图质量极高https://playgroundai.com 需要梯子,可免费生图1000次,支持SD1.5,SD2.1,自有模型Playground AI 2.2 本地安装
对硬件要求比较高,必须是独立显卡,显存6G以上,显卡越好,生成速度越快,质量越好
优势:
无限制安装各种插件,例如换脸插件roop,人脸修复ADetailer,ControlNet等插件没有使用次数限制
安装教程 stable diffusion主界面(秋叶整合版):
二.文生图 提示词基本格式:
人物及主体特征: 1girl(1男孩),1boy(1女孩)…场景特征: outdoor(室外),indoor(室内)…环境光照: day(白天),night(夜晚)…画幅视角: close-up(特写),full body(全身)… 示例一:
正向提示词:
identification photo,1 girl,long hair,bangs,looking at viewer,(blue suit,blue tie,Far Mountain background:1.3),happy,smile,highres,outdoors,naughty_face,
反向提示词:
EasyNegative,badhandv4,ng_deepnegative_v1_75t,(worst quality:2), (low quality:2), (normal quality:2), lowres, ((monochrome)), ((grayscale)), bad anatomy,DeepNegative, skin spots, acnes, skin blemishes,(fat:1.
一、沟通常见几大误区
所以,想要消弥情感纠纷,化解利益冲突,我们就要学会沟通,不断打破自己的边界,才能拥有更丝滑、更良性的互动氛围。
但在日常沟通中,我们往往会存在几个误区:
1.只有双方都明确,沟通才会开始 我们常说,“沟通,要先有一个良好的沟通态度。”
所以很多时候,我们以为只要我单方面主动、积极地沟通,就是良好沟通的开始。
但往往你会发现,我都主动地想要化解问题了,为什么对方还是不想搭理我?甚至愈发不耐烦,全身上下都在抗拒我?
其实,良好的互动,是建立在双方都明确想要沟通的基础上。如果对方回避、不想沟通时,无论你怎么努力,都是在适得其反。
另外,沟通不是从我们说话开始的,而是从我们和对方碰面那一刻开始了。
很多时候,我们的意图是想把话说明白,找到问题、化解矛盾,但你说话前的肢体动作、愤怒表情,会给对方传达出:你还在情绪中,吵下去只会矛盾升级,并不能心平气和地解决问题。
2.沟通得多,不代表沟通得好 沟通得多,也并不代表沟通得好。
当你以为自己在努力地找对方沟通时,在对方眼里:你可能只是在持续地传递负面情绪,反而会阻碍对方沟通的意愿;或者使得两人卷入更长时间的争吵,激发更大的负面情绪。
另外,不是所有的问题,都可以通过沟通来解决。
解决问题,需要双方共同的意愿和努力,如果沟通很顺畅,双方也都很坦诚,最后却很难落到现实的改变,问题也无法得到解决。
虽然解决不了所有问题,但好的沟通,一定可以帮助你更好地了解你所处的现状。
3.好的沟通≠搞好关系 好的社交和沟通能力,可以促进好的关系产生,但并不意味着你要跟每个人搞好关系。
现代社会,每一个个体都越来越独立,大家更多讲究的是高效合作而不是低效人情。
一个创业者曾讲了一个故事。他新招了一个助理,有一天,助理非常苦恼地对他说:“我特别不擅长拉关系,跟领导沟通不会拍马屁,在公司没有存在感。”
他很意外:“跟领导沟通不需要拍马屁啊。”
小助理一愣。
他接着说;“如果你什么都干不好,拍马屁是没有用的。领导喜欢的是,业务能力强的人。跟领导沟通,把业务说清楚,比刻意讨好重要的多。”
这个道理看似简单,但很多人都没想明白。
事实上,沟通从来不是拉关系,沟通的本质是有效的信息传递。
二、高效沟通的三个要点:
准确、舒服、有边界
所以,沟通你不需要面面俱到,说难也很简单,它只需要掌握几个核心,就可以在各种场合游刃有余。
好的沟通,往往有三个要点:准确,舒服,有边界。
1.“沟”:准确,高效地传递信息 脱口秀演员在创作段子时,有一个原则就是:精简。
因为简洁即幽默,任何冗余和累赘都是好笑最大的敌人。如果你给了太多的无效信息,最后讲出笑点的时候,大家往往会觉得:啊?就这?
一件事如果你不能用简洁明了地语言表达出来,说明你还没想明白。举一个思文曾在《脱口秀大会》上说过的段子:
女人啊,即便是美貌,也需要你的经济能力做支撑。因为你可以买各种衣服啊,护肤品啊,美容卡啊。
俗话说得好,没有丑女人,只有穷女人,你别看吴昕现在长得好看,你都不知道她以前没钱的时候,有多年轻。
这段话铺垫的就很简洁,观众一下就能捕捉到笑点——女人有钱才好看。吴昕有钱好看,没钱的时候,一个干脆的反转——年轻!
如果这段话,加上一下废话后就变成下边这样,你感受一下效果。
有一句俗话,相信很多人都听过,叫“没有丑女人,只有懒女人”。这句话说的就是女人要有钱,你不够漂亮就是因为你没有足够的经济实力把自己打扮得漂亮。
只要你有钱,就能花钱让自己变得漂亮。你可以买各种衣服啊,化妆品啊,护肤品啊,做保养,做美容……
就拿吴昕来说吧,你看她现在长得多好看,但是你如果不看她现在,放到以前再看她,那个时候啊,她很年轻。
是不是觉得,啰里吧嗦的,这是在说啥呢?
不只是讲脱口秀,日常沟通也一样,需要给信息提纯。大多数人总习惯描述一件事的时候,添加无关紧要的细节,大大削弱了想要准确表达的信息度。
你可以尝试把想要表达的内容列出来,再把无关的信息的删掉,剩余的按照有序的方式说出来就可以了。
2.“通”:有来有往,舒服地接收信息 我们日常沟通,往往不是单向表达就能搞定的。人与人之间的沟通是传递信息,接受信息,再反馈信息的过程。
这就需要你在其中把握谈话的节奏,调节氛围,让对话人感到舒服。
如何做到“双向往来”,让对方舒服地接收信息?两个技巧分享给你。
① 控制情绪,不阻断沟通
我们都遇到过这样的情况,谈话的一方说话火药味很重,带着浓浓地攻击性。那另一方给予反馈的时候,出于自我防御机制,也会与你针锋相对。双方情绪暗潮汹涌,往往就无法理性讨论问题,甚至会上升到争吵或者冷战。
想要在沟通中避免情绪化,一个简单的方法是避免用反问句。反问句背后是强烈的情绪,不满、质疑、鄙视等。
比如上级对下级说:“这个问题你都没想明白吗?”
父母对子女说:“这么简单的题,怎么就教不会你呢?”
妻子对丈夫说:”连个碗你都不会洗吗?”
说话人自以为在陈述现象,但是表达方式听到的人感到难受。反映在沟通上,就是抗拒、反驳,阻断了正常的交流。
正确地做法是多用陈述句。比如你将上面这句话,换成陈述句——
“这个问题你回去还得再考虑一下。”
“这道题,从这个角度你再想一想。”
“碗可能不够干净,得再洗一次。”
这样是不是就变得容易被人接受多了?把反问句从你的沟通语系里删掉,你的沟通会顺畅很多。
② 放下评价,与对方共情
在沟通中如果想让对方愿意你听说,并愿意告诉你一些自己的故事。首先要放下评判,尝试“共情”,努力理解对方。
这一点从不少访谈节目中,就可以看出答案。一个好的访谈主持人,并不会直接表达对采访对象的个人评价,更多是给予理解和倾听,营造出一个安全的表达环境,激发出对方的表达欲。
就比如一个负面缠身的商业大佬,你让他去复盘自己的过往、得失,以及他们面对外界巨大负面评价时候的内心想法,是非常困难的。最好的办法就是让他感到你的诚恳——不评判。
对一个表达欲强、言辞犀利的采访嘉宾,你不能问他:“为什么你要抨击竞对?”“网上都说您说话欠妥当。你认为呢?”
你得这样表达,“当时是什么情况,让你选择会这么做?”“作为拥有一定知名度的创业者,面对这样的负面,会觉得压力很大吗?当时你是如何度过这段时间的?”
当谈话对象感受到“被理解”,“你站在他这边的“,谈话才能顺畅地进行下去。
3.会说话的人自带边界感 与人沟通时,你面对的是一个复杂环境。“怎么说”比“说什么”更重要。每次遇到的场景和人不同,该说什么话,把握什么样的分寸都需要揣摩。
1、什么是 Spring Cloud? Spring cloud 流应用程序启动器是基于 Spring Boot 的 Spring 集成应用程序, 提供与外部系统的集成。Spring cloud Task,一个生命周期短暂的微服务框架, 用于快速构建执行有限数据处理的应用程序。 2、使用 Spring Cloud 有什么优势? 使用 Spring Boot 开发分布式微服务时,我们面临以下问题 1、与分布式系统相关的复杂性-这种开销包括网络问题,延迟开销,带宽问题, 安全问题。 2、服务发现-服务发现工具管理群集中的流程和服务如何查找和互相交谈。它涉 及一个服务目录,在该目录中注册服务,然后能够查找并连接到该目录中的服务。 3、冗余-分布式系统中的冗余问题。 4、负载平衡 --负载平衡改善跨多个计算资源的工作负荷,诸如计算机,计算机 集群,网络链路,中央处理单元,或磁盘驱动器的分布。 5、性能-问题 由于各种运营开销导致的性能问题。 6、部署复杂性-Devops 技能的要求。 3、服务注册和发现是什么意思?Spring Cloud 如何实现? 当我们开始一个项目时,我们通常在属性文件中进行所有的配置。随着越来越多 的服务开发和部署,添加和修改这些属性变得更加复杂。有些服务可能会下降, 而某些位置可能会发生变化。手动更改属性可能会产生问题。 Eureka 服务注册 和发现可以在这种情况下提供帮助。由于所有服务都在 Eureka 服务器上注册并通 过调用 Eureka 服务器完成查找,因此无需处理服务地点的任何更改和处理。 4、负载平衡的意义什么? 在计算中,负载平衡可以改善跨计算机,计算机集群,网络链接,中央处理单元 或磁盘驱动器等多种计算资源的工作负载分布。负载平衡旨在优化资源使用,最 大化吞吐量,最小化响应时间并避免任何单一资源的过载。使用多个组件进行负 载平衡而不是单个组件可能会通过冗余来提高可靠性和可用性。负载平衡通常涉 及专用软件或硬件,例如多层交换机或域名系统服务器进程。 5、什么是 Hystrix?它如何实现容错? Hystrix 是一个延迟和容错库,旨在隔离远程系统,服务和第三方库的访问点,当 出现故障是不可避免的故障时,停止级联故障并在复杂的分布式系统中实现弹性。 通常对于使用微服务架构开发的系统,涉及到许多微服务。这些微服务彼此协作。 思考以下微服务 假设如果上图中的微服务 9 失败了,那么使用传统方法我们将传播一个异常。但 这仍然会导致整个系统崩溃。 随着微服务数量的增加,这个问题变得更加复杂。微服务的数量可以高达 1000. 这是 hystrix 出现的地方 我们将使用 Hystrix 在这种情况下的 Fallback 方法功能。 我们有两个服务 employee-consumer 使用由 employee-consumer 公开的服务。 简化图如下所示 现在假设由于某种原因,employee-producer 公开的服务会抛出异常。我们在这 种情况下使用 Hystrix 定义了一个回退方法。这种后备方法应该具有与公开服务相 同的返回类型。如果暴露服务中出现异常,则回退方法将返回一些值。 6、什么是 Hystrix 断路器?我们需要它吗? 由于某些原因,employee-consumer 公开服务会引发异常。在这种情况下使用 Hystrix 我们定义了一个回退方法。如果在公开服务中发生异常,则回退方法返回 一些默认值。 如果 firstPage method() 中的异常继续发生,则 Hystrix 电路将中断,并且员工 使用者将一起跳过 firtsPage 方法,并直接调用回退方法。 断路器的目的是给第 一页方法或第一页方法可能调用的其他方法留出时间,并导致异常恢复。可能发 生的情况是,在负载较小的情况下,导致异常的问题有更好的恢复机会 。 7、什么是 Netflix Feign?它的优点是什么? Feign 是受到 Retrofit,JAXRS-2.
需求 以前用的都是CentOS红帽系的Linux系统,修改IP地址都是滚瓜烂熟的命令,但kylinOS虽然也有相同的文件、相同的命令,但配置IP的方式还是不一样(相同操作在麒麟上不生效)。
查询了麒麟的管理手册,具体配置IP的方式如下。
麒麟Linux配置IP/kylinosv10配置IP 动态IP 打开终端,以网口 eth0 为例,粘贴以下代码即可,
nmcli conn add connection.id eth0-dhcp type ether ifname eth0 ipv4.method auto 其中“eth0-dhcp”为连接的名字,可以根据自己的需要命名方便记忆和操作的名字;“ifname eth0”为配置的网口,根据自己的设备情况按需调整
静态IP 打开终端,以网口 eth0 为例,粘贴以下代码即可,
nmcli conn add connection.id eth0-static type ether ifname eth0 ipv4.method manual ipv4.address 192.168.1.10/24 ipv4.gateway 192.168.1.254 ipv4.dns 192.168.1.254 其中“eth0-static”为连接的名字,可以根据自己的需要命名方便记忆和操作的名字;“ifname eth0”为配置的网口,根据设备情况按需调整;IP、子网掩码、网关根据实际网络按需配置。
注意 需要保证对应网卡、虚拟机网卡、vlan-tag对应正确。
操作即刻生效。
最近OpenAI发布了震撼更新,推出了革命性的GPTs,GPTs 是 ChatGPT 的自定义版本,用户可以通过组合指令、知识和功能来针对特定任务或主题进行定制。
说得直白一点就是chatGPT相当于一个操作系统,开发者基于chatGPT环境提供的AI能力和调用其他接口开发程序,称为GPT程序或GPT应用,程序托管运行在chatGPT环境,用户可以通过上下文对话使用。
ChatGPT跟GPTs应用的关系,相当于手机和手机应用的关系,只是把交互形式变成了自然语言对话。
最近很多小伙伴反映使用GPTs出现错误You do not currently have access to this feature
错误原因: ChatGPT使用GPTs出现错误You do not currently have access to this feature | Read dev Docs 博客
poi导出excel模板——通过建造者模式+策略模式+函数式接口实现 poi导出excel示例优化思路代码实现补充建造者模式策略模式 poi导出excel示例 首先我们现看一下poi如何导出excel,这里举个例子:目前想要导出一个Map<sex,List>信息,sex作为一个sheet页,Person信息包含姓名、年龄、籍贯等,在Person下还有一个List属性,里面包含名称、时长等,这里需要通过http的response导出文件
代码如下:
import org.apache.poi.ss.usermodel.*; import org.apache.poi.xssf.usermodel.XSSFWorkbook; import org.apache.poi.hssf.usermodel.HSSFWorkbook; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.List; import java.util.Map; public class ExcelExportExample { public static void exportToResponse(Map<String, List<Person>> data, HttpServletResponse response) { try { response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); // 对于.xlsx格式 // 或者使用 response.setContentType("application/vnd.ms-excel"); 对于.xls格式 response.setHeader("Content-Disposition", "attachment; filename=output.xlsx"); // 文件名可以根据需要修改 try (Workbook workbook = new XSSFWorkbook()) { // 或者使用 HSSFWorkbook for .xls 格式 for (Map.Entry<String, List<Person>> entry : data.entrySet()) { String sheetName = entry.
vxetable右键菜单选项如何添加权限及根据行的数据渲染 业务场景: 页面做了按钮权限,表格上也做了右键菜单的功能,也需要给右键菜单做权限功能控制
解决思路: 通过查看文档,右键配置 menu-config选择有个属性 visibleMethod (文档说明:该函数的返回值用来决定是否允许显示右键菜单(对于需要对菜单进行权限控制时可能会用到)),它可以获取到这些数据
({ type, options, columns, row?, rowIndex?, column?, columnIndex? }) => boolean // options 就是我们的配置数据 // row 是当前点击的行 配置右键的选项的时候增加一个属性 auth: ["权限编码"]
需要用到 hooks 中的 usePermission 方法,来验证权限
在visibleMethod 中 去遍历 options 中的auth属性,去验证 是否有权限
代码参考 vxeTable 配置
... menuConfig: { // 右键配置 body: { options: [Options()], }, visibleMethod: visibleMethod, }, ... //options 配置 const orderClassTableMenuConfigOptions = () => { return [ { code: 'refresh', name: '刷新', prefixIcon: 'vxe-icon-refresh', visible: true, disabled: false, }, { code: 'add', name: '新增', prefixIcon: 'vxe-icon-feedback', visible: true, disabled: false, auth: ["
1.准备工作 无须下载python,git等软件
首先需要有VScode和ESP的离线包
下载的链接放在下面:下载自己需要的版本,ESP最好知道你要用的代码是那个版本搭建的,不然无法正常编译。版本之间有差异
VScoed:Download Visual Studio Code - Mac, Linux, Windows
ESP:dl.espressif.cn/dl/esp-idf/
2.环境搭建 1.下载应用 VScode的安装没什么好说的,有疑惑可以找一下教程。
关于ESP的安装,如果是首次安装需要点击应用修复
其次就是注意选择你所需要的单片机型号,其他的一直下一步等待安装即可,大概需要4.5分钟
2.ESP系统环境配置 解压esp的文件下新建工程Tools
打开VScode下载Espressif IDF的插件
进入命令面板
1.点击查看->命令面板
2.电脑按下F1键,笔记本按下Fn+F1键
输入ESP-IDF,找到插件配置
点击Install.等待下载
下载可能会卡在Python的虚拟环境。如图所示
如果输出是下图所示,说明应该升级PIP
升级pip是可能出现无法下载成功的情况,原因是国外的现在太慢。对Pythone进行换源就可以解决这个问题。
首先进入通过windows+r进入CMD模式
然后根据输出我们应该在虚拟python文件下升级PIP。依次输入
E: cd e:\ESP32\Tools\python_env\idf4.4_py3.8_env\Scripts python.exe -m pip install --upgrade pip 可以输入pip list验证的pip版本
然后再次进入ESP的插件配置,点击第三个
再次进去与第一不一样【如果与第一次一样代表安装失败】,可以显示我们已经安装好的ESP,单击安装安装好的,再次运行
这样就表示安装成功了
查看配置路径
依次点击第一第二选项,看是否与你开始选择文件夹位置一样。
【后续一直别人的代码需要用到这一步】
3.例程创建编译及代码烧录 创建例程
笔记本Fn+F1电脑F1进入命令面板,输入ESP-IDF Example展示例程
随机选择一个进行移植,等待编译,一两分钟左右。
编译结果显示如下,代表显示成功
点击COM可以切换串口,点击ESP32可以切换型号,第四个是SDK配置,第五个是删除build【删除已经运行好的文件】,第五个是生成bulid,也是编译的意思,倒数第一个就是烧录的意思。
在编译时可能出现.csv的报错
4.已有工程移植 用VScode打开已有工程
首先配置串口和删除Build
进入到配置路径,这个是原来文件的路径【IDF-PATH和IDF-TOOLS-PATN都要修改为你开始选择的路径】
修改为我们的路径并按下回车键
进行编译,如果上述按照过程一般不会出错。
点击最后一个火花是直接编译加下载,下载成功界面,下载前会让你选择下载器类型,根据实际情况选择
可能出现的错误:
如图错误是因为没有对应的自定义的分区表.cvs文件
通过点击齿轮的图标进入SDK设置
自己加上就可以 新建一个分区表文件,要与自己设置的或者默认的一样,放在工程目录下。我在文件里内容为