一、命名空间System.IO
C# 中I/O的操作都属于System.IO这个命名空间,在这个命名空间中C# 定义了文件相关的类、各种流、装饰器流、适配器以及其他一些相关的结构体。
在以System.IO开头的命名空间中,C#对IO进一步扩展,并提供了流压缩和解压缩(System.IO.Compression),
搜索和枚举文件系统元素(System.IO.Enumeration),提供用于使用内存映射文件的类(System.IO.MemoryMappedFiles)等内容。
二、C# IO Stream基类
C#中,所有流都是继承自Stream类,Stream类定义了流应该具有的行为和属性,使得开发人员可以忽略底层的操作系统和基础设备的具体细节。C#对流的处理忽略了读流和写流的区别,使其更像是一个管道,方便数据通信。流涉及到三个基本操作:
读取 - 将数据从流中传输到数据结构中写入 - 将数据从数据源写入流中查找 - 对流中操作的当前位置进行查找和修改因为流的特性,可能并不是所有的流都支持这三种操作,所以Stream提供了三个属性,以方便确认流是否支持这三种操作:
public abstract bool CanRead { get; } // 获取指示当前流是否支持读取的值 public abstract bool CanWrite { get; } // 获取指示当前流是否支持写入功能的值 public abstract bool CanSeek { get; } // 获取指示当前流是否支持查找功能的值 以上这三个属性均由子类根据自身特性确认是否支持读取、写入、查找,可能三个属性不会都为true,但绝对不会都为false。
下面是一些常见的流:
FileStream 用来操作文件的流MemoryStream 操作内存的流BufferedStream 缓存流,用来增强其他流的操作性能NetworkStream 使用网络套接字进行操作的流PipeStream 通过匿名和命名管道进行读取和写入CryptoStream 用于将数据流链接到加密转换 我们先略过之后篇幅会介绍的内容不提,先来看一下Stream类里重要的属性和方法:
1. 流里数据的长度
public abstract long Length { get; }
当Stream对象的CanSeek为true时,也就是流支持搜索的时候,可以通过这个属性确认流的长度,也就是有多少个字节的数据。
2. 流的位置
public abstract long Position { get; set; }
Flink安装包下载地址
1. standalone模式 解压安装Flink [root@bigdata1 software]# tar -zxvf flink-1.14.0-bin-scala_2.12.tgz -C /opt/module/ [root@bigdata1 module]# mv flink-1.14.0/ flink-standalone 进入conf修改flink-conf.yaml (cd /opt/module/flink-standalone/conf) jobmanager.rpc.address: bigdata01 flink中有jobmanager和taskmanager
修改wokers(路径同上) [root@test conf]# vim workers bigdata01 bigdata02 bigdata03 分发到集群其他节点 [root@bigdata1 module]# scp -r /opt/module/flink-standalone/ bigdata02:/opt/module [root@bigdata1 module]# scp -r /opt/module/flink-standalone/ bigdata03:/opt/module 启动Flink集群命令(在/opt/module/flink-standalone/下执行) bin/start-cluster.sh 浏览器访问 http://bigdata01:8081 可以对flink集群和任务进行监控管理。
停止Flink集群命令(在/opt/module/flink-standalone/下执行)
bin/stop-cluster.sh flink run org.example.wc.StreamingWordCount -p 1 wc.jar --host localhost --port 7777
flink list
2. Flink on Yarn模式(生产应用常用模式) 上传二进制包 解压缩 更改文件名称 配置环境变量
【各类好电影】
[最费脑力的14部电影】
《盗梦空间》、《记忆裂痕》、《生死停留》、《死亡幻觉》、《禁闭岛》、《穆赫兰道》、《蝴蝶效应》、《恐怖游轮》、《伤城》、《盗走达芬奇》、《88分钟》、《万能钥匙》、《决胜21点》、《沉默的羔羊》
【感动无数人的电影】
《恋空》《婚纱》《比悲伤更悲伤的故事》《我脑中的橡皮擦》《属于你的我的初恋》《夏天协奏曲》《天使之恋》《分手信》《近在咫尺的爱恋》
【15部让你哭的昏天暗地的电影】
《假如爱有天意》《我脑海中的橡皮擦》《情书》《恋空》《等待,只为与你相遇》《我们的幸福时光》《请别相信她》《触不到的恋人》《菊花香》《剪刀手爱德华》《海上钢琴师》《恋恋笔记本》《美丽心灵的永恒阳光》《泰坦尼克号》
【人生必看的10部电影】
爱情→《罗马假日》;
执着→《阿甘正传》;
哲理→《第七封印》;
才华→《莫扎特传》;
人生→《美国往事》;
童心→《ET》;
痛苦→《现代启示录》;
信念→《肖申克的救赎》;
责任→《辛德勒的名单》;
勇气→《勇敢的心》
【十部适合一个人静静看的电影】
1、阿甘正传
2、肖申克的救赎
3、触不到的恋人
4、海上钢琴师
5、千与千寻
6、雏菊
7、花样年华
8、幸福来敲门
9、蓝莓之夜
10、放牛班的春天
【10部震撼狙击手电影】
①《狙击电话亭》;
②《最后的莫希干人》;
③《敌人的荣誉》;
④《兵临城下》;
⑤《全金属外壳》、
⑥《快枪手 》;
⑦《双狙人》;
⑧《杀手悲歌》;
⑨《一号通缉令》;
⑩《最后刺客》
【亚洲十大恐怖电影】:
1.《咒怨》
2.鬼娃娃花子
3.《午夜凶铃》
4.《鬼来电》
5.《笔仙》
6.《解剖学教室》
7.《邪降》
8.《四人餐桌》
9.《人形师》
10.《凶相》
【12部让你笑喷的电影】
《神探飞机头》《我盛大的同志婚礼》《幸运库克》《校园卧底》《我的野蛮老师》《美女也烦恼》《疯狂的石头》《谋杀快乐》《XXXX》《我为玛丽狂》《美国派》《偷天情缘》
【18部讲述天才的电影】
《美丽心灵》、《雨人》、《波拉克》、《暗物质》、《想飞的钢琴少年》、《嫌疑人X的献身》、《十一罗汉》、《猫鼠游戏》、《香水》、《一级恐惧》、《心灵捕手》、《莫扎特传》、《证据》、《海上钢琴师》、《电锯惊魂》、《沉默的羔羊》、《非常嫌疑犯》、《寻找弗罗斯特》。
最酷的狗:《101真狗》
最可爱的狗:《狗狗心事》
最红的狗:《史努比》
最搞怪的狗:《家有贱狗》
最苦命的狗:《龙龙与忠狗》
最懂孙子兵法的狗:《猫狗大战》
最大无畏的狗:《酷狗正传》
最会装傻的狗:《酷狗宝贝》
最忠心的狗:《导盲犬小Q》
最早狗明星:《灵犬莱西》
【哈佛商学院要求学生必看的10部经典电影】
《华尔街》《大亨游戏》《颠倒乾坤》《抢钱大作战》《硅谷传奇》《可口可乐小子》《发达之路》《大公司小老板》《巴塞罗那》《社交网络》
【最美的10部电影】
Compose中常用的一些Modifier的扩展ui方法记录 关于防快速点击虚实分割线虚线边框阴影 关于 本篇主要记录一些开发中可能用到的常用方法的扩展记录,包括防快速带点击,画虚实线divider,画虚线边框,绘制阴影等。
防快速点击 inline fun Modifier.singleClickable( debounceDuration: Long = 400L, enabled: Boolean = true,//中间这三个是clickable自带的参数 rippleEnabled: Boolean = true, //是否开启水波纹 onClickLabel: String? = null, role: Role? = null, crossinline onClick: () -> Unit ): Modifier = composed { var lastClickTime by remember { mutableStateOf(value = 0L) } val eventAction: () -> Unit = { val currentTimeMillis = System.currentTimeMillis() if (currentTimeMillis - debounceDuration >= lastClickTime) { onClick() lastClickTime = currentTimeMillis } } if (rippleEnabled) { clickable(enabled, onClickLabel, role, eventAction) } else { clickable( interactionSource = NoRippleInteractionSource(), indication = null, enabled = enabled, onClickLabel = onClickLabel, role = role, onClick = eventAction ) } } class NoRippleInteractionSource : MutableInteractionSource { override val interactions: Flow<Interaction> = emptyFlow() override suspend fun emit(interaction: Interaction) {} override fun tryEmit(interaction: Interaction) = true } 虚实分割线 /** * 虚实分割线 * 实线虚线长度都为10f 根据实际需求更改下方PathEffect里面的float参数数据 **/ internal fun Modifier.
关于推动可追溯代码来源的计划 缘由 在互联网上,很多技术博客和文章引入代码段来帮助读者理解技术思路或记录对某个大型模块的原理分析和理解。然而,由于版本管理和技术变化,很多历史文章在读者读到精髓时,发现引入的代码块没有来源信息,导致不能对这个思路进行完整的了解,影响了读者的学习效果。
和ChatGpt 在关于这个问题上,做了一番详细的讨论,由此萌发了让我推动代码可溯源的动力。
在博客或文章中引入代码块但没有引入代码的来源可能导致以下问题:
缺乏参考和引用:不提供代码的来源将使读者难以查找和验证代码的准确性和可靠性。读者可能无法判断代码的作者、代码的版本或其他相关信息。侵权问题:如果你从其他来源复制了代码但没有引用或提及原始作者或代码来源,这可能构成侵权行为,违反了知识产权法律和道德规范。可信度和可复现性问题:提供代码的来源可以增强博客或文章的可信度。读者可以参考原始来源来验证代码,并获得更多的上下文信息。此外,如果读者想要在自己的环境中复现代码,代码的来源可以提供必要的指导和依赖信息。 为了解决这些问题,建议在博客或文章中引入代码块时,尽量提供代码的来源信息。这可以通过添加注释、链接到代码仓库或引用出处等方式来实现。这样可以提供更完整的信息,增加文章的可信度,同时尊重代码作者的权益。
差异 传统的Markdown语法 传统的Markdown语法中,并没有内置的方式来指定代码块的高亮行数。通常,Markdown的代码块只是用于展示代码,而不支持精确指定高亮行数的功能。
然而,一些扩展的Markdown解析器或编辑器可能提供了自定义的语法或插件,以支持在代码块中指定高亮行数。这些扩展可以根据不同的工具和插件而有所不同。
以下是一些常见的Markdown扩展和工具,它们可能提供了在代码块中指定高亮行数的功能:
GitHub Flavored Markdown (GFM)
GFM支持在代码块中使用类似{highlight}的语法来指定高亮行。例如: ```java {highlight=[1,3-5,7]} public class HelloWorld { public static void main(String[] args) { System.out.println("Hello, world!"); // 第1行、第3到第5行、第7行高亮 } } Markdown Extra
Markdown Extra是一种扩展的Markdown语法,支持类似GFM的高亮行语法。具体语法可能因工具而异,请查阅Markdown Extra的文档以了解详细信息。VS Code和其他编辑器插件
某些编辑器(如VS Code)提供了Markdown插件,可以使用特定的语法来指定高亮行。这些插件通常使用自定义的语法或标记来实现,具体的语法和用法可以查阅插件的文档。
请注意,这些功能的可用性和具体的语法取决于你所使用的Markdown解析器、编辑器或扩展。建议查阅相关工具的文档以了解是否支持在代码块中指定高亮行数,并找到相应的语法或插件来满足你的需求。Github Github Markdown
有人对此有一些建议 Allow to highlight lines in a code block (github flavored markdown) #42489
Github permalink
github提供一种可以支持高亮以及版本信息的永久链接,给这个项目提供了思路,通过 Shift 可以多选行数,然后右击选择 permalink(永久链接).
OomAdjuster.java#L3127-L3129
新的标准定义 和 ChatGpt 讨论如何设计新的标准过程中,对于新的标准定义,它也持续为了输出了想法:
目录
1、mybatis事物管理器
2、SpringManagedTransactionFactory如何处理事物
3、spring事物如何设置connection连接到threadLocal
1、mybatis事物管理器 mybatis事物抽象接口类:Transaction。该接口定义了事物基本方法和获取数据库连接方法
该类有三个实现类JdbcTransaction、ManagedTransaction、SpringManagedTransaction。
其中JdbcTransaction、ManagedTransaction是mybatis自己使用,不是我们关注的对象。我们重点关注SpringManagedTransaction,在spring环境中,mybatis使用该类来处理事物。
既然明确了是使用该类来处理事物,那我们先来看看在哪里初始化SpringManagedTransaction。老套路,ctrl+f, 发现只有在 SpringManagedTransactionFactory类中调用
继续查看 SpringManagedTransactionFactory 在哪里调用,发现是在org.mybatis.spring.SqlSessionFactoryBean#buildSqlSessionFactory()方法中初始化
mybatis-spring中,是通过SqlSessionFactoryBean#buildSqlSessionFactory()方法创建
SqlSessionFactory, 即说明mybatis-spring中默认使用SpringManagedTransactionFactory 为事物管理器。 2、SpringManagedTransactionFactory如何处理事物 从SpringManagedTransaction#getConnection()方法开始,到重点方法
DataSourceUtils.getConnection(this.dataSource)。其中DataSourceUtils类是spring提供的工具类 跟进去,查看DataSourceUtils#doGetConnection()源码,发现先从spring提供的threadLocal中获取connection连接,如果没有则重新获取,并且会通过 TransactionSynchronizationManager.isSynchronizationActive() 判断当前是否处于spring事物中,如果是则需要将connection连接绑定到spring threadLocal中。
至此,已经解决了mybatis是如何获取spring事物中的连接的。既然有获取,就有地方设置,那么下面我们再看spring事物是如何设置connection连接到threadLocal中的。
3、spring事物如何设置connection连接到threadLocal 熟悉spring事物的同学都知道,spring事物的增强是在TransactionInterceptor中的,那么我们直接看该方法的invoke方法
继续看核心方法TransactionAspectSupport#invokeWithinTransaction()方法
我们重点看TransactionAspectSupport#createTransactionIfNecessary()方法是如何处理的,跟进去最后会到TransactionAspectSupport#prepareTransactionInfo()方法,
最后会到TransactionAspectSupport.TransactionInfo#bindToThread()方法,继续跟进去
那么我们再看,发现和 DataSourceUtils 没有丝毫关系。说明我们找错了地方。
再次查看 TransactionSynchronizationManager#bindResource()方法调用地方,发现是在
AbstractPlatformTransactionManager#startTransaction()方法中绑定。那么
需要查看 AbstractPlatformTransactionManager 和 TransactionInterceptor 的关系。
发现 在初始化 TransactionInterceptor的时候,会设置 DataSourceTransactionManager。
再回头查看,发现此处会调用AbstractPlatformTransactionManager#getTransaction()方法。
继续跟,发现 此处会调用子类 DataSourceTransactionManager#doGetTransaction()方法
由于 doGetTransaction() 方法为获取已存在的事物,所以我们重点看新建事物的处理
在 DataSourceTransactionManager#doBegin()方法中,可以看到将新建的事物绑定到当前线程上下文
中间件为什么学?如何学?如何成为一个优秀的程序员?
我觉得优秀程序员要满足两点:1.扎实的编程语言基础数据结构基础,要能实现各种基本的crud需求,这是基础;2、就是了解工程上需要了解的知识,编程是一个系统性的工程。各个公司有自己的代码框架差异很大暂不讨论,但是常用的中间件能够帮助更好地编程实现,非常有用。所以要学。第三就是性能优化架构优化,当有了对整体系统的认知,准确找到性能瓶颈根据业务需求进行改进。
而在中间件这方面:
首先我现阶段注重的是广度和共性,系统观打牢,每个组件只是简单实践了一下(docker运行服务,nginx部署负载均衡,rpc简单使用),了解一下大体怎么运作的,没有更多复杂功能的尝试。要广泛了解各种中间件比如缓存,代理,容器,消息队列,rpc的架构思想,优秀的设计理念(比如抽象层次k8s,vfs,设计模式等)和数据结构(红黑树+链表,跳表等)。因为暂时没有业务环境,专注于某个组件钻牛角尖,可能以后都不会用到。所以注重整体学习,了解共性。
性能方面,对组件相应修改和自己创造,正在学习,比如在学习linux内核,性能之巅这本书。需要不断提高自己,才能不被轻易替代。
(中间件和性能方面,我觉得已知的未知更重要,也就是知道该从哪些方面做,只是还没有去做。)
**
docker: ** 出现是因为相比于虚拟机,资源复用更加灵活,虚拟机是一个完整的操作系统,占用空间大,启动慢;docker容器技术可以根据也无需求,配置不同的环境,不会互相影响。镜像操作方便迁移,实现build once run everywhere
docker主要就是隔离和标准化。核心技术是namespace技术和cgroup技术。
namespace是让不同容器看起来没有关联,防止不同空间命名冲突,比如pid,用户Id,ip地址等。
每一个容器有自己的ns, 就和多进程一样,一个进程的1234地址和另一个进程的1234地址不是一个物理地址(虚拟地址)。不同ns中相同的命名也不是真正相同的资源。
可以通过proc/pid/ns文件夹查看进程所属的ns,然后想要修改的话可以用nsenter进入指定的别的ns空间。
cgroup是用起来隔离的技术。树状结构组织,若干个进程组成cgroup,若干个cgroup树状排列,同时有很多树,代表不同的系统资源,CPU,内存,网络,设备等
可以进行一些资源的监控限制等操作,比如限制mysql一组进程核绑定,占用多大CPU时间,内存和带宽,可以访问哪些设备等等。
常用操作,
先拉取镜像 docker pull ubuntu
然后启动一个容器 docker run -i -t -name 名字 cmd
如果是交互式的话就是/bin/bash
docker image查看镜像
docker ps 查看容器 docker inspect c_id查看具体容器信息
docker top 容器id 查看其中的进程
编译dockfile还可以post发布镜像到docker_hub库里面,没试过。
我用它主要在两个方面,一个是计算机系统实验中,每次实验要装不同的环境,而且是不兼容的,所以为了方便,就用了docker加载镜像。不然的话就要卸载。
还有一个就是在docker部署网站。(静态)
步骤是,1.端口映射一下,docker run -p 80指定80端口。
2、下载nginx和vim. 写一个简单的html文件,修改nginx配置为那个文件,启动nginx。然后ctrl+Q退出,保证容器还是在运行的。然后docker port web查看一下映射情况,通过宿主机地址127.0.0.1加映射端口访问
**
k8s **
要知道k8s出现的原因,其实就是数据中心的操作系统,为了管理很多机器的软硬件资源的。
主要组成和操作系统类似。
调度器controller 进程线程进程组(docker pod service) 网络(每个pod有ip地址)存储(文件存储,对象存储,块存储,有自己的接口管理)和包管理工具helm
关注一下Kubernetes 会将 Service DNS的名字作为域名解析成为一个虚拟的 Cluster IP,然后通过负载均衡,转发到后端的 Pod。虽然 Pod 可能漂移,IP 会变,但是 Service 会一直不变。(Service就相当于一组pod,也就是实现某种功能的一个进程集合,比如mysql的一组进程,也就是说,在进行service作为虚拟ip的时候,真正到的pod会变飘逸的,但是service不会变的,有点类似于NAT,可以实现负载均衡了。)
一、什么是AOP(面向切面编程)?🍉 AOP 为 Aspect Oriented Programming 的缩写,意思为面向切面编程,是通过预编译方式 和运行期 动态代理 实现程序功能的统一维护的一种技术。
AOP (面向切面编程)是 OOP(面向对象) 的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程 的一种衍生范型。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。
二、AOP 的作用及其优势🍉 作用:在程序运行期间,在不修改源码的情况下对方法进行功能增强
优势:减少重复代码,提高开发效率,并且便于维护
三、AOP 的底层实现🍉 实际上,AOP 的底层是通过 Spring 提供的的动态代理技术实现 的。在运行期间,Spring通过动态代理技术动态的生成代理对象,代理对象方法执行时进行增强功能的介入,在去调用目标对象的方法,从而完成功能的增强。
动态代理的作用:
1)在目标类源代码不改变的情况下,增加功能。2)减少代码的重复3)专注业务逻辑代码4)解耦合,让你的业务功能和日志,事务非业务功能分离。 四、AOP 相关概念🍉 Spring 的 AOP 实现底层就是对动态代理的代码进行了封装 ,封装后我们只需要对需要关注的部分进行代码编写,并通过配置的方式完成指定目标的方法增强。
在正式讲解 AOP 的操作之前,我们必须理解 AOP 的相关术语,常用的术语如下:
切面(Aspect)
一个切面就是一个代理对象= 要为那些类生成代理+要添加的额外功能是那些 切入点(pointcut):将来要为那些类生成代理对象通知/ 增强(advice):就是要添加的额外功能 生活案例:给面包之间涂果酱
注意:切面(Aspect)=切入点(pointcut)+通知点(advice,额外功能)
AOP中的(面向切面编程)通知
前置通知:目标方法之前的额外功能 MethodBeforeAdvice 环绕通知:它是spring框架为我们提供的一种可以在代码中手动控制增强方法何时执行的方式 MethodInterceptor(Interceptor [ɪntəˈsɛptə]拦截器)
后置通知:目标方法之后的额外功能 AfterReturningAdvice(returning[rɪˈtɜːrnɪŋ])
异常通知:执行异常的额外功能 ThrowsAdvice
最终通知:一定执行的额外功能
Target(目标对象):代理的目标对象代理(Proxy[ˈprɑːksi]):一个类被AOP注入增强后,就产生一个结果代理类连接点(joinPoint):所谓连接点是指那些被拦截到的点。在spring中,这些点指的是方法(额外功能),因为spring只支持方法类型的连接点 五、切面编程步骤🍉 1、五种通知类🥝 AOP 切面=切入点+通知
前置通知:MethodBeforeAdvice
后置通知:AfterReturnAdvice
环绕通知:MethodInterceptor
异常通知:ThrowsAdvice(throw [θroʊz])
最终通知
数据库大表查询最好是根据区分度较高的索引查询,另外就是查询时候尽量避免指定排序字段。单表默认查询不加排序字段应该是自然排序,就是先插入的数据先查出来。在分页查询联多张表的字段时候一定要指定排序的字段否则可能会出现数据分页的错乱,因为多张联查可能无法获取自然排序。另外数据库关于行为与动作的数据表一定要有清理策略且清理策略最好只和时间戳相关,这样可以防止数据累积。关于表的历史数据可以采用数据库入湖或仓。另外关于系统压力测试一定要测试同一时间访问量巨大,数据库表中数据数量巨大,传输报文巨大等场景。做好系统服务扩容或降级与熔断等方案。另外服务器停机时一定要优雅停机保证数据库表不会产生无法处理的数据。
方法的签名是指方法的声明部分,其中包括方法的名称、参数列表和返回类型。方法签名是用来标识和区分不同方法的关键信息,它决定了方法的唯一性。
一个方法的签名由以下部分组成:
方法名:方法的名称用来唯一标识该方法。方法名在方法的声明部分中给出,用于调用该方法。
参数列表:方法的参数列表是一组用逗号分隔的参数,定义了方法接受的输入。参数列表中包含参数的数据类型和参数的名称。
返回类型:方法的返回类型定义了方法执行后返回的值的数据类型。如果方法不返回任何值,可以使用void关键字表示。
举例说明:
// 方法的签名为:add(int, int) int add(int num1, int num2) { return num1 + num2; } 在上面的例子中,方法的签名包含方法名称add、参数列表(int num1, int num2)和返回类型int。这个签名用来标识方法add,表示它接受两个整数类型的参数并返回一个整数类型的值。
在Java中,方法的签名是方法的重要特征,同一个类中不能有两个方法具有相同的签名,即使它们的返回类型不同。方法的重载允许在同一个类中定义多个方法,它们的方法名相同,但参数列表不同,从而根据参数的数量或类型来区分它们。方法的签名在Java编程中具有重要的意义,它影响了方法的调用和使用。
第一天 剑指 Offer 09. 用两个栈实现队列(简单)
剑指 Offer 30. 包含min函数的栈(简单)
第二天 剑指 Offer 06. 从尾到头打印链表(简单)
剑指 Offer 24. 反转链表 *(简单)
剑指 Offer 35. 复杂链表的复制(中等)*
第三天 剑指 Offer 05. 替换空格(简单)
剑指 Offer 58 - II. 左旋转字符串(简单)
第四天 剑指 Offer 03. 数组中重复的数字(简单)
剑指 Offer 53 - I. 在排序数组中查找数字 I * (简单)
剑指 Offer 53 - II. 0~n-1中缺失的数字(简单)
第五天 剑指 Offer 04. 二维数组中的查找(中等)
剑指 Offer 11. 旋转数组的最小数字(简单)
剑指 Offer 50. 第一个只出现一次的字符(简单)
第六天 剑指 Offer 32 - I.
1. 前言 ① IIS如何部署WebGL请参考另一篇文章: https://editor.csdn.net/md/?articleId=131563136
② 学校实验需要对接实验空间iLab平台,需要调用他们的接口,如:http://www.ilab-x.com/open/api/v2/user/validate?
2. 问题 将实验打包部署到IIS上之后就开始报跨域:
3. 原因 电话咨询了实验空间的技术人员,告知浏览器中直接访问他们的接口是会存在跨域,出于安全的考虑。
4. 解决方案 安装ARR3.0和rewrite_url
下载地址:https://www.iis.net/downloads/microsoft/application-request-routing
① 安装ARR 3.0 (Application Request Routing)
② 安装rewrite_url
③ 安装完之后重启IIS服务器
④ 开放代理
点击服务器 -> 双击Application-Request-Routing
点击"Server Proxy Settings"
⑤ 配置转发
双击URL重写
点击"添加规则"
点击 “空白规则” - “确定”
配置重写
使用:通配符
模式:*open/*
重写URL:http://www.ilab-x.com/open/{R:2}
【开发背景】 最近正在做室内转室外的无人车项目,首当其冲的就是解决室外建图问题。之前室内一直用的Cartographer 2D建图,效果蛮好的,但是就是面临大场景的时候,闭环检测太吃平台算力了,所以现在只能换一个激光SLAM算法。网上搜索了一下目前流行的室外激光SLAM,发现LIO-SAM使用的人比较多,相关踩坑记录也比较丰富,索性就拿它试水了。
【硬件信息】 Robosense速腾16线激光雷达
Rion瑞芬TL720D陀螺转角仪
Intel NUC工控机
【安装流程】 1、创建一个干净的工作空间目录:
mkdir -p ~/liosam_ws/src cd ~/liosam_ws/src 2、下载lio-sam源码及其依赖
sudo apt-get install -y ros-melodic-robot-localization sudo apt-get install -y ros-melodic-robot-state-publisher sudo add-apt-repository ppa:borglab/gtsam-release-4.0 sudo apt install libgtsam-dev libgtsam-unstable-dev git clone https://ghproxy.com/https://github.com/TixiaoShan/LIO-SAM.git 3、下载robosense激光雷达ros驱动包
git clone https://ghproxy.com/https://github.com/RoboSense-LiDAR/rslidar_sdk.git cd rslidar_sdk git submodule init git submodule update 4、下载robosense雷达点云转velodyne雷达的功能包
git clone https://github.com/HViktorTsoi/rs_to_velodyne.git 5、自己写一个瑞芬imu的ros驱动包
6、下载imu内参标定工具及其依赖
sudo apt-get install libdw-dev git clone https://gitcode.net/mirrors/gaowenliang/code_utils.git git clone https://gitcode.net/mirrors/gaowenliang/imu_utils.git 7、回到工程目录编译
cd ~/liosam_ws catkin_make 【编译问题】 不出所料,你的catkin_make一定会失败,接下来我们一一进行修改:
有时候我就在想,之前的实时小窗口都是通过摄像机来实现的,而unity自带截图功能,为什么我不能每帧生成一个截图然后调用他,把他赋值给image,然后就可以在场景上实现实时窗口的功能,同时我也可以加一条if判断来停止他,从而获得某一时刻的截图。
说干就干,代码内容很简单:
using System.Collections; using UnityEngine; using UnityEngine.UI; public class ScreenShot : MonoBehaviour { public Image image; public Camera screenshotCamera; // 用于截图的摄像机 private void Update() { // if (Input.GetMouseButtonDown(0)) // { StartCoroutine(ScreenShot_ScreenCapture()); // } } private IEnumerator ScreenShot_ScreenCapture() { // 禁用Image组件 image.enabled = false; // 创建RenderTexture来渲染截图 RenderTexture renderTexture = new RenderTexture(Screen.width, Screen.height, 24); screenshotCamera.targetTexture = renderTexture; screenshotCamera.Render(); // 保存RenderTexture为截图 RenderTexture.active = renderTexture; Texture2D texture = new Texture2D(Screen.width, Screen.height, TextureFormat.RGB24, false); texture.
需求 模拟批量上传处理功能, 接口同步处理, 并返回结果.
如有2w数据上传, 接口接收后并行处理, 最后将部分错误数据返回到页面.
代码 import java.util.ArrayList; import java.util.List; import java.util.Random; import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.ForkJoinPool; import java.util.concurrent.RecursiveAction; public class Test { // result保存所有的异常处理结果 public static CopyOnWriteArrayList<Integer> result = new CopyOnWriteArrayList<>(); public static void main(String[] args) { // 构建2w条记录 List<Integer> list = new ArrayList<>(); for (int i = 0; i < 20000; i++) { list.add(i); } // 使用ForkJoinPool执行 ForkJoinPool pool = new ForkJoinPool(); pool.invoke(new MyTask(list)); // 打印执行结果 System.
文章目录 AIGC 下的前端工程师该何去何从1. 疯狂的 AIGC2. 范式迁移 —— AIGC 下开发模式改变的本质2.1 命令式 -> 声明式2.2 声明式 -> AIGC 式 3. 下一代前端工程师3.1 要善于利用3.3 要懂得批判3.4 要合理使用 4. 未来可期5. 望天下再无码农6. 探讨6.1 AIGC 下,前端会消失吗?6.2 前端开发工程师会过分依赖 AI 吗? 参考链接 AIGC 下的前端工程师该何去何从 摘要:AIGC 这一时代潮流已然不可阻挡,我们要做的不是慌乱,而是握住它。本文就和大家一起来探索一下在 AIGC 下,前端工程师即将面临的挑战和机遇,聊聊我们应该何去何从。
文章转载至:AIGC浪潮下,新一代前端人的真实工作感受
1. 疯狂的 AIGC 引出 AIGC
记得 ChatGPT4 刚出来的时候,OpenAI 总裁 Greg Brockman 用笔和纸画了一个网页草图,GPT4 仅用几秒的时间便完成了网页的设计和代码的编写。
好吧,视频 CSDN 就是不给审核通过,所以这里放不了了。
视频摘自 YouTube,完整视频传送门
不知道当时前端同学们看到是个怎样的想法哈,反正我当时心都凉了,好不容易把 vue 的源码搞懂了,这就没啥用了,饭碗砸了,蓝瘦香菇。
好吧,开个玩笑 。AI 已然如此,此时就不得不问那个老生常谈的问题了,前端工程师们该何去何从呢?
想来定有一些同学持悲观态度:前端已死,不值得做下去了,AI 马上就替代了。也会有些同学与之相反吧:AI 降临,神级辅助,又不吃经济,又有大用。 我想说的是,AIGC 一定会对前端开发的未来会产生重大影响,至于这个影响对于前端工程师来说,是正是反,从来都不是工具决定的,而是用工具的人来决定的。我们要做的,不是去担忧焦虑,而是把握住它。
2. 范式迁移 —— AIGC 下开发模式改变的本质 前端开发的范式迁移过程,引出 AIGC 下前端该如何开发
首先indexDB是一个运行在浏览器的非关系型数据库,作为一个数据库,它存储的数据量就是没有上线的,同时它不仅可以存储字符串,还可以存储二进制数据。
主要特点:
1 键值对存储:indexDB内部采用对象仓库存放数据。所有类型的数据都可以直接存入,包括Javascript对象。在仓库中,数据以键值对的形式进行保存,每一个数据记录都有对应的主键,且主键是独一无二的,不能有重复。
2 异步: indexDB操作时是异步操作,不会锁死浏览器,用户在操作indexDB数据库时,可同时进行其他操作(页面渲染等),相比于localStorage的同步操作相比,有利于在大量数据进行读写操作时,避免影响网页的性能。
3 支持事务:IndexDB支持事务,支持在数据库操作失败后,整个事务取消,数据库会回滚到之前的状态,有利于保证数据的安全与完整性。
4 同源限制:IndexDB收到同源限制,每一个数据库对应创建它的域名。网页只能访问自身域名下的数据库,而不能跨域访问。
5.支持二进制储存:IndexDB不仅可以存储字符串,还可以储存二进制树(ArrayBuffer对象和Blob对象)。
6.储存空间大:indexDB由于是数据库,所以存储量比一般方式要大很多,一般来说不少于250MB。
indexDB数据库中的基本概念:
1.数据库(IDBDatabase对象):数据库是一系列相关数据的容器。每个域名(严格的说,是协议+域名+端口)都可以新建任意多个数据库,但他的版本的概念,同一时刻,只能有一个版本的数据库存在。如果要修改数据库结构(新增或删除表、索引或主键),只能通过升级数据库版本完成。
2.对象仓库(IDBObjectStore对象)每个数据库包含若干个对象仓库。它类似于关系型数据库的表格。
3.索引(IDBIndex):为了加速数据的检索可以在对象仓库里面,为不同的属性建立索引。
4.事务(IDTransaction对象):数据记录的读写和删除,都要通过事务完成。对象提供error、abort和complete三个监听事件监听操作结果。
5.操作请求(IDBRequest对象)。
6.指针(IDBCursor对象)。
7.主键集合(IDBKeyRange对象)。
代码示列: 1. 定义数据库初始变量 var db = null; var db_table = null; var databaseName = 'indexDB'; var version = 1; var tableData = [{ //待存入数据 id:1, name:'张一', age: 1, address:'西安' }] 2. 打开数据库 window.indexDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB; //获取浏览器支持的indexDB数据库 var request = window.indexedDB.open(databaseName, version); /* *数据仓库打开失败 */ request.
一、XML基础知识 1、XML简介: XML用于标记电子文件使其具有结构性的标记语言,可以用来标记数据、定义数据类型,是一种允许用户对自己的标记语言进行定义的源语言。XML文档结构包括XML声明、DTD文档类型定义(可选)、文档元素
XML 和 HTML 为不同的目的而设计:
XML 被设计用来传输和存储数据,其焦点是数据的内容。HTML 被设计用来显示数据,其焦点是数据的外观。 HTML 旨在显示信息,而 XML 旨在传输信息。
2、XML 语法 1)XML 声明文件的可选部分,如果存在需要放在文档的第一行
<?xml version="1.0" encoding="utf-8"?> 2)XML 必须包含根元素,它是所有其他元素的父元素,下面note 是根元素
<?xml version="1.0" encoding="UTF-8"?> <note> <to>Tove</to> <from>Jani</from> <heading>Reminder</heading> <body>Don't forget me this weekend!</body> </note> 3)所有的 XML 元素都必须有一个关闭标签,并且标签对大小写敏感
<Message>这是错误的</message> <message>这是错误的 <message>这是正确的</message> 4)XML 属性值必须加引号
与 HTML 类似,XML 元素也可拥有属性(名称/值的对)。
在 XML 中,XML 的属性值必须加引号。
<note date="12/11/2007"> <to>Tove</to> <from>Jani</from> </note> 5)实体引用
在 XML 中,一些字符拥有特殊的意义。
如果您把字符 “<” 放在 XML 元素中,会发生错误,这是因为解析器会把它当作新元素的开始。
这样会产生 XML 错误:
Product Quantization for Similarity Search Paper Link: Product Quantization for Nearest Neighbor Search
Blog Link: Product Quantization for Similarity Search
1 引言 PQ乘积量化是一种用于向量压缩的技术,其目标是将高维向量压缩为低维以支持近似近邻搜索(ANNS)。
该方法的主要思想如下:首先,将向量空间映射到低维向量子空间的笛卡尔积上,然后对每个子空间分别进行量化。其次,将一个向量表示为多个子空间量化结果的短编码组合。通过这种编码,可以估算两个向量之间的欧几里得距离(Euclidean Distance)。需要强调的是,PQ并非用于降维。
PQ方法将向量的数值转换成短编码,可以将其视为符号化的表现形式。
2 PQ流程 2.1 分割 假设我们以及从数据库中获取了一堆128维的向量,因此一个向量的总大小为128*32 bits = 4096 bits (512 bytes)。
我们将向量切成多段,下面展示一种分成8段,每段由16 bits的分割方式。
如图所示,向量被分割到8个子空间当中。
2.2 训练 我们通过在每个子空间执行K-means来训练向量。K-means会生成K个中心点(Centroid)。这些中心点和segment的长度是一样的,其实就是子空间中的一些点。
这些中心点被认为是重建值(reproduction values)。中心点的集合被叫做编码字典(codebook)。如果我们设置k=256,那么我们就会有256*8=2048 个centroids。
这些中心点被称为reproduction values是因为他们通过中心点的合并来近似的重建原vector。将8个子空间所属的centroid(16bits)拼接起来就是原向量的近似值。这是一种有压缩损失的方式。
2.3 编码 当训练完成后,每个向量的每个字段都可以找到在子空间离他最近的centroid。其实就是从一个子空间的256个centroids里面找到最近的一个。
找到后我们使用id来替换这个centroid的真实值(0-255)。
通过这种操作我们获取了vector的压缩向量。这就被称为PQ codes。
当我们选择K=256的时候,每个子段会被压缩成8 bits。
因此每个vector被压缩成8*8 bits = 8 bytes。这节省了大量的空间。
对于M个子段,一个PQ编码所需空间大小为M*(log base 2 of k)bits.
3 PQ搜索 在ANNS中,我们使用asymmetric distance computation (ADC)来估计vector-to-centroid的距离。
//输入四个数a,b,c,d,函数方式找出最大值。
#include <stdio.h> int getMaxFromTwo(int x,int y) { int f; f = x>y?x:y; return f; } int getMaxFromFour(int a1,int b1,int c1,int d1) { int max1; max1 = getMaxFromTwo(a1,b1); max1 = getMaxFromTwo(max1,c1); max1 = getMaxFromTwo(max1,d1); return max1; } int main() { int a,b,c,d; int max; printf("请输入四个整数:"); scanf("%d%d%d%d",&a,&b,&c,&d); max = getMaxFromFour(a,b,c,d); printf("最大数为:%d",max); return 0; }
文章目录 0.引言1.工具准备2.创建插件项目(VSIX)3.自定义VSIX属性4.创建一个command命令5.设置command名称6.编写command功能7.调试插件8.安装插件 0.引言 使用Visual Studio插件可以极大地提升开发效率、提供更好的集成环境、丰富扩展生态系统、方便调试和故障排除,并提供可视化设计和建模等功能。这些好处有助于开发人员更快速、高效地完成项目,并提供更好的用户体验。本文记录VisualStudio开发插件的过程。
1.工具准备 安装VS2022,在百度等浏览器搜索“Visual Studio2022”安装包,然后安装即可。
安装VS需要两个SDK工作负荷:.NET桌面开发和Visual Studio 扩展开发。
2.创建插件项目(VSIX) 3.自定义VSIX属性 4.创建一个command命令 5.设置command名称 <ButtonText>Invoke Command2</ButtonText> 6.编写command功能 System.Windows.Forms.MessageBox.Show("Hello, VSIX!"); 7.调试插件 (1)启动调试
(2)查看功能
8.安装插件 (1)查看插件生成位置
(2)安装VSIXProject2.vsix
(3)关闭VS2022后重启,查看功能
参考资料:
[1] 码建工. Visual Studio扩展开发(VS插件); 2021-08-22 [accessed 2023-07-21].
[2] MT_GH. VS插件开发(一); 2022-06-23 [accessed 2023-07-21].
[3] clever101. 自己动手编写一个VS插件(一); 2013-03-28 [accessed 2023-07-21].
[4] AI2中文网. VS Addin插件基本开发入门; 2015-07-31 [accessed 2023-07-21].
[5] 雪山飞狐的感觉. 自己动手编写一个VS插件 一; 2018-11-08 [accessed 2023-07-21].
[6] 「已注销」. Visual Studio 插件开发(一)—— 如何开始VSX开发; 2014-03-08 [accessed 2023-07-21].
1.
2.
3.
介绍(来自春秋云境)Victor CMS v1.0 /includes/login.php 存在sql注入
2.把拦截的包复制下来,放到txt里
3.直接sqlmap去跑 flag{315e2656-c4b6-44fe-ba9f-26c50df12f60}
文章目录 一、创建新dev工作分支二、push到自己的远程dev工作分支三、工作分支合并到master主分支1、先切换到master主分支2、将远程工作dev分支的内容merge到当前master分支中3、将merge提交到远程master分支 一、创建新dev工作分支 创建完新dev分支以后将默认切换到新dev分支上
二、push到自己的远程dev工作分支 流程和master上push内容一样,也是先add暂存,然后commit,push
三、工作分支合并到master主分支 确保在自己分支上是对的,然后再合并到主分支中
1、先切换到master主分支 2、将远程工作dev分支的内容merge到当前master分支中 3、将merge提交到远程master分支 以上merge只是在本地完成了merge,最后将merge提交到远程master分支即可!
右键项目,直接push即可!
1. 反射机制是什么 反射是java语言的一个特性,它允程序在运行时(注意不是编译的时候)来进行自我检查并且对内部的成员进行操作。
反射是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法,对于任意一个对象,都能够调用它的任意方法和属性,这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制。
一句话总结:反射就是在运行时才知道要操作的类是什么,并且可以在运行时获取类的完整构造,并调用对应的方法。
2. 反射的应用场合 在编译时根本无法知道该对象或类可能属于哪些类,程序只依靠运行时信息来发现该对象和类的真实信息
比如:log4j,Servlet、SSM框架技术都用到了反射机制
比如:log4j log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.logfile.layout=org.apache.log4j.PatternLayout 比如:Servlet <servlet> <servlet-name>HelloServlet</servlet-name> <servlet-class>servlet.HelloServlet</servlet-class> </servlet> 比如 SSM <bean id="tm" class="org..jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"/> </bean> 3. 获取 Class 对象的四种方式 知道具体类的情况下可以使用: Class alunbarClass = TargetObject.class; 但是我们一般是不知道具体类的,基本都是通过遍历包下面的类来获取 Class 对象,通过此方式获取 Class 对象不会进行初始化
通过 Class.forName()传入类的全路径获取 Class alunbarClass1 = Class.forName("cn.javaguide.TargetObject"); 通过对象实例instance.getClass()获取 TargetObject o = new TargetObject(); Class alunbarClass2 = o.getClass(); 通过类加载器xxxClassLoader.loadClass()传入类路径获取 ClassLoader.getSystemClassLoader().loadClass("cn.javaguide.TargetObject"); 通过类加载器获取 Class 对象不会进行初始化,意味着不进行包括初始化等一系列步骤,静态代码块和静态对象不会得到执行
4. 反射实战 创建一个我们要使用反射操作的类 TargetObject。 package cn.javaguide; public class TargetObject { private String value; public TargetObject() { value = "
目录
前言
一、准备工作
二、基本功能实现
1.主菜单
2.核心玩法
3.其他
资源文件
前言 这是学习Qt时期做的一个小项目,现在看感觉有很多可优化的地方,放在这里给新人朋友们提供一个参考。
一、准备工作 无论什么项目,在正式写代码前应该梳理一下项目有哪些需要实现的基本功能,后期可扩展的功能,界面的基本布局,代码细分为哪些模块等等。总而言之,我们写程序必须具备迭代思维,为后期更新维护留空间。
我做的这个小游戏就类似于Flappy Bird,主要就是通过点击实现躲避障碍物。单一实现这一功能并不难,但游戏都讲究一个包装,所以我想还需要在界面上下点功夫。如下图所示,我把界面划分成了主菜单、游戏说明、游玩页面、结算页面四个部分:
二、基本功能实现 1.主菜单 ①鼠标停留图标放大:
当鼠标悬浮在图标上方,图标变大,鼠标离开则图标复原。这一功能有更简单的实现方式(用QSS样式表设置伪状态),但当时我是重写鼠标事件判断鼠标坐标与图标是否重合来实现的(现在看来太过冗余=.=)。 void Widget::mouseMoveEvent(QMouseEvent *event) { int x=this->mapFromGlobal(QCursor().pos()).x();//获取鼠标全局坐标点 int y=this->mapFromGlobal(QCursor().pos()).y(); //qDebug() << "x:" << event->x() << "y:" << event->y(); scale1 = 0; scale2 = 0; scale3 = 0; //判断鼠标位置是否在图标内 if(x > play_x && x <(play_x+pb_width) && y > play_y && y < (play_y+pb_height)) { if(in_box)//标志位,true表示在图标内,默认状态为false { du->play();//播放音效 in_box = false; } //qDebug() << "
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
文章目录 技术简介整体技术路线常用传感器数据规格定义与HD Map的对比地库场景动态物体标注静态要素标注通用障碍物自动标注纯视觉标注方案路面静态要素动态要素标注通用障碍物标注高效的人工标注能力数据链路-HD Flow大模型用于辅助标注总结 技术简介 4D标注主要在3D空间+时序(动态物体)维度上进行标注;
以BEV为代表的感知任务输出空间从2D透视图像空间转换到3D空间,相应地从空间也转换到3D空间。
相关感知任务分为静态感知(路面要素、灯牌锥),动态感知(Detection、Tracking、Prediction、属性),通用障碍物感知(Occupancy/Occupancy Flow)
整体技术路线 通过4D重建实现点云级别或者object级别的重建,通过人工标注积累原始数据。
随着数据积累到一定程度,可以训练云端大模型逐步替换人工标注,可提升80%+的标注效率。
基本流程为:采集数据(包括极光雷达、相机、IMU、GPS)等→输入给动/静态场景进行4D重建→进行人工标注与之间→进行云端模型训练→进行模型预刷(3D or BEV)→进行多传感器交叉验证。
常用传感器 传感器布局:周视7v摄像头+环视4v摄像头;采集车安装Pandar128外参标定:Lidar-camera标定重投影误差<3px;在线标定角度误差<0.1deg,标定方式包括工厂标定和在线标定。时间同步:时间同步偏差<5ms,11v图像同步曝光。
-11v图像同步曝光 数据规格定义 Clip是一段固定时间长度(15s)或者空间距离长度(300m)的视频片段,包括多有传感器的数据Site是空间中的物理坐标点,由位于同一位置的多个clips构成 路面静态要素标注-局部建图:利用Lidar数据结合IMU/GNSS实现cm级别精度的路面重建;采用单趟重建和多趟聚合的方式,既能保证局部建图的完整性,满足远距离真值感知的需求,又能够平摊标注成本。
单趟局部建图:Lidar 定位建图依然面临着挑战,例如车辆高速行驶导致初始化困难;采用多传感器融合结合Lidar-seg语义信息提升单次建图的精度和鲁棒性,初始化成功率>98%,单趟重建的精度达到cm级(与高精度RTK进行评测)多趟聚合:多趟聚合的核心点在于位置重试别即回环检测,由于驾驶场景环境单一,容易引起回环检测失败率搞等问题;采用Lidar-seg结合Learing based features,多躺聚合的成功率可提升到90%以上。 大模型预刷:输入语义、Intensity、纹理图、通过云端模型实现高度自动化标注,可节省80%以上的人工标注成本;模型支持离散要素、几何、属性、连接关系的标注;通过多个clip的聚合,不但可以保证局部建图的完整性,以满足远距离感知的需求,同时可以通过共享标注的方式减少标注成本,平均重投影误差<3px。
与HD Map的对比 图商的HDmap:
高精度传感器,成本高,可扩展性差;受地图鲜度影响,地图更新慢;定位精度差,横向误差10cm,纵向误差40+cm;完整度高、信息丰富 4D Label:
一般精度传感器,适用于采集车;即建即用,不存在地图鲜度的问题;定位精度高,横纵向<10cm;局部的建图,可快速覆盖 地库场景 地库泊车场景采用全局建图的方式,建图精度可以达到cm级别(人工构造回环评测)
动态物体标注 针对bev3E 感知以及端到端模型的真值需求,提供3D det,Tracking,速度,加速度状态针织采用Lidar+camera后融合的方式进行大模型预刷,结合图像感知结果cross check实现全自动标注。 静态要素标注 采用Lidar+camera后融合的方式实现锥桶的3D真值全自动标注锥桶针织标注precision > 95%,recall > 95%,dxyp < 5% 通用障碍物自动标注 Occupancy反映了场景中动静态物体的占据情况,用于识别场景中的通用障碍物Occupancy真值的标注过程应该减少对语义的依赖,更多地使用几何信息Occupancy真值对小物体(50cm * 50cm)的recall > 92%,能有效地识别场景中的宠物、不规则障碍物,推车人等。 纯视觉标注方案 纯视觉方案的核心在于高精度的pose重建,我们采用改造的SFM方案实现了cm精度的重建相比较于多模态方案,纯视觉方案避免了不同传感器之间的外参标定和时间同步问题,生产的真值一致性更高 路面静态要素 对传统的增量incremental SFM进行优化,采用GNN+Wheel+IMU优化后的姿态作为初始值,直接进行Multiple-camera及时序上的三角化,可以提升10+倍的计算效率,RTE < 0.5%采用Learning based features(Superpoint/Superglue)提升再弱纹理区域的重建鲁棒性采用语义引导的MVS提升的点云的重建精度。在SFM提供的准确的视觉pose以及稀疏3D点的基础之上,采用Nerf对路面进行重建,从而对路面的要素进行标注。采用Nerf对路面进行重建,同时获取路面高度和纹理信息,利用语义信息进行监督,可以有效地址弱纹理的影响将路面高度和语义用MLP进行表达其他静态要素:以SFM提供的准确的视觉pose和系数3D点为基础,获取3D空间中交通牌的proposal,之后和2D图像预刷结果进行联合优化,角点重投影误差< 2px。与多模方案对比,一致性更好,与相机运动完全自洽。云上大模型可以采用更大容量的模型以及性能更高的时空融合策略当云端大模型性能指标高于端上10个点以上,便具备作为真值预刷的可行性。 动态要素标注 大模型有效感知范围150m,测距误差 < 5%,AP > 90%纯视觉动态链路真值与Lidar gt对端上模型的提升作用基本一致(AP相差在1个点内) 通用障碍物标注 采用多传感器之间的空间约束和时序约束进行自监督学习。采用DRO的优化模块提升网络的泛化性能。对于depth的估计,采用仿真数据,可以有效地提升动态物体边缘的感知效果。Occupancy/Occupancy flow的真值可以用于处理场景中的通用障碍物,Occupancy/Occupancy flow可以看作是depth的端到端融合100m以内对有较好的测距精度 abs.
程序员必须掌握的重要算法及其应用领域 一、引言: 算法在计算机科学中具有重要的地位,程序员在职业生涯中必然会遇到各种算法。然而,有一些算法是作为一个程序员一定会遇见且大概率需要掌握的。本文将从个人经验出发,介绍程序员必须掌握的重要算法,并给出一些实际应用领域的示例。
二:常见算法介绍 2.1、排序算法 排序算法是将一组数据按照一定的顺序进行排列的算法。常见的排序算法有冒泡排序、插入排序、选择排序、快速排序、归并排序等。排序算法在很多场景中都有应用,比如对大量数据进行排序、排行榜的生成、搜索结果按相关性排序等。
示例代码(以快速排序为例):
def quick_sort(arr): if len(arr) <= 1: return arr pivot = arr[0] left = [x for x in arr[1:] if x <= pivot] right = [x for x in arr[1:] if x > pivot] return quick_sort(left) + [pivot] + quick_sort(right) 2.2、查找算法 查找算法是在一个数据集合中寻找特定元素的算法。常见的查找算法有顺序查找、二分查找、哈希查找等。查找算法的应用广泛,比如在数据库中查询特定记录、搜索引擎中查找相关文档、字典中查找单词等。
示例代码(以二分查找为例):
def binary_search(arr, target): low = 0 high = len(arr) - 1 while low <= high: mid = (low + high) // 2 if arr[mid] == target: return mid elif arr[mid] < target: low = mid + 1 else: high = mid - 1 return -1 2.
假设你要调试 10.0.0.186 上的java,jprofiler直接连接186的ssh报错:
The error message was: Unexpected: SSH MSG UNIMPLEMENTED
找另外一个机器10.0.0.196
在196(186上可能也行)执行:
ssh -f -N -L 0.0.0.0:2222:10.0.0.186:22 root@10.0.0.186
然后jprofiler去连接10.0.0.196就可以了。
原理估计是ssh隧道转发出来的ssh是没有这个会报错的消息,这个转发它帮你处理了这个消息
目录
一、前言
二、View类
三、部分API的使用记录
1、与父布局共享状态
2、设置View不会显示到状态栏与导航栏这些系统窗口上
3、触摸模式下可以设置焦点
4、设置默认焦点
6、焦点跳转
7、显示层高度
8、偏移量高度
9、透明度
10、缩放倍数
11、偏移量移动位置
12、旋转角度
13、View的按下声效
四、View类的XML属性
五、View类可以设置的Listener
一、前言 本文主要记录一些Android开发中,基础View的API使用及描述。
二、View类 View类代表用户界面组件的基本构建块。一个View占据屏幕上的一块方形区域,负责该区域的绘图或事件处理。View类是用来创建交互式UI界面的所有部件的基类。
一个窗口的所有View以树形的方式组织。可以通过代码创建和组装View的方式或者通过编写一个或多个XML布局文件的方式搭建View树。View的具体子类可以作为控件或者显示文本、图像或者其他内容。
一旦创建好了View树,可以根据需要执行一下几类共同的操作:
设置属性。例如为一个TextView设置文本属性。除了View定义的属性和方法外,View不同子类具有一些特有的属性和方法。注意:在构建View树时已知的属性可以在XML布局文件中设置。设置焦点。Android系统会根据用户输入移动焦点。利用requestFocus方法,强制将焦点置于某个特定的视图。设置Listener。允许为View设置一些listener,这样可以在某些感兴趣的事件发生时获得通知。例如所有的View都可以使用setOnFocusChangeListener(android.view.View.OnFocusChangeListener)设置一个用以跟踪该View获得焦点或失去焦点的listener。其他View子类提供了特有的listener。例如一个Button可以设置一个监测是否被点击的listener.设置可视化。可以通过setVisibility(int)方法设置显示或隐藏View. 三、部分API的使用记录 1、与父布局共享状态 这是一个容易被忽视但是十分重要的属性。 很多人从未了解过有这种属性,从而会走上自定义触控的方式,来实现一个布局下的所有子View的点击效果与触控效果。 实际上并不需要,只需要添加这个属性,在父布局被点击或者焦点选中后,让下面的子View都共享状态。
android:duplicateParentState="true" 2、设置View不会显示到状态栏与导航栏这些系统窗口上 <!-- 用于根据状态栏等系统窗口调整视图布局。如果为 true,则调整此视图的填充以为系统窗口留出空间。仅当此视图在非嵌入式活动中时才会生效 --> <attr name="fitsSystemWindows" format="boolean" /> 3、触摸模式下可以设置焦点 这里的焦点指的是遥控器或者键盘操作的时候的View选中焦点。
控制视图是否可以在触摸模式下获得焦点的布尔值。如果对于一个视图是这样,则该视图可以在单击时获得焦点,并且如果单击另一个未将此属性设置为 true 的视图,则可以保持焦点。
android:focusableInTouchMode="true" 4、设置默认焦点 <!-- 此视图是否为默认焦点视图。每个键盘导航集群只有一个视图可以将此属性设置为 true。 --> <attr name="focusedByDefault" format="boolean" /> 5、焦点选中高亮
<!-- 此视图是否应在获得焦点但未在其背景中定义时使用默认焦点突出显示. --> <attr name="defaultFocusHighlightEnabled" format="boolean" /> 6、焦点跳转 如果你在开发TV的应用,需要设置遥控器选中的焦点,一般情况下不需要使用这些焦点跳转位置,因为Android系统会自动检索到下一个需要跳转的焦点。只有一些我们特别要求指定某个跳转焦点位置的情况下,才会使用到它们。
<!-- 当下一个焦点是时,定义下一个要关注的视图。如果引用引用的视图不存在或属于不可见的层次结构的一部分,则访问引用时将产生 {@link java.lang.RuntimeException}。--> <attr name="
综合应用 —— 名片管理系统 黑马程序员python基础项目笔记
目标 变量流程控制函数模块 系统需求 程序启动,显示名片管理系统欢迎界面,并显示功能菜单 用户用数字选择不同的功能 根据功能选择,执行不同的功能 用户名片需要记录用户的 姓名、电话、QQ、邮件 如果查询到指定的名片,用户可以选择 修改 或者 删除 名片 步骤 框架搭建新增名片显示所有名片查询名片查询成功后修改、删除名片让 Python 程序能够直接运行 01. 框架搭建 目标
搭建名片管理系统 框架结构 准备文件,确定文件名,保证能够 在需要的位置 编写代码编写 主运行循环,实现基本的 用户输入和判断 1.1 文件准备 新建 cards_main.py 保存 主程序功能代码 程序的入口每一次启动名片管理系统都通过 main 这个文件启动 新建 cards_tools.py 保存 所有名片功能函数 将对名片的 新增、查询、修改、删除 等功能封装在不同的函数中 1.2 编写主运行循环 在 cards_main 中添加一个 无限循环 while True: # TODO(小明) 显示系统菜单 action = input("请选择操作功能:") print("您选择的操作是:%s" % action) # 根据用户输入决定后续的操作 if action in ["
问题描述: 服务器在线上环境正常运行了半个多月,每天的跑批都会发送一条开始跑批的短信记录,突然某一天没有发送短信。排查该问题,发现发送短信是通过线程池异步发送的,查找短信的发送日志记录,发现没有任何的日志,看日志也没有任何的报错信息。按道理来说如果说线程池的任务满了应该丢弃任务跑出异常的,因为线程池采取的策略就是AbortPolicy策略。
原因分析: 现在系统还可以正常运行,不可能是因为内存溢出的问题,那么很可能就是线程池的问题,于是查看代码发现
public static ExecutorService newFixedThreadPool(int nThreads) { String poolName = "default"; //队列是无限队列 //JDK的newFixedThreadPool 默认的拒绝策略为:AbortPolicy return new ThreadPoolMonitor(nThreads, nThreads, 0L,TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>(), new GcollThreadFactory(poolName), new ThreadPoolExecutor.AbortPolicy(),poolName); } 这里是通过工具类生成的一个线程池,核心线程数与最大线程数设置的都是32,线程存活的时间是0秒,采取的是Linked阻塞队列,封装了一个线程池工厂用来给生成的线程起别名,采取的拒绝策略是AbortPolicy策略,丢弃任务并抛出异常。
我们看一下ThreaPoolExecutor的源码解释:
* <li> If corePoolSize or more threads are running, the Executor * always prefers queuing a request rather than adding a new * thread.</li> 翻译如下:如果超过线程池的核心线程池的数量在运行,再来的请求会进入到队列而不是添加一个新的请求。
new LinkedBlockingQueue<Runnable>(),这个方法的默认容量是Integer的最大值。
public LinkedBlockingQueue() { this(Integer.MAX_VALUE); } /** * Creates a {@code LinkedBlockingQueue} with the given (fixed) capacity.
LaTex是什么? LaTex是一款开源免费,并且应用相当广泛的排版工具,它‘对能对文字,公式,图片进行精确而复杂的排版,并且能保证全文各个章节格式的一致性,并且还能保证全文各个章节格式的一致性,像大家平时看到的论文,书籍,基本都是使用LaTex生成的,LaTex同时提供相当数量的宏包,作为对基础排版功能的扩充,像乐谱,原理图,甚至简单的动画也都可以用他完成,Latex也可用用来做简历,Latex并不是复杂难用的,跟我一起快速入门latex快速入门的排版神器
官方定义:LaTeX(LATEX,音译“拉泰赫”)是一种基于ΤΕΧ的排版系统,由美国计算机学家莱斯利·兰伯特(Leslie Lamport)在20世纪80年代初期开发,利用这种格式,即使使用者没有排版和程序设计的知识也可以充分发挥由TeX所提供的强大功能,能在几天、甚至几小时内生成很多具有书籍质量的印刷品。对于生成复杂表格和数学公式,这一点表现得尤为突出。因此它非常适用于生成高印刷质量的科技和数学类文档。这个系统同样适用于生成从简单的信件到完整书籍的所有其他种类的文档。
Latex的主要优势 Latex它会将文档的内容和排版区分开来,这就好像是HTML和CSS的关系
(markdown是一种轻量标记语言,它也是一种将内容和排版分开的标记语言,并且Markdown的语法非常轻量,非常适合于简单文字的创作,像很多wiki(超文本系统:由多人维护,每个人都可以发表自己的意见,或者对共同主题进行扩展与探讨))比如GitHub的文档都是使用Markdown语法生成的)和Markdown类似,Latex的格式和排版也可以随后轻易的切换,通常也就是一两行代码的事例如你可以轻易的将一篇普通文档切换为科学期刊,甚至是幻灯片,当然每个工具都有适用的地方
如果你只是记记笔记,不怎么需要大篇幅排版的情况下,使用word这类所见即所得的工具自然也会方便许多。常用的Tex发行版一般有两个:TexLive和MikTex
安装Latex,需要安装两个东西1,安装Tex发行版,2,安装LaTex编辑器,这两个软件就好比Python和和pycharm
texlive是必须要安装的latex环境,就像学习python需要安装python环境一样。注意mikTex也是texlive的环境,texstudio是编辑器,就像学习python要用pycharm一样,是比较官方的编辑器,但不是必须的,你也可以使用vscode,dublime等其他文本编辑器打开。
TexLive提供的包很全,但是占用空间大
MakTex占用空间小,安装速度快,但如果遇到本地缺少的包则需要联网下载
大家可以根据自己的实际情况考虑,如果你的网络连接不太稳定,则可以选择TexLive一劳永逸,如果大家不希望配置本地环境,只是想快速尝试的话也可以用Overleaf,它可以免费使用Tex编辑 器 网址 : https://www.overleaf.com/
下载: 在线LaTeX编辑器:https://www.overleaf.com
TeX Live下载: https://www.tug.org/texlive/acquire-iso.html
下载速度慢的推荐使用镜像:
适合境外用户,下载速度可以起飞:HK镜像
适合境内用户,起码比境外镜像快:清华镜像列表,以及中科大镜像列表
MikTeX下载:https://miktex.org/download
LaTeX 公式编辑器:https://latex.codecogs.com/eqneditor/editor.php
一份不太简短的LaTeX介绍:https://github.com/CTeX-org/lshort-zh-cn
下载Texlive TeXLive,它其实就是一个大的捆绑包,把基本的操作系统和一些必要的工具捆在一起,让用户可以开箱即食
texlive安装 若下载的exe文件直接双击,若是iso文件,打开其中的install-tl-advanced.bat文件安装。
按提示点击至一下界面,点击advanced
耐心等待安装所有的包,这段时间很长,大概需要一个小时
在电脑中找到并打开TeXworks editor应用程序,复制下面的IEEE trans模板到软件页面上,然后保存tex文件(必须是英文路径)。
1、二维数组转一位数组
const arr = [1,2,3,[5,6],[1,4,8]] const tempArr = arr.join(',').split(',') console.log(tempArr) 扩展:
从数组里找出最大的值:Math.max.apply(null, arr)
从数组里找出最小的值:Math.min.apply(null, arr)
arr为一维数组,且全部为数值或可转为数值,否则得到结果为NaN。
2、多维数组转一维数组
const arr = [1,'2','test',3,[5,6,['abc',11,12]],[1,4,8,[13]]] const tempArr = arr.join(',').split(',') console.log(tempArr) 记录于2023-7-21
文章目录 CompletableFuture 概述优点使用demo CompletableFuture 概述 CompletableFuture提供了一种观察者模式类似的机制,可以让任务执行完成后通知监听的一方。
优点 1.异步任务结束时,会自动调用某个对象的方法
2.主线程设置好回调后,不再关心异步任务的执行,异步任务之间可以顺序执行
3.异步任务出错时,会自动回调某个对象的方法
使用demo public class CompletableFutureBuildDemo { public static void main(String[] args)throws ExecutionException,InterruptedException { ExecutorService executorService = Executors.newFixedThreadPool(3); CompletableFuture<Void> completableFuture =CompletableFuture.runAsync(()->{ System.out.println(Thread.currentThread().getName()); try { TimeUnit.SECONDS.sleep(1); }catch (InterruptedException e){ e.printStackTrace(); } }); System.out.println(completableFuture.get()); executorService.shutdown(); } }
<section>和<div>都是HTML标签,用于在HTML文档中组织和布局内容,但它们在语义和用法上有一些区别。
区别: <div>:<div>是最常见的HTML容器标签,它没有特定的语义,仅用于将内容分组并应用样式。在CSS中,可以为<div>元素定义样式,并用于布局或将一组相关元素包装在一起。<div>可以用于任何目的,但缺乏语义化,不具有明确的含义。
<section>:<section>标签具有更具语义化的含义。它用于将文档内容分成不同的部分或章节,并且通常具有自己的标题。<section>标签有助于更好地表示文档的结构和内容组织,对于搜索引擎和辅助技术(如屏幕阅读器)来说也更有意义。
底层原理: 在底层,<section>和<div>都是HTML文档中的块级元素。块级元素是指在文档中占据整个可用宽度,独占一行的元素。当浏览器解析HTML文档时,它会根据标签类型来决定如何显示和渲染内容。
对于<div>,浏览器会将其视为一个普通的块级容器,没有特定的样式或语义。开发者可以根据需要使用CSS来为<div>添加样式。
而对于<section>,浏览器会理解它作为一个具有语义化含义的块级容器,并且在文档结构中有一定的重要性。这有助于开发者更好地组织内容并让其在语义上更具意义。
举例来说,当你有一个博客页面时,你可以使用<section>来分隔文章的不同部分,如标题、正文、评论等。而<div>可以在文章内用于更细粒度的布局,例如将内容分成多列或添加样式包装。但请注意,过度使用<div>会导致HTML语义混乱,应该尽量使用语义化标签如<section>、<article>、<header>、<footer>等来更好地表示页面内容结构。
文章目录 一、调用同一文件夹下的文件二、调用同级文件夹下的子文件三、调用不同级别文件夹下的文件 一、调用同一文件夹下的文件 在environment.py 中调用 multi_discrete.py 中的class MultiDiscrete
from .multi_discrete import MultiDiscrete 二、调用同级文件夹下的子文件 示例:
在make_env.py文件中希望调用environment.py中的class MultiAgentEnv。从图中可见,make_env.py文件的路径是:‘/master/multiagents/make_env.py’,environment.py的路径是’/master/multiagents/multiagent/environment.py’。
此时需要这么调用:
from multiagent.environment import MultiAgentEnv 三、调用不同级别文件夹下的文件 示例:
在make_env.py文件中希望调用environment.py中的class MultiAgentEnv。
从图中可见,make_env.py文件的路径是:‘/master/utils/make_env.py’,
environment.py的路径是’/master/multiagents/multiagent/environment.py’。
此时需要这么调用:
(这么记:共同的文件路径用 “./” 表示,然后写出其余的文件夹路径)
import sys sys.path.insert(1,'./multiagents') from multiagent.environment import MultiAgentEnv 但是import … as… 要写完整路径(不知道为什么,不写完整路径就报错)。导入文件示例:
import sys sys.path.insert(1,'/home/deeplearning/pythoncode/openAI-maddpg-master/multiagents') import multiagent.environment as multi_env
将nacos脚本放到idea中做为启动项 1.点击Edit Configuration 2.添加Shell Script 3.编辑名字和选择脚本所在位置 startup.sh(MacOS)
startup.cmd(Windows)
4.添加完成后,在启动台就可以找到nacos启动脚本 5.选择后直接运行即可
p=*:表示下载所有的视频
–merge-output-format mp4:表示将声音和视频合并
电脑上需要安装ffmpeg,将其配置到系统变量即可
yt-dlp https://www.bilibili.com/video/BV1S94y127Sv?p=* –merge-output-format mp4
1002 Binary Number
Binary Number Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/65536 K (Java/Others)
Total Submission(s): 276 Accepted Submission(s): 59
Problem Description Markyyz is learning binary numbers. There is an easy problem in his homework.
You are given a binary number s1∼n (s1 is the highest bit. sn is the lowest bit.). You need to do an operation exactly k times: select an interval [l,r] (1≤l≤r≤n) arbitrarily and flip sl,sl+1,.
缓存雪崩 什么是缓存雪崩?
当某一个时刻出现大规模的缓存失效的情况,那么就会导致大量的请求直接打在数据库上面,导致数据库压力巨大,如果在高并发的情况下,可能瞬间就会导致数据库宕机。这时候如果运维马上又重启数据库,马上又会有新的流量把数据库打死。这就是缓存雪崩。
分析:
造成缓存雪崩的关键在于在同一时间大规模的key失效。为什么会出现这个问题呢,有几种可能,第一种可能是Redis宕机,第二种可能是采用了相同的过期时间。搞清楚原因之后,那么有什么解决方案呢?
解决方案:
1、在原有的失效时间上加上一个随机值,比如1-5分钟随机。这样就避免了因为采用相同的过期时间导致的缓存雪崩。
如果真的发生了缓存雪崩,有没有什么兜底的措施?
2、使用熔断机制。当流量到达一定的阈值时,就直接返回“系统拥挤”之类的提示,防止过多的请求打在数据库上。至少能保证一部分用户是可以正常使用,其他用户多刷新几次也能得到结果。
3、提高数据库的容灾能力,可以使用分库分表,读写分离的策略。
4、为了防止Redis宕机导致缓存雪崩的问题,可以搭建Redis集群,提高Redis的容灾性。
缓存击穿 什么是缓存击穿?
其实跟缓存雪崩有点类似,缓存雪崩是大规模的key失效,而缓存击穿是一个热点的Key,有大并发集中对其进行访问,突然间这个Key失效了,导致大并发全部打在数据库上,导致数据库压力剧增。这种现象就叫做缓存击穿。
分析:
关键在于某个热点的key失效了,导致大并发集中打在数据库上。所以要从两个方面解决,第一是否可以考虑热点key不设置过期时间,第二是否可以考虑降低打在数据库上的请求数量。
解决方案:
1、上面说过了,如果业务允许的话,对于热点的key可以设置永不过期的key。
2、使用互斥锁。如果缓存失效的情况,只有拿到锁才可以查询数据库,降低了在同一时刻打在数据库上的请求,防止数据库打死。当然这样会导致系统的性能变差。
缓存穿透 什么是缓存穿透?
我们使用Redis大部分情况都是通过Key查询对应的值,假如发送的请求传进来的key是不存在Redis中的,那么就查不到缓存,查不到缓存就会去数据库查询。假如有大量这样的请求,这些请求像“穿透”了缓存一样直接打在数据库上,这种现象就叫做缓存穿透。
分析:
关键在于在Redis查不到key值,这和缓存击穿有根本的区别,区别在于缓存穿透的情况是传进来的key在Redis中是不存在的。假如有黑客传进大量的不存在的key,那么大量的请求打在数据库上是很致命的问题,所以在日常开发中要对参数做好校验,一些非法的参数,不可能存在的key就直接返回错误提示,要对调用方保持这种“不信任”的心态。
解决方案:
1、把无效的Key存进Redis中。如果Redis查不到数据,数据库也查不到,我们把这个Key值保存进Redis,设置value="null",当下次再通过这个Key查询时就不需要再查询数据库。这种处理方式肯定是有问题的,假如传进来的这个不存在的Key值每次都是随机的,那存进Redis也没有意义。
2、使用布隆过滤器。布隆过滤器的作用是某个 key 不存在,那么就一定不存在,它说某个 key 存在,那么很大可能是存在(存在一定的误判率)。于是我们可以在缓存之前再加一层布隆过滤器,在查询的时候先去布隆过滤器查询 key 是否存在,如果不存在就直接返回。
总结 这三个问题在使用Redis的时候是肯定会遇到的,而且是非常致命性的问题,所以在日常开发中一定要注意,每次使用Redis时,都要对其保持严谨的态度。还有一个需要注意的是要做好熔断,一旦出现缓存雪崩,击穿,穿透这种情况,至少还有熔断机制保护数据库不会被打死。
1002 City Upgrading
类似题及其题解
City Upgrading Time Limit: 12000/6000 MS (Java/Others) Memory Limit: 524288/131072 K (Java/Others)
Total Submission(s): 306 Accepted Submission(s): 78
Problem Description The city where crazyzhk resides is structured as a tree. On a certain day, the city's network needs to be upgraded. To achieve this goal, routers need to be deployed. Each router covers the node it is placed on and its neighboring nodes. There is a cost ai associated with placing a router at each node.
目录 一、bean生命周期基本流程二、流程细节1、初始化方法和销毁方法1)自定义式:2) 接口式3)声明式4)执行顺序 2、InstantiationAwareBeanPostProcessor实例化后置处理器2、BeanPostProcessor初始化后置处理器4、xxxAware接口 三、 总结执行流程 一、bean生命周期基本流程 实例化属性填充初始化销毁 二、流程细节 1、初始化方法和销毁方法 1)自定义式: xml与@Bean方式一样 public class Book { public void init(){ System.out.println("初始化方法"); } public void destroy(){ System.out.println("销毁方法"); } } @Bean(initMethod = "init",destroyMethod = "destroy") public Book book(){ return new Book(); } 2) 接口式 InitializingBean(初始化接口)、DisposableBean(销毁接口)实现其方法即可 public interface InitializingBean { void afterPropertiesSet() throws Exception; } public interface DisposableBean { void destroy() throws Exception; } 3)声明式 添加注解 @PostConstruct(初始化)@PreDestroy(销毁)的方法 public class Book { @PostConstruct public void initMethod(){ System.
package com.zyq.util; import lombok.Data; import java.util.*; import java.util.concurrent.ConcurrentLinkedDeque; /** * 缓存工具类 * <p> * 【说明】 * 写这个工具类的背景是因为页面有的时候需要携带参数从A页面跳转到B页面,如果参数长度过大, * 就会导致url拼接过长,而url的长度是有限的。因此前端可以先请求后端,后端将数据保存在某处, * 然后返回一个uuid给前端,前端携带该uuid跳转到B页面,再通过该uuid拿到数据, * 这样就可以解决页面跳转参数过长丢失数据的问题。 * <p> * 该工具类适用单节点部署的项目,或者多节点部署时路由规则是按用户进行路由的(写这个工具类也是先了解了该项目是单体部署的)。 * 如果是多节点项目部署,且后端路由规则不是根据用户的话,那么该工具类就不适用。 * 比如第一次请求获取的是后端1节点生成的uuid,但是再次访问的时候把uuid携带到了后端2节点,因此是获取不到的。 * (可以将对应的数据缓存到Redis或数据库的方式进行存取) * * @author zyqok * @since 2023/7/20 */ public class UserCacheUtils { /** * 清理过期数据最小周期时间(单位:毫秒),当前为1分钟 */ private static final long MIN_CLEAR_MILLISECONDS = 6000; /** * 缓存最小时间(单位:秒),当前为1秒 */ private static final long MIN_CACHE_SECONDS = 1; /** * 缓存最大时间(单位:秒),当前为1天 */ private static final long MAX_CACHE_SECONDS = 24 * 60 * 60; /** * 上一次清理过期数据的时间 */ private static long lastClearExpireTime = System.
Nginx 配置实现请求转发功能 1、找到配置文件2、文件说明3、在nginx.conf中修改4、需要修改的地方(1)修改Nginx 默认端口号(2)配置nginx转发的规则 5、修改Nginx请求地址,重启nginx重启前端即可6、效果展示: 1、找到配置文件 2、文件说明 #开启进程数 <=CPU数 worker_processes 1; #错误日志保存位置 #error_log logs/error.log; #error_log logs/error.log notice; #error_log logs/error.log info; #进程号保存文件 #pid logs/nginx.pid; #每个进程最大连接数(最大连接=连接数x进程数)每个worker允许同时产生多少个链接,默认1024 events { worker_connections 1024; } 3、在nginx.conf中修改 主要在【http】中修改
http { #文件扩展名与文件类型映射表 include mime.types; #默认文件类型 default_type application/octet-stream; #日志文件输出格式 这个位置相于全局设置 log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; #请求日志保存位置 #access_log logs/access.log main; #打开发送文件 sendfile on; #tcp_nopush on; #keepalive_timeout 0; #连接超时时间 keepalive_timeout 65; #打开gzip压缩 #gzip on; #设定请求缓冲 #client_header_buffer_size 1k; #large_client_header_buffers 4 4k; #设定负载均衡的服务器列表 #upstream myproject { #weigth参数表示权值,权值越高被分配到的几率越大 #max_fails 当有#max_fails个请求失败,就表示后端的服务器不可用,默认为1,将其设置为0可以关闭检查 #fail_timeout 在以后的#fail_timeout时间内nginx不会再把请求发往已检查出标记为不可用的服务器 #} #webapp #upstream myapp { # server 192.
一、定义与组成 定义:iostream为输入输出流,流是指要从某种 IO 设备上读出或写入的字符序列。组成:iostream由istream和ostream(输入流和输出流)组成,标准库定义了四个对象: cin: 标准输入,处理输入时使用
cout: 标准输出,处理输出时使用
cerr: 标准错误,通常用来输出警告和错误信息给程序的使用者
clog: 用于产生程序执行的一般信息
二、使用 头文件使用,不要加上“.h”,没加上的为改进的iostream库 #include< iostream >
使用的时候,该头文件没有定义全局命名空间,必须使用 using namespace std;
这样才能正确使用cout。
操纵符: “<<” : 把流插入到输出设备或输出缓冲区中,用于输出“>>” : 把流从输入缓冲区提取到变量中,用于输入 输入:
cin:“cin”和“>>”组合使用 单单使用cin时,遇到空格与回车键就停止输入
使用**cin.get()**来输入一个字符
使用cin.getline() 来输入,遇到回车键时停止输入,需要注意,括号里面需要约定输入的字符数
输出: cout:与“<<”,“endl”(刷新缓冲区并插入换行符)组合使用,运用栈的原理进行输出,可以有各种格式设置
cerr :cerr 对象是非缓冲的,且每个流插入到 cerr 都会立即输出,用于显示错误消息
clog:有经过缓冲区
文章目录 0.引言1.新建EXCEL2.EXCEL另存为模板3.使用模板 0.引言 使用Excel模板可以帮助用户更高效地处理和分析大量数据,简化重复任务,并提供清晰直观的数据可视化效果。对于需要频繁进行数据处理和分析的个人或组织来说,使用Excel模板是一个非常实用的工具。本文总结Excel模板自定义并使用的过程。
1.新建EXCEL 2.EXCEL另存为模板 3.使用模板 参考资料:
[1] chibenji. 如何在Excel中自定义模板; 2022-07-20 [accessed 2023-07-20].
[2] 菜鸟辣妈. 如何在Excel中自定义模板; 2017-04-09 [accessed 2023-07-20].
[3] NoooooYes. Excel 2016创建自定义模板的方法; 2016-08-18 [accessed 2023-07-20].
[4] 晨曦雨梦1. win8系统如何自定义excel模板并保存; 2015-08-06 [accessed 2023-07-20].
<el-collapse v-model="activeSection" accordion> <el-collapse-item :name="index" v-for="(item, index) in addArray" :key="item.sectionCount" ref="collapse" > <videoContent :item="item"></videoContent> </el-collapse-item> </el-collapse> 情景:
el-collapse绑定了 addArray,在操作时, 展开折叠面板时,addArray更新。但是通过测试发现,el-collapse-item中的item并不会更新数据,只有收起折叠面板时才会更新item数据。
解决方法:
使用 $forceUpdate() 方法来强制刷新组件,这样 el-collapse-item 的数据变动会触发重新渲染,确保视图更新及时。
<template> <el-collapse v-model="activeSection" accordion> <el-collapse-item :name="index" v-for="(item, index) in addArray" :key="item.sectionCount" ref="collapse" > <!-- 省略部分代码 --> </el-collapse-item> </el-collapse> </template> <script> export default { data() { return { activeSection: null, // v-model 绑定数据 addArray: [], // el-collapse-item 数据 forceUpdateKey: 0, // 强制刷新的标识 }; }, methods: { // 假设有一个方法用于更新 addArray 的数据,比如 pushItemToArray pushItemToArray(item) { this.
在做数据回显时,发现部分字段回显失败,检查所有代码发现都没有问题。后来发现是初始化时候赋值可以过早,ant design vue中的form表单setFidesValue不生效解决方法:
1、添加一个异步setTimeout: setTimeout(() => { this.form.setFieldsValue({xxx:'xxx'}) }, 0) 2、加上this.$nextTick(()=>{}): this.$nextTick(() => { this.form.setFieldsValue({xxx:'xxx'}) })
form.getFieldValue()拿到的值为change之前的值,
e.target.value是预期更改的值即change之后的值(它与getFieldValue值不匹配)
我个人使用的是Ubantu16.04版本。
samba服务的安装及配置 一、安装:
sudo apt-get install samba
二、配置:
1、创建一个需要共享的目录,并修改权限:
lpf@ubuntu:~$ mkdir share
lpf@ubuntu:~$ sudo chmod 777 share/ -R
2、打开配置文件:
lpf@ubuntu:~$ sudo vim /etc/samba/smb.conf
3、对创建的共享目录进行配置并保存退出:path和users需要改成自己的
[share]
path = /home/student/share available = yes
browseable = yes
public = yes
writable = yes
valid users = student
三、重新samba服务:
lpf@ubuntu:~/1703$ sudo /etc/init.d/smbd restart
四、测试:
在windows中win+R:
–>开始
—>运行
—>\linux的IP (例如:\192.168.0.189 )
五、设置samba密码: 2》设置samba密码:设置共享文件夹密码,student是用户名
sudo smbpasswd -a student
3》重启samba服务:
sudo /etc/init.d/smbd restart
nfs服务器的安装配置和使用 1、将已经制作好的文件系统rootfs.tar.gz拷贝到 /opt,并解压
问题原因所在: 前端Vue传输的数据字段类型和后端实体类字段不一致。
可通过接口检查传输数据类型: 将不一致数据类型修改后问题解决。
了解的知识 需要什么就添加什么,都在对应的文件里,比如gpio就再gpio.c里面,在.c文件里右键跳到头文件查找自己需要的函数。xx.s是汇编的启动文件,里面有中断的向量表。misc.c里面是中断函数。在system_stm32f4xx.c 和stm32f4xx.h里面修改对应的时钟频率。
LED灯使用 1.首先查看开发板对应的原理图引脚,和芯片连接的网络标号,看它在哪一根时钟总线上。 /**************************************** 函数名:void LED_Init(void) 功能:初始化LED灯 参数:无 返回值:无 说明: 1.通过原理图查询到 LED1 ---- PE8 LED2 ---- PE9 LED3 ---- PE10 *****************************************/ void LED_Init(void) { //1.RCC 使能 AHB1 总线上的 GPIOE 总线时钟 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE); //2.初始化GPIO GPIO_InitTypeDef GPIO_InitStruct; GPIO_InitStruct.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10; //引脚:8|9|10 GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT; //模式:通用输出 GPIO_InitStruct.GPIO_OType = GPIO_OType_PP; //类型:推挽输出 GPIO_InitStruct.GPIO_Speed = GPIO_Fast_Speed; //速度:快速 50MHz GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL; //状态:无上下拉 GPIO_Init(GPIOE, &GPIO_InitStruct); //初始化GPIO //3.控制寄存器输出数据 ---- 让LED不亮 //GPIO_SetBits(GPIOE,GPIO_Pin_8|GPIO_Pin_9|GPIO_Pin_10); //将LED引脚置位高电平 -- 不亮 LED1 = LED2 = LED3 = 1; //将LED引脚置位高电平 -- 不亮 } 2.
最近需要传一些大文件(40G)到远程服务器
目录
前言
一、本地主机是Windows
二、本地主机是Ubuntu
方法1:scp
方法2:rsync
前言 跳连接指的是
跳连接(Jump Host),也称为跳板主机或代理主机,是在进行远程连接时使用的一种技术。当您需要通过一个中间服务器(跳板主机)来访问其他内部服务器时,跳连接就派上了用场。这种配置通常用于增加安全性或通过一个中转点访问处于内部网络的目标服务器。
指的比如是我中间的跳板主机成为地址B,目标主机是A,我需要从B跳到A
提示:以下是本篇文章正文内容,下面案例可供参考
一、本地主机是Windows VScode和MobaXterm都是非常可取的远程连接软件,但是对于传输超过10G的大文件十分不友好(在CV工作中,图片或者是视频的数据集相对来说都比较大),我之前用VScode发现看不了上传文件的进度条(可能也是我没认真尝试),无论是VSCode或者是MobaXterm其实都存在上传速度慢且容易发生中断,好处就是你远程连接后可以采取拖拽的形式上传文件,这点倒是十分方便
好了,切入正题
我选择的是使用Xshell+Xftp进行跳连接
详情可以参考这篇文章如何实现跳板机(服务器跳转访问,xshell和xftp为例)_xftp 跳板机_qq_43797186的博客-CSDN博客
可以达到2M/s的速度,感觉还是比较友善的
二、本地主机是Ubuntu 相对来说ubuntu连接远程的linux不用下载很多工具,命令行搞定
方法1:scp 终端输入:
scp -o ProxyJump=B@xxx.xxx /home/xx/leftImg8bit_trainextra.zip A@xxx.xx:/file/cityscape/ 在这里有几个部分要说明一下"scp -o ProxyJump= “这部分可以不变
B这部分就是跳板主机,中间主机的地址
"/home/xx/leftImg8bit_trainextra.zip” 这部分换成自己要上传的文件的本地绝对路径
A这部分就是你的目标主机地址:要上传的在服务器上的绝对路径
这样就可以成功,但是相对来说,速度太慢,在我电脑上达不到2M/s这样的需求
方法2:rsync 在大多数的linux系统上都安装好了rsync,不确定的可以再确认一下,终端输入:
rsync --version 相对scp后的命令改为:
rsync -avz --progress -e "ssh -J B的地址(跳板)" /home/xxx/leftImg8bit_trainvaltest.zip A的地址(目标):/file/cityscape/(目标地址) 相对来说,速度快了很多
达到了2M/s的速度
问题:安装完成后,打开matlab出现:
解决:
将和 ISO 文件一起的“libmwlmgrimpl.dll”文件复制到“\bin\win64\matlab_startup_plugins\lmgrimpl”文件夹,直接替换掉原来的文件
安装jupyter notebook 输入命令安装jupyter notebook
pip3 install jupyter 安装后先生成配置文件,用于后面写入ip,端口号,密码等
jupyter notebook --generate-config 配置文件 启动【ipython】配置密码(注意不是python)
ipython In [1]: from notebook.auth import passwd #导入包 In [2]: passwd() #调用包 Enter password: #输入密码,用于后面登陆jupyter notebook Verify password: #确认密码 Out[2]: 'sha1:ce23d945972f:34769685a7ccd3d08c84a18c63968a41f1140274' #这段是密钥,复制下来等会用 exit() #退出 开始编辑配置文件
vim jupyter_notebook_config.py #在任意地方加上如下内容(键入i进入插入模式) c.NotebookApp.ip = '*' #允许任何ip去访问我们的jupyter notebook c.NotebookApp.password = u'sha1:ce23d945972f:34769685a7ccd3d08c84a18c63968a41f1140274' #u后面加上你复制的密钥 c.NotebookApp.open_browser = False #因为是在linux,就不让他打开浏览器了 c.NotebookApp.port = 8888 #随便指定一个端口,如果这个端口被占用,jupyter会加1重新找端口,直到找到为止 c.NotebookApp.allow_remote_access = True #允许远程控制 c.NotebookApp.notebook_dir = u'路径' #设置你打开jupyter notebook的时候想显示的位置,可以设置成经常使用的路径 #配置完记得保存(键入esc,然后输入:wq保存并退出) 启动jupyter notebook jupyter notebook 在windows下远程访问jupyter notebook,在本地打开浏览器访问以下地址:
一、找到SimHei字体 可以在windows上搜索,具体路径为C:\Windows\Fonts\simhei.ttf
二、将中文字体文件放入matplotlib安装目录下 /home/hpdbman/anaconda3/envs/jiahui/lib/python3.7/site-packages/matplotlib/mpl-data/fonts/ttf 注意:需要修改simhei.ttf为SimHei.ttf,否则无法生效
三、找到maplotlib的缓存位置并清空 import matplotlib as mpl mpl.get_cachedir() 于是找到maptlotlib的缓存位置是/home/hpdbman/.cache/matplotlib
执行清空命令
!rm -rf /home/hpdbman/.cache/matplotlib 四、 代码开始处设置字体 plt.rcParams['font.family'] = ['sans-serif'] plt.rcParams['font.sans-serif'] = ['SimHei'] plt.rcParams['axes.unicode_minus']=False
文章目录 1. 什么是 Redis?2. Redis 可以用来干什么?3. Redis 有哪些数据结构?4. Redis 为什么快呢?5. 能说一下 I/O 多路复用吗?6. Redis 6.0 之前为什么使用单线程?7. Redis 6.0 之后为何引入了多线程?8. Redis 持久化方式有哪些?有什么区别?8.1 RDB8.1.1 执行时机8.1.2 RDB 缺点 8.2 AOF8.2.2 AOF 配置8.2.3 AOF 文件重写 9. 如何选择 RDB 和 AOF?10. Redis 如何保证高并发和高可用?10.1 主从集群10.1.1 主从数据同步的流程 10.2 哨兵机制10.2.1 哨兵机制的结构和作用10.2.2 集群监控原理10.2.3 集群故障恢复原理 10.3 分片集群 11. 什么是缓存穿透?12. 什么是缓存雪崩?13. 什么是缓存击穿?14. 如何保证缓存和数据库数据的一致性?15. Redis 的 key 过期之后,会立即删除吗?(Redis 数据过期策略)16. Redis 内存不足怎么办?(Redis 内存淘汰策略)17. 什么是大 Key?18. Redis 分布式锁18.1 Redis 分布式锁在项目中如何实现?18.2 如何控制 Redis 实现分布式锁有效时长呢?18.3 Redisson 实现的分布式锁是可重入的吗?18.
文章目录 JVM线程模型乐观锁与悲观锁JUC JVM线程模型 jvm线程与操作系统线程之间存在某种映射关系,这两种不同维度的线程之间的规范和协议就是线程模型
三种线程模型:
1对1:java线程与操作系统线程1对1关系
多对1:多个用户线程映射到一个内核线程上,用户线程调度需要用户空间完成
多对多:多个用户线程映射到多个内核线程上。
乐观锁与悲观锁 并发环境中,出现多个线程对统一资源进行争抢的情况,两个线程同时对资源进行修改,会导致数据不一致的情况,为了解决这个问题,使用锁机制 乐观锁:乐观锁总是假设最好的情况,认为共享资源每次被访问的时候不会出现问题,线程可以不停地执行,无需加锁也无需等待,只是在提交修改的时候去验证对应的资源(也就是数据)是否被其它线程修改了(具体方法可以使用版本号机制或 CAS 算法)
悲观锁:悲观锁有点像是一位比较悲观(也可以说是未雨绸缪)的人,总是会假设最坏的情况,避免出现问题 (认为共享资源每次被访问的时候就会出现问题(比如共享数据被修改),所以每次在获取资源操作的时候都会上锁,这样其他线程想拿到这个资源就会阻塞直到锁被上一个持有者释放。也就是说,共享资源每次只给一个线程使用,其它线程阻塞,用完后再把资源转让给其它线程。)
对象锁:四种状态
无锁、偏向锁、轻量级锁、重量级锁
JUC JUC中大量组件以及一些开源中间件都依赖AQS
Reentrantlock:可重入锁 countDownLatch:线程计数器
threadPoolExcutor:线程池
concurrentHashMap:哈希表
在pycharm下执行pip - V,报错如下:
由于当前python版本为3.9,从python3.4及以上就自带pip包了,所以猜测一定是环境变量配置问题。
解决: 1. open ~/.bash_profile 打开并查看一下环境变量
2. 将第二行的pip环境变量添加并保存。
3.关闭.bash_profile文件,并执行source ~/.bash_profile ,就生效了。
解决后:
发布视频挂载请确认小程序发布上线且小程序等级至少达到B级。
1、前往“获流”-“信息流”-“素材管理”-“百家号挂载素材提交”,完成挂载素材上传。
(1)素材编辑上传后,经审核后素材状态更新为“审核通过”,该条素材才可被挂载投放。
2、前往“获流” -“信息流“-“内容管理”内,点击「发视频」跳转至百家号后台内进行视频编辑。也可以直接访问百家号平台完成视频挂载。
3、在百家号视频编辑页面内,按照编辑规范完成视频上传及视频信息维护。后点击视频框体下方「小程序」入口,完成挂载物料选取。
(1)在弹出面板内搜索挂载目标小程序名称,并在搜索结果中选中所要挂载的小程序。
(2)选中小程序后即会展示该小程序下已过审挂载物料,则根据当前视频内容选择所需挂载目标物料即可完成。需注意所挂载物料需与当前视频内容存在相关性,若不相关则会导致审核未通过。
网站服务
(3)选中后即可在编辑页面内展示所选物料,并可点击「删除」按钮完成物料删除或替换。当视频信息及挂载物料填写完毕后即可点击「发布」按钮完成视频发布。
1、编辑发布前请确认小程序发布上线且已经完成准入条件中的相关配置; 2、点击【获流-信息流-内容管理】,选择【发图文】; 3、编辑图文内容。 (1)可结合场景在内容中选择插入图片、视频、小程序卡、文字链、商品卡、咨询组件,引导用户转化。注意:小程序卡、商品卡和咨询组件需至少选择一个插入。
①插入图片入口;②插入视频入口;③插入小程序卡和文字链入口,文字链在点击插入小程序卡后的页面中选择“是否设置挂载命中词”设置;④插入商品;⑤插入咨询组件(在线咨询组件和电话组件)
(2) C端文章正文上方默认展示“引导用户关注图片”,默认文案为“点击右上方关注按钮,体验不一样的精彩”,开发者可在“插图图片”入口更新文案。
4、预览、检测和发布文章。 (1)预览。编辑完成后可点击“预览”,扫码在手机端预览文章。
(2)质量检测。文章发布前,请点击编辑器右侧“开启检测”,使用工具检测图文内容是否符合规范,以提升发文效率。
(3)发布。预览和检测后进行发布,发布渠道可在编辑框下方勾选发送到百度APP-信息流或搜索/关注频道。
(4)点击“发布”提交审核后,还可以在弹窗中选择是否同步发布“群发通知“或”“发布动态”,如勾选“30天内不再提示”,则该弹窗入口 30 天内将不再出现,图文内容30天内不能同步发布“群发通知”或“发布动态”。
注意:群发通知发送至“百度APP-我的-通知”入口,每周可下发 4 次,次数与下发到通知入口的其他消息任务共用。
seo服务
5、发送成功后可展现在对应勾选频道,开发者可在【内容管理】首页查看发布情况及阅读数据。
编辑发布前请确认小程序发布上线且已经完成准入条件中的相关配置;
1、点击“获流 ->信息流 ->内容管理 -> 发动态”。 2、如果是首次发布动态,则进入百家号账号绑定流程,输入百家号账号和手机验证码,调用授权即完成小程序与百家号的绑定关系。如未注册百家号,请注册百度账号申请。 同一时刻一个小程序只能绑定一个百家号账号,进入发布页面后可操作账号换绑;一个百家号账号可以同时被多个小程序绑定。
绑定后进入动态发布页面,该页面分为动态内容发布和素材挂载两部分。
3、编辑动态内容目前支持编辑文字和插入图片,后续将支持插入视频、热点、表情等更多形式。 4、选择小程序素材挂载 动态挂载支持挂载该小程序的素材和同公司主体下其他小程序的素材
seo运营
1)该小程序下的所有素材在搜索框下默认展现,支持在搜索框内按照素材标题搜索查询,查询后选择挂载;
2)同主体下的所有小程序的素材,通过点击“查看更多素材”,按照小程序名称 / AppID 查询小程序,再通过素材标题查询对应小程序的素材,查询后选择挂载。
如小程序下没有素材或者需要上传新素材,请点击“添加新素材”进行素材上传, 填写页面内容并提交审核,审核通过后素材将在上述素材挂载位置出现。
5、发布动态 点击“发布”完成动态发布,发布后,可在“内容管理首页 -> 我的内容 -> 动态列表”中查看和管理。
只有完成动态内容编辑并挂载小程序素材后才可发布。
EasyPoi导入 <a-upload name="file" :showUploadList="false" :multiple="false" :headers="tokenHeader" :action="importExcelUrl" @change="handleImportExcel"> <a-button type="primary" icon="import">导入数据</a-button> </a-upload> data() { return { url: { importExcelUrl: 'cs/csBalanceAgent/importExcel' } } }, methods: { importExcelUrl: function() { return `${window._CONFIG['domianURL']}/${this.url.importExcelUrl}` }, /* 导入 */ handleImportExcel(info) { console.log('info-----------------', info) this.loading = true if (info.file.status !== 'uploading') { console.log('file==================', info.file, info.fileList) } if (info.file.status === 'done') { this.loading = false if (info.file.response.success) { // this.$message.success(`${info.file.name} 文件上传成功`); if (info.file.response.code === 201) { let { message, result: { msg, fileUrl, fileName } } = info.
1、都是按下返回鍵触发,调用父类方法会直接关闭调当前activity 2、先后调用顺序onKeyDown>onBackPressed 3、dispatchKeyEvent优先级最高,且上面两个方法不会调用 @Override public void onBackPressed(){ super.onBackPressed(); Log.i("adam","已退出"); } //都是按下返回鍵触发,调用父类方法会直接关闭调当前activity //先后调用顺序onKeyDown>onBackPressed @Override public boolean onKeyDown(int keyCode, KeyEvent event) { if ((keyCode == KeyEvent.KEYCODE_BACK)) { Toast.makeText(this, "按下了back键 onKeyDown()", Toast.LENGTH_SHORT).show(); Log.i("adam","onKeyDown已退出"); return super.onKeyDown(keyCode, event); }else { Log.i("adam","true"); return false; } } //优先级最高,且上面两个方法不会调用 @Override public boolean dispatchKeyEvent(KeyEvent keyEvent) { if (keyEvent.getKeyCode() == 4 && keyEvent.getAction() == 0 && keyEvent.getRepeatCount() == 0) { Log.i("adam","dispatchKeyEvent已退出"); } return false; } 4、新建一个退出对话框 public void adamExit(){ // 仅供参考 AlertDialog.
1. 对根目录下的静态资源代理 Nginx代理nginx.conf配置——反向代理 2. 目录代理 如果需要将资源代理到不同的目录下,则在nginx.conf中的server节点下进行如下配置:
location /image { root /opt/cache; } location vedio { root /opt/cache; } 修改后,重新加载nginx配置即可,nginx部分命令如下:
# 检查配置 nginx -t # 重载配置 nginx -s reload # 关闭 nginx -s quit # 启动 nginx -s start 3. 代理指定路径下的静态资源 在server中添加如下配置(示例listen端口为80)
location ~ /video/.*\.(mp4)?$ { expires -1; # 匹配结果示例:opt/cache/video/demo.mp4 root /opt/cache; } 访问:localhost/video/demo.mp4即可访问
前言 实例分割一般有两种做法,一种是top-down,既先检测 bbox,后在每个bbox中进行mask的分割,例如Mask R-CNN。第二种为bottom-up做法,先分割出每一个像素,再进行归类。本文介绍的两篇论文另辟蹊径, 直接分割实例 mask,属于box-free的做法。正如YOLO大神Joseph Redmon所说“Boxes are stupid anyway though, I’m probably a true believer in masks except I can’t get YOLO to learn them“。本文就是摒弃了boxes进行实例分割,因此有必要对该论文进行深入分析。
论文地址:v1: https://arxiv.org/abs/1912.04488 ,v2: https://arxiv.org/abs/2003.10152。
参考的代码为在mmdetection的基础上实现的:https://github.com/WXinlong/SOLO
SOLO v1 head设计 首先思考一个问题,能否像语义分割一样进行实例分割?实例分割和语义分割在算法处理上最大的不同就是,实例分割需要处理同类别的实例重叠或粘连的问题。那么如果将不同的实例分配到不同的输出channel上,不就可以解决这个问题了吗?本文作者正是这种思路,不过这样也面临两个问题: 一是通道分配顺序的问题,语义分割是根据类别进行通道分配的。而对于实例分割,相同类别的不同实例需要分配到不同通道上,需要解决按照什么样的规则分配。二是尺度问题,不同尺度的物体利用相同大小的输出来预测会导致正负样本不平衡,以及小目标分割边缘不够精细的问题。对于这两个问题,本文作者给出了解答。作者首先对MS COCO数据集进行统计,发现在验证集中,绝大多数(约98.9%)的实例要么中心位置不同,要么大小不同。因此可以通过中心位置和对象大小直接区分实例, 既location 和 sizes。所以作者利用位置来分配实例应该落入哪一个通道,利用FPN来解决尺度问题。
具体做法为: 类似YOLO中的做法,首先将图片等分为 S×S\epsilon=0.2 。当被缩小后的box落入原图上某几个格子,这些格子对应的分类分支位置以及mask分支channel为正样本,否则为负样本。每一个gt平均有3个正样本。代码如下:
# 分类分支的正负样本分配,这里的top,down,left,right为gt box缩小sigma倍后的box上下左右值 cate_label[top:(down+1), left:(right+1)] = gt_label 对于mask分支的正样本分配,在0.2倍的gt box内grid cell对应的通道均分配为mask正样本 seg_mask = mmcv.imrescale(seg_mask, scale=1. / output_stride)
seg_mask = torch.Tensor(seg_mask)
for i in range(top, down+1):
for j in range(left, right+1):
RK3568 Android11 SDK支持两路MIPI DSI单独或者组合双通道显示;
其中每一路DSI支持1920* 1080@60fps 输出,
两路DSI组合双通道输出的话分辨率可达2560* 1440@60fps ;
调试MIPI屏幕主要还是需要找供应商提供初始化的CMD;大多数屏幕是需要初始化的CMD;
少数屏是已集成在芯片里,只需操作MIPI屏幕打开显示即可;
本文分成两部分,包括【国内服务器上搭建chat GPT】和【后端Spring Boot集成chat GPT】。
无论是在【国内服务器上搭建chat GPT】和【后端Spring Boot集成chat GPT】,两个方式都需要魔法访问,否则是无法正常使用的,即需要具备正常访问谷歌或者 api.openai.com的能力。
至于什么是魔法访问,以及如何搭建魔法访问,请自行研究哈。
下面就开始讲解两部分的教程。
一、国内服务器上搭建chat GPT 首先,你需要准备以下东西:
1、一台可以访问公网的Linux云服务器,最低配置1核2G即可(当然,有钱可以任性,买最高配置)
2、chatGPT的密钥
3、开源的仿chatGPT的Docker镜像
1.1、准备一台云服务器 可以是腾讯云、阿里云或者华为云等,我分别在阿里云和华为云上都能正常搭建。
1.2、设置网络代理 在部署魔法访问的服务器上,需要在/etc/profile增加代理,确保通过密钥方式的chatGPT接口调用能正常访问:
export all_proxy=http://127.0.0.1:8889
export http_proxy=http://127.0.0.1:8889
export https_proxy=https://127.0.0.1:8889
export all_proxy=socks5://127.0.0.1:1080
这里的8889和1080需要根据你的魔法访问里的config.json来相应设置。
配置完成后,执行source /etc/profile,检验一下curl https://api.openai.com/
可以访问即没问题。可以继续往下走。
1.3、安装Docker 搭建完成后,因为Docker的对外访问若需要走所在宿主的代理话,还需要设置以下操作——
创建一个~/.docker/目录,然后在该目录下新建一个config.json文件,在该文件里添加以下命令——
{ "default": { "httpProxy": "http://127.0.0.1:8889", "httpsProxy": "http://127.0.0.1:8889", "noProxy": "*.test.example.com,.example2.com,127.0.0.0/8" } } } 1.4、Docker镜像 目前网上GitHub已经开源了许多优秀的仿写chatGPT 页面的应用,我们无需再额外造轮子,只需要挑选其中一款用来打包部署成Docker容器运行即可。
我使用的是chatgpt-mirror这个开源项目。
直接克隆项目到对应的Linux服务器——
git clone https://github.com/yuezk/chatgpt-mirror.git 在基于该开源项目以Dockerfile形式打包前,需要执行以下被依赖到的镜像——
docker pull node:18-alpine docker pull node:18-slim 接下来,就可以执行以下操作来创建一个Docker镜像了——
cd chatgpt-mirror #--network host表示与宿主公用网络,即走代理,然后留意下最后有一个 .
第十二章 面向对象实现 一、面向对象实现概述 1.主要任务 (1)把面向对象设计结果翻译成用某种程序语言书写的面向对象程序。
(2)测试并调试面向对象的程序。 2.面向对象程序质量的影响因素 (1)面向对象设计的质量;
(2)采用的程序语言的特点;
(3)程序设计风格。 3.保证软件可靠性的方法 保证软件可靠性的主要措施是软件测试。面向对象测试的目标是用尽可能低的测试成本发现尽可能多的软件错误。 二、程序设计语言 1.面向对象语言的优点 (1)面向对象设计结果的表示方式
①面向对象语言
编译程序可以自动把面向对象概念映射到目标程序中。
②非面向对象语言
必须由程序员自己把面向对象概念映射到目标程序中。(2)优点
从面向对象观点看来,能够更完整、更准确地表达问题域语义的面向对象语言的语法是非常重要的,会带来以下3个重要优点:
①一致的表示方法
面向对象开发基于不随时间变化的、一致的表示方法。既有利于在软件开发过程中始终使用统一的概念,也有利于维护人员理解软件的各种配置成分。
②可重用性
既可重用面向对象分析结果,也可重用相应的面向对象设计和面向对象程序设计结果。
③可维护性
程序显式地表达问题域语义,对维护人员理解待维护的软件有很大帮助。在选择编程语言时,应该考虑的首要因素是哪个语言能最恰当地表达问题域语义。 2.面向对象语言的技术特点 纯面向对象语言着重支持面向对象方法研究和快速原型的实现,而混合型面向对象语言的目标则是提高运行 速度和使传统程序员容易接受面向对象思想。成熟的面向对象语言通常都提供丰富的类库和强有力的开发环境。在选择面向对象语言时应该着重考虑以下几种技术特点。
(1)支持类与对象概念的机制
①内容
面向对象语言允许用户动态创建对象,并且可以用指针引用动态创建的对象。需要及时释放不再需要的对象所占用的内存。
②管理内存的方法
a.由语言的运行机制自动管理内存,即提供自动回收"垃圾"机制;
b.由程序员编写释放内存的代码。
注意:自动管理内存虽然方便且安全,但是必须采用先进的垃圾收集算法才能减少开销。(2)实现聚集结构的机制
①使用指针;
②使用独立的关联对象。
注意:大多数现有的面向对象语言并不显式支持独立的关联对象,在这种情况下,增加内部指针可以方便地实现关联。(3)实现泛化结构的机制
①实现继承的机制;
②解决名字冲突的机制,即处理在多个基类中可能出现的重名问题。(4)实现属性和服务的机制
①实现属性的机制
a.支持实例连接的机制;
b.属性的可见性控制;
c.对属性值的约束。
②实现服务的机制
a.支持消息连接(表达对象交互关系)的机制;
b.控制服务可见性的机制;
c.动态联编(在发送消息前,无须知道接受消息的对象属于哪个类)。(5)类型检查
①分类
a.弱类型
语言仅要求每个变量或属性隶属于一个对象。
b.强类型
语法规定每个变量或属性必须准确地属于某个特定的类。
②强类型语言优点
a.有利于在编译时发现程序错误,提高软件的可靠性。
b.增加了优化的可能性,提高软件的运行效率。
③适用性
使用强类型编译型语言开发软件产品,使用弱类型解释型语言快速开发原型。(6)类库
①类型
大多数面向对象语言都提供一个实用的类库。某些语言本身并没有规定提供什么样的类库,而是由实现这种语言的编译系统自行提供类库,主要可分为以下几类:
a.包含实现通用数据结构的类,即包容类;
b.实现各种关联的类;
c.独立于具体设备的接口类;
d.用于实现窗口系统的用户界面类。
②重要性
存在类库,许多软构件就不必由程序员从头编写了,为实现软件重用带来很大方便。(7)效率
提高面向对象语言效率的方法为:
①使用拥有完整类库的面向对象语言。
第十一章:面向对象设计 一、面向对象设计的概念 1.定义 设计是把分析阶段得到的需求转变成符合成本和质量要求的、抽象的系统实现方案的过程。从面向对象分析到面向对象设计是一个逐渐扩充模型的过程,即面向对象设计就是用面向对象观点建立求解域模型的过程。 2.设计与分析的关系 (1)分析结果可以直接映射成设计结果,而在设计过程中又会加深和补充对系统需求的理解,进一步完善分析结果。
(2)分析和设计活动是一个多次反复迭代的过程。
(3)分析是提取和整理用户需求,并建立问题域精确模型的过程。设计则是把分析阶段得到的需求转变成符合成本和质量要求的、抽象的系统实现方案的过程。 3.分类 (1)系统设计:确定实现系统的策略和目标系统的高层结构。
(2)对象设计:确定解空间中的类、关联、接口形式及实现服务的算法。 二、面向对象设计的准则 1.优秀设计的定义 优秀设计是权衡了各种因素,从而使得系统在其整个生命周期中的总开销最小的设计。优秀软件设计的一个主要特点就是容易维护。 2.准则 (1)模块化
面向对象软件开发模式支持了把系统分解成模块设计的原理,对象是面向对象软件系统中的模块,它是把数据结构和操作这些数据的方法紧密地结合在一起所构成的模块。(2)抽象
面向对象的程序设计语言不仅支持过程抽象,而且支持数据抽象,对象类实际上是具有继承机制的抽象数据类型,它对外开放的公共接口构成了类的规格说明(协议),这种接口规定了外界可以使用的合法操作符,利用这些操作符可以对类实例中包含的数据进行操作。
①规格说明抽象
使用者无须知道操作符的实现算法和类中数据元素的具体表示方法,就可以通过这些操作符使用类中定义的数据,这种抽象称为规格说明抽象。
②参数化抽象
指当描述类的规格说明时并不具体指定所要操作的数据类型,而是把数据类型作为参数,使得类的抽象程度更高,应用范围更广,可重用性更高。(3)信息隐藏
在面向对象的软件中,信息隐藏通过对象的封装来实现,即类结构分离了接口与实现,从而支持了信息隐藏。对于类,属性的表示方法和操作的实现算法都是隐藏的。(4)弱耦合
耦合是指一个软件结构内不同模块之间互连的紧密程度。在面向对象方法中,对象是最基本的模块,因此,耦合主要指不同对象之间相互关联的紧密程度。弱耦合是优秀设计的一个重要标准。
①交互耦合
对象间的耦合通过消息连接来实现,则这种耦合是交互耦合。要使交互耦合尽可能松散,必须遵守下述准则。
a.尽量降低消息连接的复杂程度。应该尽量减少消息中包含的参数个数,降低参数的复杂程度。
b.减少对象发送或接收的消息数。
②继承耦合
继承是一般类与特殊类之间耦合的一种形式。通过继承关系结合起来的基类和派生类构成了系统中粒度更大的模块,因此,它们彼此之间应该结合得越紧密越好。(5)强内聚
内聚衡量一个模块内各个元素彼此结合的紧密程度,在设计时应该力求做到高内聚。在面向对象设计中存在下述3种内聚:
①服务内聚
一个服务应该完成一个且仅完成一个功能。
②类内聚
设计类的准则是,一个类应该只有一个用途,它的属性和服务应该是高内聚的。如果某个类有多个用途,应该把它分解成多个专用的类。
③一般—特殊内聚
设计出的一般一特殊结构应该是对相应的领域知识的正确抽取。紧密的继承耦合与高度的一般一特殊内聚是一致的。(6)可重用
软件重用是提高软件开发生产率和目标系统质量的重要途径。重用基本上从设计阶段开始。重用有两方面的含义:
①尽量使用已有的类。
②如果需要创建新类,则在设计这些新类的协议时应该考虑将来的可重复使用性。 三、启发规则 1.必要性 总结人类使用面向对象方法学开发软件的经验,可以得出几条启发规则,它们往往能帮助软件开发人员提高面向对象设计的质量。 2.具体规则 (1)设计结果应该清晰易懂
使设计结果清晰、易读、易懂是提高软件可维护性和可重用性的重要措施。保证设计结果清晰易懂的主要因素如下:
①用词一致
应该使名字与它所代表的事物一致,而且应该尽量使用人们习惯的名字。不同类中相似服务的名字应该相同。
②使用已有的协议
如果开发同一软件的其他设计人员已经建立了类的协议,或者在所使用的类库中已有相应的协议,则应该使用这些已有的协议。
③减少消息模式的数目
如果已有标准的消息协议,设计人员应该遵守这些协议。
④避免模糊的定义
一个类的用途应该是有限的,而且应该从类名可以较容易地推出它的用途。(2)一般一特殊结构的深度应适当
①使类等级中包含的层次数适当,类等级中包含的层次保持在7±2。
②不能仅从方便编码的角度出发随意创建派生类,应该使一般一特殊结构与领域知识或常识保持一致。(3)设计简单的类
应该尽量设计小而简单的类,以便开发和管理。为使类保持简单,应注意以下几点:
①避免包含过多的属性
属性过多通常表明这个类过分复杂了,它所完成的功能可能太多了。
②有明确的定义
为了使类的定义明确,分配给每个类的任务应该简单,最好能使用一两个简单语句描述它的任务。
③简化对象之间的合作关系
如果需要多个对象协同配合才能做好一件事,则破坏了类的简明性和清晰性。
④不要提供太多服务(公共服务不超过7个)
一个类提供的服务过多,同样表明这个类过分复杂。典型地,一个类提供的公共服务不超过7个。
⑤划分“主题”。(4)使用简单的协议
一般来说,消息中的参数不要超过3个。通过复杂消息相互关联的对象是紧耦合的,对一个对象的修改往往导致其他对象的修改。(5)使用简单的服务
①避免使用复杂的服务。
②需要在服务中使用CASE语句时,应用一般—特殊结构代替这个类。(6)把设计变动减至最小
文章目录 前言一、粉丝提问二、自信读题三、O(n^2) 算法1四、O(n^2) 算法2五、O(nlogn) 算法六、O(nlogn) C++版本七、O(nlogn) C++优化版本 前言 英雄算法联盟 - 七月集训 已经开始 20 天,八月算法集训 将于 08月01日 正式开始,目前已经提前开始报名,报名方式参见(八月算法集训报名),想要参加的同学,建议提早报名,因为对于算法零基础的同学,会有一些提前的准备工作,比如需要 1 - 5 天的时间完成预训练 和 九日集训 提前养成刷题的习惯,再参加算法集训会更加有成效。
一、粉丝提问 英雄老师,昨天面试遇到的,力扣 2563,难哭了,55555!
二、自信读题 读题!给定一个整数数组 nums 和两个整数 lower 和 upper,返回 公平数对的数目,如果 (i, j) 数对满足以下情况,则认为它是一个 公平数对。
0 <= i < j < n,且 lower <= nums[i] + nums[j] <= upper
三、O(n^2) 算法1 计算数组长度,存储在 n 中,初始化结果变量 ans 为 0。遍历枚举第一个下标 i,遍历枚举第二个下标 j,如果 lower ≤ num[i]+num[j] ≤ upper,则表明是一组合法的 (i, j) 数对。结果计数器加一,返回这个计数器,就是我们要求的答案啦。运行,没什么问题:
浮点数加减法计算导致精度损失的问题 文章目录 浮点数加减法计算导致精度损失的问题示例分析解决方案 示例 来看一段简单的java代码:
public class Solution { public static void main(String[] args) { double a = 398.92; double b = 1282.04; double c = 2167.38; double d = 3284.94; double sum = a+b+c+d; System.out.println(sum); } } 猜一猜计算的结果是什么?
7133.280000000001 7133.280000000001 7133.280000000001
很震惊, 为什么小数点后两位的小数相加会得到小数点后多位的小数呢? 按理说无论多少个小数点后两位的小数相加最后的和都不会产生多于小数点后两位的小数
这是编程语言导致的问题吗?
再来看一下在python语言中的结果
a = 398.92 a += 1282.04 a += 2167.38 a += 3284.94 print(a) 从运行结果来看, 和Java运行的结果是一毛一样。
其实浮点数的精度损失问题并不是编程语言的特有问题,而是由于浮点数的二进制表示方式和计算机硬件设备的局限性所导致的。无论使用什么编程语言,都无法完全避免浮点数的精度损失问题,只能采用一些方法来减少误差或提高精度。
分析 那问题出在了哪里呢?
就拿Python中浮点数加减法来说吧,Python中的浮点数类型float,是按IEEE 754标准来存储的。该标准对浮点数的精度做了规定:
使用二进制来表示一个浮点数,包括符号位、指数位和小数位(尾数位)尾数位数是有限的,一般为53位(64位系统可达64位)指数部分也有位数限制,一般为11位(64位系统可达15位) IEEE 754浮点数标准定义的浮点数格式:
DDE处理的细节 分离背景层和细节层:使用特殊的滤波器,将图像分成背景层和细节层。背景层通常包含低频信息,而细节层包含高频信息。
对背景层进行灰度增强:通过对背景层应用适当的灰度增强算法,提高背景层的对比度和视觉感知。
对细节层进行细节增强和噪声抑制:细节层中包含着图像的细节信息,可以利用非线性处理方法,例如增强锐化或边缘增强算法来增强细节,并抑制噪声。
动态范围调整:根据图像的整体动态范围,对背景层和细节层进行动态范围的调整和压缩,以便将原本动态范围较高的图像信息映射到8位输出图像的范围内。
合成输出图像:将增强后的背景层和细节层重新合成为一幅8位输出图像,以显示大动态温差和目标局部细节信息。
如上,DDE技术通过滤波器分离、背景层和细节层的处理、动态范围调整等步骤,能够提取和突出图像的细节,并将其限制在8位输出图像中,以保留大动态温差和目标局部的细节信息。
分离背景层和细节层: 对背景层进行灰度增强: 两种方法的效果
自适应直方图均衡化 对比度拉伸 对细节层进行细节增强 结果比对: DDE算法 直接对输入图像 应用 直方图均衡化 直接对输入图像应用自适应直方图均衡化
自适应直方图均衡化(局部对比度增强) 深度学习学习到图像的哪些特征: 边缘特征:边缘,即灰度或颜色变化的地方
纹理特征:即图像中重复的局部结构
形状特征:包括物体的轮廓,形状的几何特征
颜色特征:不同颜色空间的颜色特征,包括颜色分布、颜色直方图
空间结构特征:不同物体之间的空间结构关系,包括物体的相对位置、大小、方向等特征
层次结构特征:从低层次的局部特征到高层次的语义特征
个人总结: 我是为了做红外目标检测才做的DDE数据增强
个人感觉DDE算法将背景和前景区分度加大,提高图像对比度,同时边缘特征、性状特征很清楚
而直方图均衡化有点曝光太强的感觉,边缘特征、性状特征不太清楚
自适应直方图均衡化后,边缘特征、性状特征也比较清楚
DDE算法处理后的比自适应直方图肉眼上看上去更舒服,但是还是需要结合模型训练才能看出DDE算法是否比自适应直方图要好!
代码: #include <opencv2/opencv.hpp> using namespace cv; int main() { // 读取输入图像 Mat inputImage = imread("/home/jason/work/01-img/infrared.png",IMREAD_GRAYSCALE); imshow("input", inputImage); // ------------------- // 执行DDE细节增强 // ----------------- // 第一步:滤波器分离低频和高频信息 Mat blurImg, detailImg; GaussianBlur(inputImage, blurImg, Size(0, 0), 10); detailImg = inputImage - blurImg; imshow("
一、软件可靠性 软件可靠性是软件产品在规定的条件下和规定的时间区间完成规定功能的能力。
1 软件可靠性的定量描述 1. 规定时间。
使用执行时间最为准确。
执行时间:软件运行过程中,CPU执行程序指令所用的时间总和。
2. 失效概率。
用 F(t) 表示,可以看作关于时间 t 的一个连续、可导的函数。
3. 可靠度。
可靠度就是软件系统在规定的条件下、规定的时间内不发生失效的概率。
用 R(t) 表示,R(t) = 1 - F(t)。
4. 失效强度。
失效强度是指单位时间软件系统出现失效的概率。
用 f(t) 表示,f(t) = F'(t)。
5. 平均失效前时间。
MTTF,定义为从 t=0 时到故障发生时系统的持续运行时间的期望值。
MTTF = R(t)在(0, ∞)上的积分。
6. 平均恢复前时间。
MTTR,就是从出现故障到修复成功中间的这段时间。MTTR越小表示易恢复性越好。
7. 平均故障间隔时间。
MTBF,失效或维护中所需的平均时间。
对于可靠度服从指数分布的系统,从任一时刻 t₀ 到达故障的期望时间都是相等的,因此有 MTBF = MTTF + MTTR。
2 可靠性目标 2.1 失效严重程度类 失效严重程度类就是对用户具有相同程度影响的失效集合。
(通俗地讲,就是把失效分为致命、严重、一般 等级)
2.2 可靠性目标参考 失效严重程度类
可靠性要求/%
失效强度
平均无失效时间
目录
概念
特点
进程段
进程分类
进程状态
进程状态切换图
函数接口
创建子进程
fork
回收进程资源
wait
waitpid
结束进程
exit
_exit
获取进程号
getpid
getppid
守护进程 特点
步骤
概念 程序:编译好的可执行文件,存放在磁盘上的指令和数据的有序集合,是静态的,没有任何执行的概念。
进程:独立的可调度的任务,是执行一个程序所分配资源的总称,是程序的一次执行过程,是动态的,包括创建、调度、执行和消亡。
特点 系统会为每一个进程分配从0-4G的虚拟空间,0-3G(用户空间)是每个进程所独有的,3-4G(内核空间)是所有进程共有的。CPU调度进程时会给进程分配时间片(几毫秒~几十毫秒),当时间片用完后,CPU再进行其他进程的调度,实现进程的轮转,从而实现多任务的操作。 进程段 Linux中的进程包含三个段:
“数据段”存放的是全局变量、常数以及动态数据分配的数据空间(如malloc()函数取得的空间)等“正文段”存放的是程序中的代码“堆栈区”存放的是函数的返回地址、函数的参数以及程序中的局部变量 进程分类 交互进程:该类进程是由shell控制和运行的。交互进程既可以在前台运行,也可以在后台运行。该类进程经常与用户进行交互,需要等待用户的输入,当接收到用户的输入后,该类进程会立刻响应,典型的交互式进程有:shell命令进程、文本编辑等。批处理文件:该类进程不属于某个终端,它被提交到一个队列中以便执行。守护进程:该类进程在后台运行。它一般在Linux启动时开始执行,系统关闭时才结束。 进程状态 运行态(TASK_RUNNING):R
指正在被CPU运行或者就绪的状态。这样的进程被称为running进程。
睡眠态(等待态):
可中断睡眠态(TASK_INTERRUPPTIBLE)S:
处于等待状态中的进程,一旦被该进程等待的资源被释放,那么该进程就会进入运行状态。
不可中断睡眠态(TASK_UNINTERRUPTIBLE)D:
该进程状态只能用wake_up() 函数才能唤醒。
暂停态(TASK_STOPPED)T:(又叫停止态)
当进程收到信号SIGSTOP、SIGSTP、SIGTTIN或SIGTTOU时,就会进入暂停状态。可向其发送SIGCONT信号让进程转换到可运行状态。
死亡态:X
进程结束。
僵尸态(TASK_ZOMBIE):Z
当进程已经终止运行,但还占用系统资源,要避免僵尸态的产生。
进程状态切换图 进程创建后,进程进入就绪状态,当CPU调度到此进程时进入运行态,当时间片用完时,此进程就会进入就绪态,如果此进程正在执行一些IO操作(阻塞操作)会进入阻塞态,完成IO操作(阻塞结束)后又可进入就绪态,等待CPU的调度,当进程运行结束即进入结束态。
函数接口 创建子进程 fork 格式:pid_t fork(void); 功能:创建子进程 返回值: 成功:在父进程中:返回子进程的进程号 >0 在子进程中:返回值为0 失败:-1并设置errno #include <stdio.h> #include <unistd.h> #include <sys/types.h> #include <sys/wait.h> int main(int argc, char const *argv[]) { int a = 0; printf("
遗憾 最大的遗憾是:
做的项目并发量、用户量不大。背锅,被人甩锅的时候,没有进行明确的反击。 屈辱 项目:2021-2022 打印日志的时候,如果实体重写了toString(),即使使用Map类型,也不需要使用JSON包来序列化json字符串。-- 那时候你就应该直接反击,直接说,而不是不敢说。新入项目组,不知道有跳板机查看数据库,就被那女的阴阳怪气一番。-- 那时候你就应该直接说:我怎么知道?谁跟我说过没?自测的时候,因为没有收到测试通知,直接又被吼。-- 那时候你就应该说:没有通知让自测。逼你搭建组合流水线的时候,你就应该说:那怎么搭建。而不是一个人自己去找人,而是让他们自己找人。那些人回滚代码覆盖了自己的代码的时候,就应该对那女的说:那你发一下邮件,如果有回滚的代码覆盖了本次需求的代码,则与我无关。开会搞融合sca,阴阳怪气喊你的时候,就应该直接不理那女的!或者直接反问:搞融合的时候,有会议吗?有文档给我吗?!喊支撑的时候,就应该直接访问那女的:我刚刚开通权限,你又没给我说过怎么搞,我怎么支撑!4月底修改数据库的时候,就应该直接说:对对对,就让她错下去,而不是跟她废话说哪里错!4月份,那个测试发测试结果在群里的时候,就应该直接反问测试:你懂业务没?基于哪点业务?4月份,前端参数都给错,和测试一起甩锅给你的时候,你就应该把所有图发到群里,直接反问:测试不会F12看参数吗?前端的问题还要后端来定位!而不是懦弱得私聊发截图给前端!懦夫!5.23左右在会上背锅的时候,就应该直接发话:把以前的单子拿出来,对着看,根本没这样的需求!而不是生闷气,还私聊发截图解释,最后换来一句冷冷的:忘记了!即使没有在会上指出来,也应该发在群里!6月的时候,6.1那天就不应该接那女的电话,6.3的时候也是!6.7的时候,给你分了个垃圾配置需求,你就应该直接对那女的说:这个搞不来,你去给别人!6.20左右,问文档的时候,那女的连接口文档和checklist文档都分不清就吼你的时候,你就应该直接反问那女的:这两个文档不是同一个,OK?你可以拉xxx上来问啊!。。。或者你在会后直接发群里问别人:接口文档和checklist文档是同一个吗,然后再说有人居然认为是同样一个!6.21左右,那女的、还有男测试,反问我给他们说需求的时候,你就应该直接说:你见过有开发者给测试说需求的吗?谁给的需求,测试就问谁去!还有,什么什么他不懂技术!你把我想成什么!你怎么给我说,我就怎么给他们说,有问题吗?问题出现在哪?6.23分配需求搞整改的时候,你就应该直接不出声。6.23那女的问你链接的时候,你就应该直接不理她!CTMD!6.27那女的让你帮他们改数据库的时候,你就不应该理,各自改各自的!6.29,英雄的怒气,忍无可忍,那时候,应该加上这样的来怼那女的:你跟xx简直一对奇葩,离职了的有多少人讨厌你们,清楚吗?了解吗?我告诉你们,你们怎么跟我说,我就怎么给新人说,别怪我!还有什么什么他不会技术,你把老子想成什么了,老子明天就能走了,今天就要怼你,老子受够你们了,告辞!6.30 - 7.14,自己退出了群,就不应该再理那群人,你还交接个锤子! 注:那女的,是爱国厂的女组长!
过错 在项目1的时候,应该团结一切能团结的力量,而不是把那女的一套用到其他人身上!尽量耐心地给别人讲解技术和业务! 这一切,都是因为太懦弱!社会这本书,你读了几页?
不是因为你的示弱而不欺负你,恰恰因为你的示弱而欺负你!
1、查看k8s 运行状态
systemctl status kubelet.service 2、启动k8s
systemctl start kubelet.service 3、重启k8s
systemctl restart kubelet.service 4、重置k8s(别手贱执行,相当于上库跑路了)
kubeadm reset 5、获取节点
kubectl get nodes 6、获取pods
kubectl get pods 7、获取svc
kubectl get svc 8、查看运行pod、deployment等状态
kubectl desceribe pod 名称 9、上面命令查不到可以用pod运行日志
kubectl logs -f <name> -n kube-system
一、Goby的漏洞发现 对一个IP进行C段扫描时,发现了一台服务器存在Elasticsearch未授权访问漏洞
二、Elasticsearch未授权访问漏洞 漏洞描述 ElasticSearch是一个基于Lucene的搜索服务器。它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口。Elasticsearch是用Java开发的,并作为Apache许可条款下的开放源码发布,是当前流行的企业级搜索引擎。Elasticsearch的增删改查操作全部由http接口完。由于Elasticsearch授权模块需要付费,所以免费开源的Elasticsearch可能存在未授权访问漏洞。该漏洞导致,攻击者可以拥有Elasticsearch的所有权限。可以对数据进行任意操作。业务系统将面临敏感数据泄露、数据丢失、数据遭到破坏甚至遭到攻击者的勒索。
三、漏洞手动检测 该服务器Elasticsearch开放的是9200端口
若存在Elasticsearch未授权访问漏洞,则搜索以下内容发现敏感数据
http://localhost:9200/_plugin/head/ web管理界面 http://localhost:9200/_cat/indices http://localhost:9200/_river/_search 查看数据库敏感信息 http://localhost:9200/_nodes 查看节点数据 手动检测,发现漏洞存在
四、修复建议 1、限制IP访问,禁止未授权IP访问ElasticSearch端口(默认9200)。
2、设置nginx反向代理服务器,并设置http basic认证来实现elasticsearch的登录认证
本文是LLM系列的文章,针对《A Survey on Time-Series Pre-Trained Models》的翻译。
时间序列预训练模型综述 摘要1 引言2 背景2.1 时间序列挖掘任务2.1.1 时间序列分类2.1.2 时间序列预测2.1.3 时间序列聚类2.1.4 时间序列异常检测2.1.5 时间序列推测 2.2 深度学习模型用于时间序列2.2.1 循环神经网络2.2.2 卷积神经网络2.2.3 Transformer 2.3 为什么预训练模型 3 TS-PTMs概览3.1 监督PTMs3.1.1 基于分类的PTMs3.1.2 基于预测的PTMs 3.2 非监督的PTMs3.2.1 基于重建的PTMs 3.3 自监督的PTMs3.3.1 基于一致性的PTMs3.3.2 伪标记PTMs 4 实验结果和分析4.1 PTMs在时间序列分类上的性能4.1.1 基于监督分类和无监督重构的迁移学习PTM的比较4.1.2 基于Transformer和一致性的PTMs比较4.1.3 可视化 4.2 PTMs在时间序列预测上的性能4.3 PTMs在时间序列异常检测上的性能 5 未来方向5.1 大规模时间序列数据集5.2 时间序列的固有性质5.3 时间序列中的Transformer5.4 对时间序列的对抗性攻击5.5 时间序列噪声标签的预训练模型 6 结论 摘要 时间序列挖掘在实际应用中显示出巨大的潜力,是一个重要的研究领域。基于大量标记数据的深度学习模型已成功用于TSM。然而,由于数据注释成本的原因,构建大规模标记良好的数据集是困难的。近年来,预训练模型由于其在计算机视觉和自然语言处理方面的卓越表现,逐渐引起了时间序列领域的关注。在这项综述中,我们对时间序列预训练模型(TS-PTM)进行了全面的回顾,旨在指导对TS-PTM的理解、应用和研究。具体来说,我们首先简要介绍TSM中使用的典型深度学习模型。然后,我们根据预训练技术对TS-PTM进行了概述。我们探索的主要类别包括有监督的、无监督的和自我监督的TS-PTM。此外,还进行了大量的实验来分析迁移学习策略、基于Transformer的模型和具有代表性的TS-PTM的优缺点。最后,我们指出了TS-PTM未来工作的一些潜在方向。源代码位于https://github.com/qianlima-lab/time-series-ptms.
1 引言 作为数据挖掘领域的一个重要研究方向,时间序列挖掘(TSM)已被广泛应用于现实世界中的应用,如金融、语音分析、动作识别和交通流预测。TSM的基本问题是如何表示时间序列数据。然后,可以基于给定的表示来执行各种挖掘任务。由于严重依赖领域或专家知识,传统的时间序列表示(例如,shapelets)非常耗时。因此,自动学习适当的时间序列表示仍然具有挑战性。
近年来,深度学习模型在各种TSM任务中取得了巨大成功。与传统的机器学习方法不同,深度学习模型不需要耗时的特征工程。相反,他们通过数据驱动的方法自动学习时间序列表示。然而,深度学习模型的成功依赖于大量标记数据的可用性。在许多真实世界的情况下,由于数据获取和注释成本的原因,很难构建一个标记良好的大型数据集。
为了减轻深度学习模型对大型数据集的依赖,通常使用基于数据增强和半监督学习的方法。数据增强可以有效地提高训练数据的大小和质量,并已被用作许多计算机视觉任务的重要组成部分。然而,与图像数据增强不同的是,时间序列数据增强还需要考虑时间序列中的时间依赖性和多尺度依赖性等属性。此外,时间序列数据增强技术的设计通常依赖于专家知识。另一方面,半监督方法使用大量未标记的数据来提高模型性能。然而,在许多情况下,即使是未标记的时间序列样本也很难收集(例如,医疗保健中的心电图时间序列数据)。
缓解训练数据不足问题的另一个有效解决方案是迁移学习,它放宽了训练和测试数据必须独立且相同分布的假设。迁移学习通常有两个阶段:预训练和微调。在预训练期间,模型在一些包含大量数据的源域上进行预训练,这些源域是独立的,但与目标域相关。在微调时,对来自目标域的通常有限的数据进行预训练模型(PTM)的微调。
最近,PTM,特别是基于Transformer的PTM,在各种计算机视觉(CV)和自然语言处理(NLP)应用中取得了显著的性能。受这些启发,最近的研究考虑了时间序列数据的时间序列预训练模型(TSPTM)的设计。首先,通过监督学习、无监督学习或自监督学习对时间序列模型进行预训练,以获得适当的表示。然后在目标域上对TS-PTM进行微调,以提高下游TSM任务(例如,时间序列分类和异常检测)的性能。
监督TS-PTM通常通过分类或预测任务进行预训练。然而,难以获得用于预训练的大量标记时间序列数据集往往限制了监督TSPTM的性能。此外,无监督的TS-PTM利用未标记的数据进行预训练,这进一步解决了标记数据不足的限制。例如,基于重建的TS-PTM使用自动编码器和重建损失来预训练时间序列模型。最近,基于对比学习的自监督PTM在CV中显示出了巨大的潜力。因此,一些学者已经开始探索基于一致性的任务设计和伪标记技术,以挖掘时间序列的固有属性。尽管如此,TS PTM的研究仍然是一个挑战。
在这项调查中,我们对TS-PTM进行了全面的回顾。具体来说,我们首先介绍了TSM中使用的各种TSM任务和深度学习模型。然后,我们基于预训练技术提出了TS PTM的分类法(图1)。其中包括有监督的预训练技术(导致基于分类和基于预测的PTM)、无监督的预训练技术(基于重建的PTMs)和自监督的预训技术(基于一致性和基于伪标记的PTMs)。请注意,一些TS-PTM可能使用多个任务(例如,[37]中的预测和重建或[38]中的一致性)进行预训练。为了简化综述,我们根据TS-PTM的核心预训练任务对其进行了分类。
在时间序列分类、预测和异常检测方面进行了广泛的实验,以研究各种迁移学习策略和具有代表性的TS-PTM的优缺点。此外,还讨论了TSPTM的未来发展方向。这项综述旨在让读者全面了解TS-PTM,从早期的迁移学习方法到最近的基于转换和一致性的TS-PTM。主要贡献可概括如下:
我们根据所使用的预训练技术,对现有的TS-PTM进行了分类和全面审查。我们进行了大量的实验来分析TS-PTM的优缺点。对于时间序列分类,我们发现基于迁移学习的TS-PTM在UCR时间序列数据集(包含许多小数据集)上表现不佳,但在其他公开可用的大时间序列数据集中表现优异。对于时间序列预测和异常检测,我们发现设计一种合适的基于Transformer的预训练技术应该是未来TS-PTM研究的重点。我们分析了现有TS-PTM的局限性,并在(i)数据集、(ii)Transformer、(iii)固有特性、(iv)对抗性攻击和(v)噪声标签下提出了潜在的未来方向。 本文的其余部分组织如下。第2节提供了TS-PTM的背景。第3节对TS-PTM进行了全面审查。第4节介绍了各种TS-PTM的实验。第5节提出了一些未来的方向。最后,我们在第6节中总结了我们的发现。
#include<iostream>
using namespace std;
int main()
{
int x = 0, n, m = 0, c = 0;
for(int x = 1; x <= 12; x ++)
{
cin >> n;
m = m + 300 - n;
c = c + m / 100;
m = m % 100;
if(m < 0)
{
cout << " - " << x;
return 0;
}
}
cout << m + 100 * c * 1.
【案例3-2】银行存取款
对于银行存取款的流程,人们非常熟悉,用户可在银行对自己的资金账户进行存款、取款、查询余额等操作,极大地方便了人们对资金的管理。
本案例要求使用所学的知识编写一个程序,实现银行存取款功能。案例要求具体如下:
(1)创建账户,初始存款为500元。
(2)向账户存入1000元。
(3)从账户取出800元。
ps:这个案例并不难,就是练习构造方法。
/** * ZAY 2023.7.19 */ import java.util.Scanner; public class Example09 { public static void main(String[] args) { Scanner sc = new Scanner(System.in); for (int i = 0; i < 100; i++){ User.User(); Saving.Saving(); Withdraw.Withdraw(); System.out.println("是否继续处理"); String m = sc.next(); if (m.equals("是")) { } else { break; } } } } //定义创建账户类 class User { public static void User() { Scanner sc = new Scanner(System.
1. HTTPS是一种安全的网络传输协议,用于在客户端和服务器之间加密数据传输,以保护敏感信息不被窃取或篡改。它是基于HTTP协议的,因此也被称为HTTP over TLS或HTTP over SSL。在使用RESTful API时,如果API要求传输敏感信息(如用户密码、信用卡号等),建议使用HTTPS来保护通信安全。
2. RESTful API是一种基于HTTP协议设计的Web服务接口,它使用HTTP请求方法(如GET、POST、PUT、DELETE)来访问和操作资源。它通常使用JSON或XML格式的数据进行交互。RESTful API本身并不依赖于任何特定的传输协议,但由于HTTP协议具有广泛的应用和支持,因此RESTful API通常使用HTTP协议进行通信。RESTful API可以用于实现不同类型的应用程序之间的数据交互,例如Web应用程序、移动应用程序、IoT设备等。
3. CGI是一种Web服务器与外部应用程序(如脚本)交互的标准接口。通过CGI,Web服务器可以将HTTP请求传递给外部应用程序进行处理,并将处理结果返回给客户端。CGI可以被用于处理RESTful API中的某些请求,例如对于某些复杂的请求,需要在后端进行一些数据处理或计算,这时可以使用CGI来调用相应的脚本或程序进行处理。
综上所述,HTTPS、RESTful API和CGI三者之间存在一定的关联,但它们各自的作用和功能是不同的。在实际应用中,可以使用HTTPS来保护RESTful API的通信安全,而CGI可以用于处理RESTful API中的某些请求。
在腾讯会议中,XMPP、CGI和REST API是三种不同的通信协议或接口,它们具有以下区别:
XMPP(Extensible Messaging and Presence Protocol):XMPP是一种开放标准的实时通信协议,用于即时消息传递和在线状态管理。它是一种基于XML的协议,旨在支持实时通信和即时消息传递。在腾讯会议中,XMPP协议用于处理会议中的即时消息、在线状态和一些基本的会议操作。
CGI(Common Gateway Interface):CGI是一种用于在服务器上执行脚本和处理请求的标准接口。在腾讯会议中,CGI通常用于处理一些与会议相关的服务器端操作,例如创建会议、管理会议室、获取会议信息等。CGI接口可以接收来自客户端的请求,并将其传递给服务器端的脚本进行处理。
REST API(Representational State Transfer Application Programming Interface):REST API是一种基于HTTP协议的软件架构风格,用于构建分布式系统和网络应用程序的接口。在腾讯会议中,REST API用于提供一组规范的HTTP请求和响应方式,以便开发人员可以通过发送HTTP请求来执行各种会议操作,例如创建会议、邀请参会人员、获取会议录制等。
总结:
XMPP用于处理即时消息和在线状态。CGI用于处理服务器端的会议操作。REST API用于通过HTTP请求执行各种会议操作。
1.背景
后台利用socket.io发送websocket消息,加密用到protobuf
2.反序列化时遇到问题
Traceback (most recent call last):
File "D:/locust/Nigeria/test3.py", line 40, in <module>
play.ParseFromString(decode_spin_str)
google.protobuf.message.DecodeError: Error parsing message
3.问题分析
手动自己序列化一个同样字段的值,做比较:
发现问题:
数据开头多了一个\x04
4.问题原因:socket.io 的协议,会固定写一个字节 ’04’ 到消息头部
5.去掉方法:aaa[1:]
现代前端项目开发中依赖管理已经是不可或缺的一环,然后由于各种问题,如历史原因、项目缺少维护等,前端项目在依赖管理中会遇到非常多的问题。本篇文章讨论其中一种,当 npm install 时遇到报错 ERESOLVE unable to resolve dependency tree 的问题原因以及如何解决。
报错信息 在一个安装了 react@18.2.0 的项目中安装依赖 ali-react-table,就会出现以下错误。仔细阅读错误原因可以得知,ali-react-table 中使用 peerDependencies 定义了依赖于react@"^16.8.0 || ^17.0.1" 项目,和我们项目中的 React 版本号冲突了。虽然这里是因为 ali-react-table 已经疏于维护并没有更新依赖版本信息,但是我们对第三方依赖的可控性是比较低的,除了等待第三方依赖更新或者提 PR 等待合并之后发版,我们还有一些其他方法可以暂时解决这个问题。
npm ERR! code ERESOLVE npm ERR! ERESOLVE unable to resolve dependency tree npm ERR! npm ERR! While resolving: vite-project@0.0.0 npm ERR! Found: react@18.2.0 npm ERR! node_modules/react npm ERR! react@"^18.2.0" from the root project npm ERR! npm ERR! Could not resolve dependency: npm ERR!
为什么需要 i18n? 英语是世界上使用最广泛的语言,但只有七分之一的人会说英语。它是 3.79 亿人的第一(母语)语言,但有 9.17 亿人说中文普通话,4.6 亿人说西班牙语,3.41 亿人说印地语。
在互联网呈指数级增长的新兴市场,存在大量非英语用户。如果你的网站可以在全球范围内进行翻译,那么你的潜在目标市场可能会增加 700%!
i18n 全称 Internationalization,也就是国际化的意思,因为单词太长,所以中间的 18 个字母被缩写为 18,再加上开头和结尾的字母,就组成了 i18n。
JavaScript i18n API 可以帮助我们对网站进行多语言翻译,让它们可以轻松适应使用不同语言用户的需求。
在本文中,我将介绍 i18n API 提供的各种方法,以及如何在实际项目中实现 i18n 来覆盖更广泛、更国际化的用户。
i18n 其实很难 从上面的描述中,i18n 看起来很容易,但是当你尝试去做的时候,又发现它并不简单。
基于拉丁语的语言可能表面上相似。比如,请求姓名、电子邮件和日期的表单翻译如下:
英语nameemaildate西班牙语nombreemailfecha法语nome-maildate德语nameemaildatum Gettext 是一种在类 Unix 计算机操作系统上实现国际化和本地化程序的系统,它已经存在了几十年,而且这个库可以用在大多数编程语言中,在 nodejs 也可用。
在最简单的场景下,我们可以使用某种形式的标记来实现它。比如下面这段 HTML 模板:
<label for="name">{{ NAME }}</label> 当用户将英语设置为主要语言时,NAME 会被动态替换。
但是只是最简单的案例,实际情况中会有很多问题:
1.同一种语言可以有不同的变体。在西班牙使用的西班牙语与在南美洲使用的西班牙语不同。
2.一种语言中的单词在其他语言中可能会更长。例如,“电子邮件”在俄语中翻译为“электронное письмо”。
3.文本并不总是从左到右。有些语言是从右向左书写的,例如阿拉伯语、希伯来语、库尔德语和意第绪语。也有一些语言是可以从上到下书写的,比如中文、韩文、日文和闽南文。
更糟糕的问题 除了上面提到的问题,还有更糟糕的情况。
当我们需要显示日期、时间、数字、货币或单位时,会出现进一步的复杂问题。
在英文中显示其日,通常是 12/03/24 这种格式。但是在其他语言中:
使用 MDY 格式的美国居民会使用 3 December 2024。使用 DMY 格式的欧洲、南美和亚洲居民会使用 12 March 2024加拿大、中国、日本和匈牙利居民会使用 2012 年 3 月 24 日,他们选择了实用得多的 YMD 格式。 英文中的数字 1,000,在其他语言中:
在Vue中,===和==都是用于比较两个值的运算符,但它们之间存在一些区别。
===(严格相等)运算符比较两个值的类型和值是否完全相等。如果两个值的类型或值有任何不同,它将返回false。==(相等)运算符比较两个值的类型和值是否相等。它在比较之前会先尝试进行类型转换。如果两个值的类型相同,则直接根据值的相等性来判断。如果两个值的类型不同,则会尝试将其中一个值转换为与另一个值相同的类型,然后再进行比较。 举个例子来说,假设有以下代码:
const a = 5; const b = '5'; console.log(a === b); // false console.log(a == b); // true 在这个例子中,a和b的类型不同,a是一个数字,b是一个字符串。使用===运算符进行比较时,由于类型不同,它返回了false。而使用==运算符进行比较时,它会尝试将b转换为数字,然后发现它们的值相等,所以返回了true。
在实际开发中,建议使用===运算符来进行严格的比较,因为它可以避免一些隐式的类型转换,帮助我们准确判断值是否相等。
1. 查看设备
1
cat /proc/devices
2.查看设备具体号
1
cat /dev/ttyS +[table键]
3. 监听串口
如:(选择想要监听的号)
1
cat /dev/ttyS0
4. 开两个终端:
一个cat /dev/ttyS接收
另一个echo “字符” >/dev/ttyS发送数据 1
cat /proc/tty/driver/serial 查看串口中断 测试自己可以将TX RX短接。
查看串口状态:
1
cat /proc/tty/driver/serial
5、查看串口(/dev/ttyS0)当前的参数,包括波特率、数据位等。
1
stty -F /dev/ttyS0 -a
6、stty设置串口参数
1
stty -F /dev/ttyS0 ispeed 115200 ospeed 115200 cs8
使用以上命令行,可以查看当前设备下的串口设备。一般硬件的com1对应ttyS0。但是还需要与外部通讯,发送测试指令来验证是否正确。
串口调试时,打开串口时,需要给串口设置好权限。
临时打开串口权限 sudo chmod 666 /dev/ttyS0 该方法只能临时添加访问权限,一次性的,下次拔插串口线或者开关机还需要再次赋予串口权限。
永久打开串口权限 首先查看用户组
ls -l /dev/ttyS0 终端输出:
crw-rw---- 1 root dialout 4, 65 12月 19 2020 /dev/ttyS0 可以看到用户 root ,所属用户组为 dialout, 因此一种方法是把我们的当前用户名 加入到这个用户组。
目录 一、准备工作1.1 安装或关闭以下服务1.2 本次安装环境 2、主数据库配置2.1主数据库配置2.2创建用户2.3查看信息 三、从主数据库配置3.1从数据库配置3.2连接主服务器3.3测试 4、其他4.1连接完毕后发现Slave_IO_Running值异常,4.2报错`Error connecting to source 'test@192.168.1.10:3306'. This was attempt 2/86400, with a delay of 60 seconds between attempts. Message: Authentication plugin 'caching_sha2_password' reported error: Authentication requires secure connection.`4.3报错`Coordinator stopped because there were error(s) in the worker(s). The most recent failure being: Worker 1 failed executing transaction 'ANONYMOUS' at source log mysql-bin.000003, end_log_pos 1789. See error log and/or performance_schema.replication_applier_status_by_worker table for more details about this failure or others, if any.
在做网络编程时,很多程序猿都会使用Apache的HttpClient,也有很多大佬自己封装HttpURLConnection,但是笔者认为最强的,还是大名鼎鼎的OkHttp。
源码地址:https://github.com/square/okhttp
使用方法:参照这位老铁的博客,写的非常详细。
https://blog.csdn.net/tanga842428/article/details/78713089
客户端使用可以使用单例模式:
https://blog.csdn.net/weixin_40281743/article/details/85330193
注意一点:maven导入依赖时,建议排除安卓的依赖。
<dependency> <groupId>com.squareup.okhttp3</groupId> <artifactId>okhttp</artifactId> <version>3.11.0</version> <exclusions> <exclusion> <groupId>com.google.android</groupId> <artifactId>android</artifactId> </exclusion> </exclusions> </dependency> 另外:设置超时与超时异常处理:
https://blog.csdn.net/do168/article/details/51848895
okhttp使用完后需要关闭流,释放资源吗?
https://juejin.im/post/5a524eef518825732c536025
OKHttp官方推荐使用单例模式创建client,简单的封装一个工具类
public class HttpUtil { private static final Logger logger = LoggerFactory.getLogger(HttpUtil.class); private static OkHttpClient client; private static final String DEFAULT_MEDIA_TYPE = "application/json; charset=utf-8"; private static final int CONNECT_TIMEOUT = 5; private static final int READ_TIMEOUT = 7; private static final String GET = "GET"; private static final String POST = "
1、build中版本号为30及以上时,aidl无效,解决方案 ①在客户端的manifest.xml中添加一下代码,其中代码中的包名为服务端的包名 <manifest> ... <application> .... </application> <queries > <package android:name="com.example.clientapplication"/> <intent> <action android:name="android.intent.action.MService"/> </intent> </queries> </manifest> ②修改build中的版本号 2、打开aidl中服务端的服务service出现闪退的问题 Caused by: java.lang.RuntimeException: Didn't create service "XXX" on path: DexPathList[[zip file "/data/app/com.chemao.certification-2/base.apk"], nativeLibraryDirectories=[/data/app/com.chemao.certification-2/lib/arm, /vendor/lib, /system/lib]] 方法:service的位置放错了,service应该放在java目录下。 aidl中服务端的目录结果如下所示: 3、跨进程通信aidl最简单的方法 ①服务端 (1)AS切换模式为project,对main右键创建aidl文件,如下图: (2)在创建的文件中定义想实现的接口 (3)build projection 如果rebuild出现问题的话,可以先clean projection (4)创建类继承service,在service中创建内部类实现aidl中定义的接口数据,在java目录下创建,不要在aidl中进行创建,不然后续会出现问题。 public class MService extends Service { private IAidlInterface mBinder; @Nullable @Override public IBinder onBind(Intent intent) { Log.d("TAG", "onBind: " + intent); return mBinder.asBinder(); } @Override public void onCreate() { super.
文章目录 再谈谈RPC的理解RPC的发展史RPC历经数十年而不衰的原因?1、分布式系统的需求2、RPC相关技术的演进3、多语言的支持 本文源自一次面试官的提问:说说你对于RPC框架的了解,你知道哪些RPC框架,以及为什么RPC历经几十年还能不断推出新的框架。 我觉得这个问题很有意思。在IT界RPC真的是一个“奇葩”,奇葩在每过一段时间都会有新的RPC框架出现,网络上仍然在不断争论哪个RPC框架更好,而这些RPC框架还有很多还是大厂的杰作,大厂们仿佛乐此不疲。
要知道RPC的历史可以追溯到1990年代初期,那时候“开放软件基金会”(Open Software Foundation,OSF)和业界主流的计算机厂商一期指定了名为分布式计算环境(Distributed Computing Environment)的分布式技术体系,当时就定出了一个远程服务调用的规范(Remote Procedure Call,RPC),这个规定被称为DCE/RPC,后来Sun公司又开发出来一个ONC RPC,在这个时期基本上确定了RPC的很多概念和技术关注点,其中有很多解决思路,即使到了今天仍然有巨大的借鉴意义。
和RPC同期的很多技术或者框架很多都已经淹没在历史之中了,连当初盛极一时的EJB,现在已经几乎没人使用了,但是RPC却焕发了新的活力。
为什么历经三十多年,RPC还能不断推陈出新,被抽推崇呢?我认真思考这个问题的原因,有了一些不知是否成熟的想法,于是便记录下来。
再谈谈RPC的理解 RPC(Remote Procedure Call,远程过程调用),是一种通信协议,用于不同计算机之间的远程通信。它允许应用程序通过网络调用远程计算机上的服务或函数,并获取返回结果。RPC隐藏了底层网络通信的细节,使得远程调用就像本地调用一样简单和透明。
在RPC中,通常有一个客户端和一个服务器端。客户端发起远程调用请求,服务器端接收请求并执行相应的操作,然后将结果返回给客户端。RPC可以跨越不同的编程语言和操作系统,使得分布式系统中的不同组件能够进行相互通信和协作。
RPC的实现通常包括以下关键组件:
**定义接口:**RPC通过定义接口描述远程服务的方法和参数,通常使用IDL(Interface Definition Language)来定义接口规范,例如使用Protocol Buffers、Thrift或gRPC等。**序列化与反序列化:**在远程调用过程中,需要将方法参数和返回值序列化为字节流进行传输,然后在对端进行反序列化。这样可以确保跨网络传输的数据能够被正确地重建和解析。**通信协议:**RPC使用不同的通信协议进行数据传输,如HTTP、TCP、UDP等。通信协议负责在客户端和服务器之间建立连接,并进行数据的可靠传输。**远程调用管理:**RPC框架通常提供远程调用的管理功能,包括请求的路由、负载均衡、故障恢复等。这些功能确保请求能够被正确地路由到相应的服务节点,并能够应对节点故障或网络中断的情况。**安全性和认证:**由于RPC涉及跨网络通信,安全性和认证是重要考虑因素。RPC框架通常提供身份验证、加密传输和访问控制等机制,以保护数据的机密性和完整性。 于是乎,你可以看到接口定义的方式可以不同、序列化和反序列化的机制可以不同、通信的协议可以不同、路由和安全方面的建设可以不同,这就给了各类RPC框架有非常大的想象空间,每个RPC框架都可以有自己独特的方面。
所以我们看到有各种各样我们所熟知的框架出现:
CORBA(Common Object Request Broker Architecture,OMG)Java RMI(Sun/Oracle)Thrift(Facebook/Apache)Dubbo(阿里巴巴/Apache)gRPC(Google)Motan1/2(新浪)Finagle(Twitter)brpc(百度/Apache).NET Remoting(微软)Arvo(Hadoop) 他们有的主要支持C++,有的主要支持Java,有的支持各类语言,有的以简单见长,有的则以性能取胜,各有特色。
要深入了解RPC,需要追溯一下RPC的发展史。
RPC的发展史 RPC的发展历史可以追溯到上世纪80年代,主要分为以下阶段:
早期阶段: 在早期阶段,RPC的概念开始出现并得到了实践。最早的RPC实现包括Sun Microsystems的NFS(Network File System)和Apollo Systems的NCS(Network Computing System),它们都是为了在分布式系统中实现远程调用而设计的,这个阶段是分布式技术的萌芽时期。基于传统协议的RPC出现: 随着网络技术的发展,RPC的概念开始在不同的领域得到应用。许多基于传统协议的RPC实现出现,如DCE RPC(Distributed Computing Environment RPC)和CORBA(Common Object Request Broker Architecture)。这些实现使用了自定义的IDL(Interface Definition Language)和协议,以实现跨平台、跨语言的远程调用,这个时期的RPC协议应用还不广泛,性能存在较大的问题。Web服务和SOAP: 随着Web的兴起,RPC的关注点逐渐转向Web服务。Web服务使用SOAP(Simple Object Access Protocol)作为通信协议,通过XML进行数据传输。SOAP基于HTTP和XML,使得跨网络的远程调用更加方便。SOAP提供了基于WSDL(Web Services Description Language)的接口定义和基于UDDI(Universal Description, Discovery, and Integration)的服务发现,SOAP可以认为是RPC的一种案例,这阶段还出现了XML-RPC,后来也渐渐淘汰了。REST和Web API时代: 随着Web的演进,基于REST(Representational State Transfer)的Web API成为了一种更简洁、轻量级的远程调用方式。RESTful API使用HTTP协议,通过URL和HTTP方法(如GET、POST、PUT、DELETE)来表达资源的操作。RESTful API的普及使得基于HTTP的RPC变得更加流行,并广泛应用于Web开发和移动应用程序。现代RPC框架: 进入21世纪,出现了许多现代化的RPC框架,如gRPC、Apache Thrift、Apache Dubbo等。这些框架提供了更高效、更强大的RPC能力,并支持多种编程语言和平台。它们通常采用二进制协议(如Protocol Buffers)和高性能的网络通信技术(如HTTP/2、TCP)来提升性能和效率。 随着技术的不断演进和需求的变化,RPC的发展也在不断推进,协议在变化,通信网络技术也在变化,发展到现代RPC框架则提供了更多的功能和特性,使得分布式系统的开发更加便捷和高效。
创建日期:2023年7月19日
是否解决:是
问题难度:简单
解决耗时:10min
一、遇见的问题 1.1 问题背景 尝试 eureka 多配置文件多次启动时移动了项目文件夹
1.2 问题描述 项目refactor 移动文件夹后,无法启动,提示 找不到或无法加载主类”
错误: 找不到或无法加载主类 priv.liuyp.eureka.EurekaServerApplication 原因: java.lang.ClassNotFoundException: priv.liuyp.eureka.EurekaServerApplication 二、问题分析 2.1 问题原因分析 找不到主类,就看看编译后的 class 路径是否正确 2.2 解决方向 IDEA的 project structure 中查看output路径是否正确clean maven 项目重新加载找到具体的编译后target 输出路径看看是否跟output配置的一致 三、问题解决 3.1 确定原因 **clean maven 项目重新加载 **
结果:无效
IDEA的 project structure 中查看output路径是否正确
结果:正确未修改,target 配置的路径是和 src平级的默认路径
找到具体的编译后target 输出路径看看是否跟output配置的一致
结果:target 文件路径仍是项目移动前的路径,说明有某处配置不对。
3.2 解决过程 没有发现其他地方仍配置移动前的路径在 idea 自动生成的的项目工程文件 xxxx.iml 发现了 target 路径仍旧是相依被移动之前的路径。删除iml文件,让idea重新载入后,项目成功启动
Game of Hyper Knights
1 seconds
64 MB
Medium Hard
LOJ-1315
English
A Hyper Knight is like a chess knight except it has some special moves that a regular knight cannot do. Alice and Bob are playing this game (you may wonder why they always play these games!). As always, they both alternate turns, play optimally and Alice starts first. For this game, there are 6 valid moves for a hyper knight, and they are shown in the following figure (circle shows the knight).
justify-content与justify-items与常用属性 justify-contentjustify-content的属性 justify-itemsjustify-items 的常见属性 align-itemsalign-items 常见属性 flex-directionflex-direction 常见属性 flex-wrapflex-wrap 常见属性 flex-flowalign-contentalign-content常见属性 justify-content 在CSS中,justify-content 是用于控制容器中的子元素在主轴上的对齐方式的属性。它必须是与display: flex;或display: inline-flex;属性结合使用时才有效。
display: flex;是一种用于创建弹性容器的CSS属性,它会将其子元素视为弹性项目,从而启用弹性布局。只有在使用弹性布局时,justify-content属性才会生效。
弹性布局(Flexbox)是一种现代的CSS布局模型,通过将容器分为主轴和交叉轴,使开发者能够更容易地对齐、分布和重新排列元素。justify-content属性用于控制主轴上的对齐方式,可使用不同的值来实现不同的布局效果,例如居中对齐、两端对齐、均匀分布等。
justify-content的属性 flex-start: 元素和容器的左端对齐。
flex-end: 元素和容器的右端对齐。
center: 元素在容器里居中。
space-between:元素之间保持相等的距离,容器的主轴上的空间会被均匀地分配给子元素
space-around:元素周围保持相等的距离。
justify-items justify-items 属性用于控制网格容器中的网格项目在其网格单元格中的水平对齐方式。
justify-items 的常见属性 start:将网格项目的内容对齐到网格单元格的起始位置。
end:将网格项目的内容对齐到网格单元格的末尾位置。
center:将网格项目的内容对齐到网格单元格的中间位置。
stretch:将网格项目的内容水平拉伸以填充整个网格单元格的宽度。
baseline:将网格项目的基线与网格单元格的基线对齐。
align-items align-items 是一个用于弹性容器的 CSS 属性,它控制容器中子元素在交叉轴上的对齐方式
align-items 常见属性 flex-start: 元素与容器的顶部对齐。
flex-end: 元素与容器的底部对齐。
center: 元素纵向居中。
baseline: 元素在容器的基线位置显示。
stretch: 元素被拉伸以填满整个容器。
flex-direction flex-direction 是一个用于弹性容器的 CSS 属性,它决定了容器中的子元素在主轴上的排列方向。
flex-direction 常见属性 row: 元素摆放的方向和文字方向一致。
row-reverse: 元素摆放的方向和文字方向相反。
column: 元素从上放到下。
column-reverse: 元素从下放到上。
一、先看效果图
二、背景介绍
图形验证码网上有挺多,比如:网易易盾、腾讯防水墙、阿里云验证码等等。参考了一下,自己实现了一个简单的成语点选的模式。
三、实现思路
1.选择若干张图片(这里使用的是320x160的尺寸),随机从中抽取一张作为背景图。
2.整理一个成语库,用作验证码里的字。
3.将选择的成语随机(位置随机,字体随机,颜色随机)绘制到背景图上,记录每个字的坐标范围,后面用于验证用户是否选择正确。
4.将成语及图片返回给前端。
5.前端点击后,将点击坐标点传回后端,后端进行验证。 四、实现代码
C# ASP.NET MVC版 1.后端生成验证码图片
using System; using System.Collections.Generic; using System.Drawing; using System.Drawing.Imaging; using System.Globalization; using System.IO; using System.Text.RegularExpressions; using System.Web; namespace RC.Framework { public class ValidateHelper { private static readonly Random Random = new Random(); #region 检测选中的位置是否为后台设置的文字位置(判断验证码输入是否有效) /// <summary> /// 检测选中的位置是否为后台设置的文字位置(判断验证码输入是否有效) /// </summary> /// <param name="input"></param> /// <param name="range"></param> /// <returns></returns> public static bool Validate(string input, string range) { if (input.
要求一:从源文件夹中定时转移文件到目标文件夹中,目标文件夹每天按照年月日生成。 @echo off :: 该脚本旨在将源文件夹中的内容移动到以日期时间戳命名的目标文件夹中。 :: 它将持续监视源文件夹以检测新文件,并定期将它们移动到目标文件夹。 :: 设置源文件夹 set "source_folder=C:\source\folder" :: 设置目标文件夹,以年月日生成的目标文件夹将放在destination_parent下 set "destination_parent=C:\destination\parent" :: 进入主循环。 :LOOP set "datestamp=%date:~0,4%%date:~5,2%%date:~8,2%" :: 检查源文件夹是否存在。如果不存在,则显示错误消息。 if not exist "%source_folder%" ( echo Source folder does not exist. exit /b ) :: 检查目标父文件夹是否存在。如果不存在,则显示错误消息并退出脚本。 if not exist "%destination_parent%" ( echo Destination parent folder does not exist. exit /b ) :: 如果目标文件夹不存在的话,创建目标文件夹,以指定的日期时间戳作为其名称。 set "destination_folder=%destination_parent%\%datestamp%" if not exist "%destination_folder%" ( mkdir "%destination_folder%" ) :: 通过尝试静默获取文件列表来检查源文件夹是否为空。 dir /b "
文章目录 硬件知识 LED 原理GPIO 引脚操作方法GPIO 模块一般结构GPIO 寄存器的一般操作 STM32MP157的GPIO操作方法先使能PLL4MPU、MCU共享GPIO模块1. 在MPU上使能某个GPIO模块2. 在MCU上使能某个GPIO模块 GPIO模块设置引脚工作模式:GPIO模式对于输出引脚:设置输出类型对于输出引脚:设置输出速度对于输入/输出引脚:设置上下拉电阻对于输入/输出引脚:读取引脚电平对于输出引脚:设置引脚电平,方法1对于输出引脚:设置引脚电平,方法2 STM32MP157的LED操作方法STM32MP157点亮LED灯led_drv.cledtest.cMakefile编译测试 硬件知识 LED 原理 LED 的驱动方式,常见的有四种。
① 使用引脚输出 3.3V 点亮 LED,输出 0V 熄灭 LED。② 使用引脚拉低到 0V 点亮 LED,输出 3.3V 熄灭 LED。③ 使用引脚输出 1.2V 点亮 LED,输出 0V 熄灭 LED。④ 使用引脚输出 0V 点亮 LED,输出 1.2V 熄灭 LED。 有的芯片为了省电等原因,其引脚驱动能力不足,这时可以使用三极管驱动(如方式3和4)。
由此,主芯片引脚输出高电平/低电平,即可改变 LED 状态,而无需关注GPIO 引脚输出的是 3.3V 还是 1.2V。所以简称输出 1 或 0:
GPIO 引脚操作方法 GPIO 模块一般结构 有多组 GPIO,每组有多个 GPIO使能:电源/时钟模式(Mode):引脚可用于 GPIO 或串口或其他功能方向:引脚 Mode 设置为 GPIO 时,可以继续设置它是输出引脚,还是输入引脚数值: 对于输出引脚,可以设置寄存器让它输出高、低电平对于输入引脚,可以读取寄存器得到引脚的当前电平 GPIO 寄存器的一般操作 芯片手册一般有相关章节,用来介绍:power/clock
思路: /* 模拟订单号生成 超市购物时,小票上都会有一个订单号,且订单号唯一 编写程序模拟订单系统中订单号的生成 生成订单号时,使用年月日和毫秒值组合生成唯一订单号 例如: 给一个包括年月日和毫秒值的数组arr[2023,0401,1100], 将其拼接成字符串s:202304011100,作为一个订单号 掌握String类中常用方法的使用 for循环、方法调用 1.先定义一个数组,存放年月日毫秒值 2.定义方法,将数组拼接成字符串,并保存 要实现数组转成一个字符串, 首先定义一个方法,实现数组拼接成字符串 参数类型为数组,返回值类型为String 可先使用String定义一个空串, 然后使用字符串的操作方法,在开始和最后加上[]字符, 之后,在加“[]”字符中间循环遍历数组,用开始定义的字符串接收 在方法中遍历数组,把每一个得到的字符拼接成一个字符串并返回 3.调用该方法,并定义一个字符串变量接收结果 4.输出控制台 */ 代码: 代码结构:
测试类:
package base.base015; /* 模拟订单号生成 超市购物时,小票上都会有一个订单号,且订单号唯一 编写程序模拟订单系统中订单号的生成 生成订单号时,使用年月日和毫秒值组合生成唯一订单号 例如: 给一个包括年月日和毫秒值的数组arr[2023,0401,1100], 将其拼接成字符串s:202304011100,作为一个订单号 掌握String类中常用方法的使用 for循环、方法调用 1.先定义一个数组,存放年月日毫秒值 2.定义方法,将数组拼接成字符串,并保存 要实现数组转成一个字符串, 首先定义一个方法,实现数组拼接成字符串 参数类型为数组,返回值类型为String 可先使用String定义一个空串, 然后使用字符串的操作方法,在开始和最后加上[]字符, 之后,在加“[]”字符中间循环遍历数组,用开始定义的字符串接收 在方法中遍历数组,把每一个得到的字符拼接成一个字符串并返回 3.调用该方法,并定义一个字符串变量接收结果 4.输出控制台 */ public class Test15 { public static void main(String[] args) { int[] arr = {2023,0401,1100}; String s = arrayToString(arr); System.out.println("订单号:"+s); } private static String arrayToString(int[] arr) { String str = "