Django有很多内置的模板过滤器,允许你修改模板中的变量。过滤器看起来{{variable|my_filter}}。 带参数的过滤器类似于{{variable|my_filter:"foo"}}。您可以对一个变量应用任意多的过滤器,例如,{{variable|filter1|filter2}},它们中的每一个都将应用于前面生成的输出。
创建一个自定义过滤器,以便能够在博客文章中使用markdown语法,然后在模板中将文章内容转换为HTML。
使用pip安装markdown模块
python -m pip install Markdown 编辑blog_tags.py
from django import template from django.utils.safestring import mark_safe import markdown register = template.Library() @register.filter(name='markdown') def markdown_format(text): return mark_safe(markdown.markdown(text)) blog_tags的代码在自定义模版标签时创建,更多内容请看
Django自定义模版标签-CSDN博客
为了避免函数名和markdown模块之间的冲突,我们将函数名命名为markdown_format,并将过滤器名命名为markdown,以便在模板中使用,例如{{variable|markdown}}。 Django会转义过滤器生成的HTML代码。使用Django提供的mark_safe函数将结果标记为模板中呈现的安全HTML。
📌t默认情况下,Django不会信任任何HTML代码,并且会在将其放入输出之前进行转义。唯一的例外是那些被标记为可安全转义的变量。
现在,在帖子列表和详细信息模板中加载模板标记模块。
在blog/post/list.html和blog/post/detail.html模板的顶部{% extends %}标签之后添加以下一行:
{% load blog_tags %}
编辑 post/detail.html模版
{{ post.body|linebreaks }}
替换为
{{ post.body|markdown }}
编辑post/list.html 模版
{{ post.body|truncatewords:30|linebreaks }}
替换为
{{ post.body|markdown|truncatewords_html:30 }}
📌truncatewords_html过滤器在一定数量的单词之后截断字符串,避免未关闭的HTML标记。
有关自定义过滤器更多信息,请查看如何编写自定义的模板标签和过滤器 | Django 文档 | Django (djangoproject.com)
前言 Kubernetes 可以理解成一个对计算、网络、存储等云计算资源的抽象后的标准 API 服务。几乎所有对 Kubernetes 的操作,不管是用 kubectl 命令行工具,还是在UI或者CD Pipeline 中,都相当于在调用其 REST API。很多人说 Kubernetes 复杂,除了其本身实现架构复杂以外,还有一个原因就是里面有二十多种原生资源的 API 学起来曲线比较陡。但不用担心,我们只要抓住本质 – 提供容器计算能力的平台,就能纲举目张,很容易快速理解。在 K8S 中,最重要也最基础的资源是 Pod,翻译一下就是“豆荚”,我们用下面这个最最基础的 Nginx 容器为例,搞清楚豆荚的一生,K8S 就懂了一半。大家也不需要研究 Kubernetes 怎么搭建,推荐用 OrbStack 在本地一键安装一套 Docker & K8S 环境出来,快速开始实验。首先,写一段这样的 Yaml 文件出来。
# nginx.yaml apiVersion: v1 kind: Pod metadata: name: nginx labels: app: nginx spec: containers: - name: web image: nginx ports: - name: web containerPort: 80 protocol: TCP 然后用 kubectl 将 nginx 的 Pod 进行创建,命令后面加 -v8 是详细日志模式,可以看出来 kubectl 到底做了什么事情。
目录
可比较的概念
基本数据类型的比较
复合数据类型的比较
不可比较类型的替代方案
比较操作的注意事项
小结
在日常开发中,比较操作是最常用的基本操作之一,可以用来判断变量之间是否相等或者对应的大小关系,比较操作对于排序、查找和集合数据结构的实现至关重要。在 Golang 中,不是所有的数据类型都是可比较的。理解哪些数据类型是可以进行比较的以及如何比较,对于编写健壮和高效的代码是非常重要的。本文将深入解析 Golang 中可比较的数据类型,并结合代码示例来说明如何在不同情况下进行比较。
可比较的概念 在 Golang 中,可比较的数据类型意味着该类型的两个值可以使用 == 和 != 运算符进行等值比较,一些类型还可以使用 < 、> 、<= 和 >= 进行大小比较。可比较性是类型的一个属性,决定了类型的值是否可以进行某些操作。
基本数据类型的比较 整型、浮点型和复数,各种整型(如 int8、int16、int32、int64及对应的无符号类型),浮点型(float32 和 float64)和复数(complex64 和 complex128)。这些类型都是可比较的,可以使用 == 和 != 来检查两个值是否相等或不等。除了复数外,其余的数值类型还可以使用 < 、> 、<= 和 >= 进行大小比较。字符串,字符串也是可比较的。可以使用 == 和 != 来判断两个字符串是否相等。字符串是基于字典序进行比较的,因此也可以使用 < 、> 、<= 和 >= 来比较大小。布尔型,布尔型(bool)的值只有 true 和 false。布尔值可以使用 == 和 != 进行比较,但不支持大小比较。 复合数据类型的比较 数组(array),数组是一个固定长度的序列,定义了序列中元素的类型和长度。只有当两个数组的元素类型都是可比较的并且相同、数组长度也相同的时候,这两个数组才是可比较的。数组间的比较是逐个元素进行的,一旦遇到不相等的元素则停止比较并返回结果。示例代码如下: package main import "fmt" func main() { var a [3]int = [3]int{1, 2, 3} var b [3]int = [3]int{1, 2, 3} var c [3]int = [3]int{1, 4, 3} fmt.
The concept: The long term aim of the project is to develop a fully functional software, known as DataViz, for plotting and processing datasets, which will be eventually deployed and released for all students in the department to use in their reports, data processing, and as a show case of an authentic experience of software development for the students of ELEC362. The development is planned over 5 years, which started in 2022.
1.先查看磁盘空间 df -h 2.找到容器的containerId-json.log文件,并清理 find /var/lib/docker/containers/ -name *-json.log |xargs du -sh 3、可以根据需求清理对应日志也可以清理数据大的日志 $ cat /dev/null > /var/lib/docker/containers/dbaee0746cc6adad3768b4ef2e25eff04f7a5ca29bbb185460ff5fb334ca28a6/dbaee0746cc6adad3768b4ef2e25eff04f7a5ca29bbb185460ff5fb334ca28a6-json.log 当然我们也可以尝试脚本化清理:
如果docker容器正在运行,那么使用rm -rf方式删除日志后,通过df -h会发现磁盘空间并没有释放。原因是在Linux或者Unix系统中,通过rm -rf或者文件管理器删除文件,将会从文件系统的目录结构上解除链接(unlink)。如果文件是被打开的(有一个进程正在使用),那么进程将仍然可以读取该文件,磁盘空间也一直被占用。正确姿势是cat /dev/null > *-json.log,当然你也可以通过rm -rf删除后重启docker。接下来,提供一个日志清理脚本clean_docker_log.sh,内容如下:
#!/bin/sh echo "======== start clean docker containers logs ========" logs=$(find /var/lib/docker/containers/ -name *-json.log) for log in $logs do echo "clean logs : $log" cat /dev/null > $log done echo "======== end clean docker containers logs ========" # chmod +x clean_docker_log.sh # ./clean_docker_log.sh 但是,这样清理之后,随着时间的推移,容器日志会像杂草一样,
我们来看下一段查询:
select * from sys_role;
如果我们要进行分页查询,例如每页显示两条数据,我们可以利用 limit 关键字:
select * from sys_role limit 0,2;
select * from sys_role limit 2,2; 假设我们当前页面为 n,每页显示的数据为 m;则用 limit 查询时有以下配置:
select * from sys_role limit (n-1)*m,m;
页面偏移量为 (n - 1) * m;每页显示的页数为 m
Kubernetes API 删除和弃用流程 Kubernetes 项目对功能有详细记录的弃用政策。此策略规定,只有当同一 API 的更新、稳定版本可用时,才可以弃用稳定的 API,并且每个稳定性级别的 API 都有最短生命周期。已弃用的 API 是已标记为在未来 Kubernetes 版本中删除的 API;它将继续运行,直到删除(从弃用起至少一年),但使用将导致显示警告。已删除的 API 在当前版本中不再可用,此时您必须迁移到使用替换版本。
普遍可用 (GA) 或稳定的 API 版本可能会被标记为已弃用,但不得在 Kubernetes 主要版本中删除。弃用后的 3 个版本必须支持 Beta 或预发布 API 版本。Alpha 或实验性 API 版本可能会在任何版本中删除,恕不另行通知。 无论 API 是由于某个功能从测试版升级到稳定版而被删除,还是因为该 API 根本没有成功,所有删除都符合此弃用政策。每当删除 API 时,都会在文档中传达迁移选项。
关于 k8s.gcr.io 重定向到registry.k8s.io 的说明 为了托管其容器映像,Kubernetes 项目使用社区拥有的映像注册表,称为registry.k8s.io。从去年 3 月开始,旧 k8s.gcr.io 注册表的流量开始被重定向到registry.k8s.io。已弃用的 k8s.gcr.io 注册表最终将被淘汰。
关于 Kubernetes 社区拥有的包存储库的说明 2023 年初,Kubernetes 项目 pkgs.k8s.io社区拥有的 Debian 和 RPM 软件包软件存储库。社区拥有的存储库取代了 Google 拥有的旧存储库(apt.kubernetes.io和yum.kubernetes.io)。2023 年 9 月 13 日,这些遗留存储库被正式弃用,其内容被冻结。
当用户向 Kubernetes 提交了一个创建 deployment 的请求后,Kubernetes 从接收请求直至创建对应的 pod 运行这整个过程中都发生了什么呢?
kubernetes 架构简述 在搞清楚从 deployment 提交到 pod 运行整个过程之前,我们有先来看看 Kubernetes 的集群架构:
上图与下图相同:
如图所示,k8s 集群分为 control plane 控制平面和 node 节点。control plane 控制平面(也称之为主节点)主要包含以下组件:
kube-api-server: 顾名思义,负责处理所有 api,包括客户端以及集群内部组件的请求。
etcd: 分布式持久化存储、事件订阅通知。只有 kube-api-server 直接操作 etcd,其它所有组件都是与 kube-api-server 进行相互。
scheduler: 处理 pod 的调度,将 pod 绑定到具体的 node 节点。
controller manager: 控制器,处理各种资源对象。
cloud controller manager: 对接云服务商的控制器。
node 节点,专门部署用户的应用程序(与控制平面隔离,避免影响到 k8s 的核心组件),主要包含以下组件:
kubelet: 管理节点上的 pod 以及状态检查和上报。
kube-proxy: 进行流量的路由转发(目前是通过操作节点的 iptables 或者 ipvs 实现)。
CRI: 容器运行时接口。
从 Deployment 到 Pod 从 Deployment 到 Pod 的整个过程如下图所示:
分布式Dubbo+Zookeeper 1、分布式理论 1)什么是分布式系统? 在《分布式系统原理与范型》一书中有如下定义:“分布式系统是若干独立计算机的集合,这些计算机对于用户来说就像单个相关系统”;
分布式系统是由一组通过网络进行通信、为了完成共同的任务而协调工作的计算机节点组成的系统。分布式系统的出现是为了用廉价的、普通的机器完成单个计算机无法完成的计算、存储任务。其目的是利用更多的机器,处理更多的数据。
分布式系统(distributed system)是建立在网络之上的软件系统。
首先需要明确的是,只有当单个节点的处理能力无法满足日益增长的计算、存储任务的时候,且硬件的提升(加内存、加磁盘、使用更好的CPU)高昂到得不偿失的时候,应用程序也不能进一步优化的时候,我们才需要考虑分布式系统。因为,分布式系统要解决的问题本身就是和单机系统一样的,而由于分布式系统多节点、通过网络通信的拓扑结构,会引入很多单机系统没有的问题,为了解决这些问题又会引入更多的机制、协议,带来更多的问题。。。
2)Dubbo文档 随着互联网的发展,网站应用的规模不断扩大,常规的垂直应用架构已无法应对,分布式服务架构以及流动计算架构势在必行,急需一个治理系统确保架构有条不紊的演进。
在Dubbo的官网文档有这样一张图
①单一应用架构 当网站流量很小时,只需一个应用,将所有功能都部署在一起,以减少部署节点和成本。此时,用于简化增删改查工作量的数据访问框架(ORM)是关键。
适用于小型网站,小型管理系统,将所有功能都部署到一个功能里,简单易用。
缺点:
1、性能扩展比较难
2、协同开发问题
3、不利于升级维护
②垂直应用架构 当访问量逐渐增大,单一应用增加机器带来的加速度越来越小,将应用拆成互不相干的几个应用,以提升效率。此时,用于加速前端页面开发的Web框架(MVC)是关键。
通过切分业务来实现各个模块独立部署,降低了维护和部署的难度,团队各司其职更易管理,性能扩展也更方便,更有针对性。
缺点:公用模块无法重复利用,开发性的浪费
③分布式服务架构 当垂直应用越来越多,应用之间交互不可避免,将核心业务抽取出来,作为独立的服务,逐渐形成稳定的服务中心,使前端应用能更快速的响应多变的市场需求。此时,用于提高业务复用及整合的**分布式服务框架(RPC)**是关键。
④流动计算架构 当服务越来越多,容量的评估,小服务资源的浪费等问题逐渐显现,此时需增加一个调度中心基于访问压力实时管理集群容量,提高集群利用率。此时,用于提高机器利用率的资源调度和治理中心(SOA)[ Service Oriented Architecture]是关键。
2、RPC RPC【Remote Procedure Call】是指远程过程调用,是一种进程间通信方式,他是一种技术的思想,而不是规范。它允许程序调用另一个地址空间(通常是共享网络的另一台机器上)的过程或函数,而不用程序员显式编码这个远程调用的细节。即程序员无论是调用本地的还是远程的函数,本质上编写的调用代码基本相同。
也就是说两台服务器A,B,一个应用部署在A服务器上,想要调用B服务器上应用提供的函数/方法,由于不在一个内存空间,不能直接调用,需要通过网络来表达调用的语义和传达调用的数据。为什么要用RPC呢?就是无法在一个进程内,甚至一个计算机内通过本地调用的方式完成的需求,比如不同的系统间的通讯,甚至不同的组织间的通讯,由于计算能力需要横向扩展,需要在多台机器组成的集群上部署应用。RPC就是要像调用本地的函数一样去调远程函数;
1)RPC基本原理 步骤解析:
RPC两个核心模块:通讯,序列化。
3、测试环境搭建 1)Dubbo Apache Dubbo |ˈdʌbəʊ| 是一款高性能、轻量级的开源Java RPC框架,它提供了三大核心能力:面向接口的远程方法调用,智能容错和负载均衡,以及服务自动注册和发现。
dubbo官网 http://dubbo.apache.org/zh-cn/index.html
1.了解Dubbo的特性
2.查看官方文档
dubbo基本概念
服务提供者(Provider):暴露服务的服务提供方,服务提供者在启动时,向注册中心注册自己提供的服务。
服务消费者(Consumer):调用远程服务的服务消费方,服务消费者在启动时,向注册中心订阅自己所需的服务,服务消费者,从提供者地址列表中,基于软负载均衡算法,选一台提供者进行调用,如果调用失败,再选另一台调用。
注册中心(Registry):注册中心返回服务提供者地址列表给消费者,如果有变更,注册中心将基于长连接推送变更数据给消费者
监控中心(Monitor):服务消费者和提供者,在内存中累计调用次数和调用时间,定时每分钟发送一次统计数据到监控中心
调用关系说明
l 服务容器负责启动,加载,运行服务提供者。
l 服务提供者在启动时,向注册中心注册自己提供的服务。
l 服务消费者在启动时,向注册中心订阅自己所需的服务。
l 注册中心返回服务提供者地址列表给消费者,如果有变更,注册中心将基于长连接推送变更数据给消费者。
l 服务消费者,从提供者地址列表中,基于软负载均衡算法,选一台提供者进行调用,如果调用失败,再选另一台调用。
l 服务消费者和提供者,在内存中累计调用次数和调用时间,定时每分钟发送一次统计数据到监控中心。
2)Dubbo环境搭建 点进dubbo官方文档,推荐我们使用Zookeeper 注册中心
代码层结构 根目录:com.zhangziwa.practisesvr
启动类:com.zhangziwa.practisesvr.PractisesvrApplication
实体类:com.zhangziwa.practisesvr.model
数据传输对象(dto):com.zhangziwa.practisesvr.dto
视图包装对象(vo)推荐:com.zhangziwa.practisesvr.vo
数据接口访问层(Dao):com.zhangziwa.practisesvr.mapper
数据服务接口层(Service):com.zhangziwa.practisesvr.service
数据服务实现层(Service Implements):com.zhangziwa.practisesvr.serviceImpl
前端控制器层(Controller):com.zhangziwa.practisesvr.controller
工具类库(utils):com.zhangziwa.practisesvr.utils
配置类(config):com.zhangziwa.practisesvr.config
Bean分类 Dodel:数据库表对应的实体。
Dto:数据传输对象(Data Transfer Object)用于封装多个 实体类 之间的关系。
Vo:视图包装对象(View Object)用于封装客户端请求的数据,防止部分数据泄露(如:管理员ID),保证数据安全,不破坏原有的实体类结构。
资源目录结构 根目录:src/main/resources
项目配置文件:src/main/resources/application.yml
静态资源目录:src/main/resources/static : 用于存放html、css、js、图片等资源
视图模板目录:src/main/resources/templates :用于存放jsp、thymeleaf等模板文件
mybatis映射文件:src/main/resources/mapper(mybatis项目)
mybatis配置文件:src/main/resources/mapper/config(mybatis项目)
项目目录示例 idea 以文本形式输出 SpringBoot项目 目录结构
──src ├─main │ ├─java │ │ └─com │ │ └─zhangziwa │ │ └─practisesvr │ │ ├─config │ │ ├─controller │ │ ├─dto │ │ ├─excuter │ │ ├─mapper │ │ ├─model │ │ ├─service │ │ ├─serviceImpl │ │ ├─utils │ │ └─vo │ └─resources │ ├─mapper │ │ └─config │ ├─static │ └─templates 参考 Spring Boot项目目录结构
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档> 学习的最大理由是想摆脱平庸,早一天就多一份人生的精彩;迟一天就多一天平庸的困扰。各位小伙伴,如果您:
想系统/深入学习某技术知识点…
一个人摸索学习很难坚持,想组团高效学习…
想写博客但无从下手,急需写作干货注入能量…
热爱写作,愿意让自己成为更好的人…
文章目录 前言一、概述二、结构三、案例实现四、组合模式的分类五、优点六、使用场景总结 前言 一、概述
二、结构
三、案例实现
四、组合模式的分类
五、优点
六、使用场景
一、概述 对于这个图片肯定会非常熟悉,上图我们可以看做是一个文件系统,对于这样的结构我们称之为树形结构。在树形结构中可以通过调用某个方法来遍历整个树,当我们找到某个叶子节点后,就可以对叶子节点进行相关的操作。可以将这颗树理解成一个大的容器,容器里面包含很多的成员对象,这些成员对象即可是容器对象也可以是叶子对象。但是由于容器对象和叶子对象在功能上面的区别,使得我们在使用的过程中必须要区分容器对象和叶子对象,但是这样就会给客户带来不必要的麻烦,作为客户而已,它始终希望能够一致的对待容器对象和叶子对象。
定义:
又名部分整体模式,是用于把一组相似的对象当作一个单一的对象。组合模式依据树形结构来组合对象,用来表示部分以及整体层次。这种类型的设计模式属于结构型模式,它创建了对象组的树形结构。
二、结构 组合模式主要包含三种角色:
抽象根节点(Component):定义系统各层次对象的共有方法和属性,可以预先定义一些默认行为和属性。树枝节点(Composite):定义树枝节点的行为,存储子节点,组合树枝节点和叶子节点形成一个树形结构。叶子节点(Leaf):叶子节点对象,其下再无分支,是系统层次遍历的最小单位。 三、案例实现 【例】软件菜单
如下图,我们在访问别的一些管理系统时,经常可以看到类似的菜单。一个菜单可以包含菜单项(菜单项是指不再包含其他内容的菜单条目),也可以包含带有其他菜单项的菜单,因此使用组合模式描述菜单就很恰当,我们的需求是针对一个菜单,打印出其包含的所有菜单以及菜单项的名称。
要实现该案例,我们先画出类图:
代码实现:
不管是菜单还是菜单项,都应该继承自统一的接口,这里姑且将这个统一的接口称为菜单组件。
//菜单组件 不管是菜单还是菜单项,都应该继承该类 public abstract class MenuComponent { protected String name; protected int level; //添加子菜单 public void add(MenuComponent menuComponent){ throw new UnsupportedOperationException(); } //移除子菜单 public void remove(MenuComponent menuComponent){ throw new UnsupportedOperationException(); } //获取指定的子菜单 public MenuComponent getChild(int i){ throw new UnsupportedOperationException(); } //获取菜单或菜单项的名称 public String getName(){ return name; } //打印菜单名称的方法(包含子菜单和子菜单项) public void print(){ throw new UnsupportedOperationException(); } } 这里的MenuComponent定义为抽象类,加粗样式因为有一些共有的属性和行为要在该类中实现,Menu和MenuItem类就可以只覆盖自己感兴趣的方法,而不用搭理不需要或者不感兴趣的方法,举例来说,Menu类可以包含子菜单,因此需要覆盖add()、remove()、getChild()方法,但是MenuItem就不应该有这些方法。这里给出的默认实现是抛出异常,你也可以根据自己的需要改写默认实现。
3.1 数据库核心:数据结构
数据库只需做两件事情:向它插入数据肘,它就保存数据:之后查询时,它应该返回那些数据。
本章我们主要从数据库的角度再来探讨同样的问题,即如何存储输入的数据,井在收到查询请求时,怎样重新找到数据.
了解存储引擎的底层机制。
存储引擎用于大家比较熟悉的两种数据库,即传统的关系数据库和大多数所谓的NoSQL数据库。我们将研究两个存储引擎家族,即日志结构的存储引擎和面向页的存储引擎,比如B-tree 。
一、数据结构
世界上最简单的数据库,它由两个Bash函数实现:
echo ” $1,$2”> database
grep “^$1,” database| sed -e "s/^$1", //" | tail -n 1
这两个函数实现了一个key-value存储。当调用 db_set key value ,它将在数据库中保存你所输入的 key和value.
调用 db_get key ,它会查找与输入 key相关联的最新值并返回。
它底层的存储格式其实非常简单:一个纯文本文件。其中每行包含一个key-value对,用逗号分隔(大致像一个csv文件,忽略转义问题)。每次调用db set 即追加新内容到文件末尾,因此,如果多次更新某个键,旧版本的值不会被覆盖,而是需要查看文件中最后一次出现的键来找到最新的值(因此在db_get中使用tail-n1)。
对于简单的情况,追加到文件尾部方式通常足够高效。与db_set相似,许多数据库内部都使用日志( lo g ),日志是一个仅支持追加式更新的数据文件。
虽然真正的数据库有很多更为复杂问题需要考虑(例如并发控制、回收磁盘空间以控制日志文件大小、处理错误和部分完成写记录等),但是基本的原理是相同的。
每次想查找一个键,db_get必须从头到尾扫描整个数据库文件来查找键的出现位置。在算能术语中,查找的开销是 O(n )。为了高效地查找数据库中特定键的值,需要新的数据结构:索引。背后的基本想怯都是保留一些额外的元数据,这些元数据作为路标,帮助定位想要的数据。
索引是基于原始数据报生而来的额外数据结构。很多数据库允许单独添加和删除索引,而不影响数据库的内容,它只会影响查询性能。维护额外的结构势必会引入开销,特别是在新数据写入时。对于写人,它很难超过简单地追加文件方式的性能,因为那已经是最简单的写操作了。由于每次写数据时,需要更新索引,因此任何类型的索引通常都会降低写的速度。
涉及存储系统中重要的权衡设计:适当的索引可以加速读取查询,但每个索引者ll会减慢写速度。
1.1 哈希索引
以键-值数据的索引开始。key-value类型并不是唯一可以索引的数据,但它随处可见,而且是其他更复杂索引的基础构造模块。key - value存储与大 多数编程语言所内置的字典结构非常相似,通常采用 hash map (或者 hash table ,哈希表)来实现。
既然已经有了内存数据结构的 hash map ,为什么不用它们在磁盘上直接索引数据呢?
假设数据存储全部采用追加式文件组成,如之前的例子所示 。 那么最简单的索引策略就是 : 保存内存中的 hash map ,把每个键一一映射到数据文件中特定的字节偏移量 ,这样就可以找到每个值的位置。
常见的跨域解决方案有以下几种:
JSONP:通过动态创建<script>标签来实现跨域请求,但只支持 GET 请求。
CORS(Cross-Origin Resource Sharing):在服务器端设置响应头,授权特定的域名访问资源。
代理服务器:在同一个域名下设置一个代理服务器,然后由代理服务器请求目标服务器,再将结果返回给前端。
Nginx 反向代理:通过配置 Nginx 反向代理服务器,将请求转发到目标服务器,绕过浏览器的同源策略。
WebSocket:使用 WebSocket 进行双向通信,WebSocket 不受同源策略的限制。
iframe 嵌套:将目标页面嵌套到一个 iframe 中,通过 postMessage 方法进行通信。
以上方法根据不同的场景和需求选择合适的方式来解决跨域问题。
第二部分、线性表详解:数据结构线性表10分钟入门 线性表,数据结构中最简单的一种存储结构,专门用于存储逻辑关系为"一对一"的数据。
线性表,基于数据在实际物理空间中的存储状态,又可细分为顺序表(顺序存储结构)和链表(链式存储结构)。
本章还会讲解顺序表和链表的结合体——静态链表,不仅如此,还会涉及循环链表、双向链表、双向循环链表等链式存储结构。
十七、如何判断单链表为有环链表? 循环链表一节,给大家详细地介绍了循环链表。在此基础上,本节带领大家讨论一个问题:如何判断一个单链表中有环?
注意,有环链表并不一定就是循环链表。循环链表指的是“首尾相连”的单链表,而有环链表则指的是单链表中存在一个循环子链表,如图 1 所示。
图 1 有环链表示意图
图 1 所示就是一个有环链表,但并不是循环链表。
那么,如果给定一个单链表,如何判断其是否为有环链表呢?常用的判断方法有如下 2 种。
1) 最直接的实现思想就是:从给定链表的第一个节点开始遍历,每遍历至一个节点,都将其和所有的前驱节点进行比对,如果为同一个节点,则表明当前链表中有环;反之,如果遍历至链表最后一个节点,仍未找到相同的节点,则证明该链表中无环。
注意,如果一个单链表为有环链表,基于单链表中各节点有且仅有 1 个指针域的特性,则势必该链表是没有尾结点的(如图 1 所示)。换句话说,有环链表的遍历过程是无法自行结束的,需要使用 break 语句手动结束遍历。
基于上面的实现思想,下面设计了一个相应的实现函数:
//自定义 bool 类型
typedef enum bool
{
False=0,
True=1
}bool;
// H 为链表的表头
bool HaveRing(link * H) {
link * Htemp = H; /
/存储所遍历节点所有前驱节点的存储地址,64位环境下地址占 8 个字节,所以这里用 long long 类型
long long addr[20] = { 0 };
int length = 0, i = 0;
Vue、小程序和Uni-App都有各自的生命周期,下面是它们的生命周期介绍:
Vue 的生命周期 Vue 的生命周期分为创建、挂载、更新和销毁四个阶段,具体的生命周期函数如下:
beforeCreate:实例刚在内存中被创建出来,此时还没有初始化好 data 和 methods 属性。
created:实例已经在内存中创建完成,data 和 methods 属性已经完成初始化。可以进行数据的操作,如异步请求数据。
beforeMount:在挂载开始之前被调用,此时 Vue 实例的模板已经编译完成,但尚未挂载到页面中。
mounted:实例挂载到页面后调用,此时可以进行 DOM 操作,如获取元素节点。
beforeUpdate:数据更新之前调用,发生在虚拟 DOM 重新渲染和打补丁之前。可以在该钩子中进行更新前的操作。
updated:数据更新之后调用,发生在虚拟 DOM 重新渲染和打补丁之后。可以在该钩子中进行更新后的操作。
beforeDestroy:实例销毁之前调用。在这个阶段,实例仍然完全可用。
destroyed:实例销毁后调用。此时,Vue 实例的所有指令、事件监听器都已经被移除,组件也会被销毁。
小程序的生命周期 小程序的生命周期分为创建、更新和销毁三个阶段,具体的生命周期函数如下:
onLoad:页面加载时触发,可以获取页面参数。
onShow:页面显示/切入前台时触发,每次打开页面都会触发。
onReady:页面初次渲染完成时触发,可以进行页面元素操作。
onHide:页面隐藏/切入后台时触发。
onUnload:页面卸载时触发。
onPullDownRefresh:用户下拉刷新时触发。
onReachBottom:页面上拉触底时触发。
onShareAppMessage:用户点击右上角分享时触发。
Uni-App 的生命周期 Uni-App 的生命周期与 Vue 的生命周期基本一致,除了增加了一些平台特有的生命周期函数,具体的生命周期函数如下:
onLaunch:应用初始化时触发,全局只触发一次。
onShow:应用启动或从后台进入前台时触发。
onHide:应用从前台进入后台时触发。
onError:应用发生脚本错误或 API 调用失败时触发。
onUniNViewMessage:接收从 nvue 页面发送过来的数据。
需要注意的是,Uni-App 是基于 Vue 的跨平台框架,所以它的生命周期函数与 Vue 的生命周期函数大部分是一致的。而小程序是一种独立的开发框架,其生命周期函数与 Vue 和 Uni-App 有所不同。
前言
大家好吖,欢迎来到 YY 滴单片机系列 ,热烈欢迎! 本章主要内容面向接触过单片机的老铁
主要内容含:
欢迎订阅 YY滴C++专栏!更多干货持续更新!以下是传送门!
YY的《C++》专栏YY的《C++11》专栏YY的《Linux》专栏YY的《数据结构》专栏YY的《C语言基础》专栏YY的《初学者易错点》专栏YY的《小小知识点》专栏YY的《单片机期末速过》专栏 目录 一.定时计数器的结构与工作原理二.定时计数器的工作方式 一.定时计数器的结构与工作原理 1.MCS-51系列单片机内部有( )个定时/计数器。C
A.1B.3C.2D.4 解析:如图所示,有两个定时计数器
T0、T1作用定时计数器:即可以(对内)计数完成定时功能;又可以对(外部)计数,完成计数;
2.MCS-51系列单片机内部的定时/计数器是( )位的。D
A.2B.4C.8D.16 解析:
3.TMOD是单片机内部的( )寄存器 B
A.定时器控制B.定时器方式C.定时器数据D.定时器计数 解析:
内部有两个定时/计数器,分别是控制寄存器TCON(TIME CONTROL)还有TMOD(TIME MODE)
4.应用单片机定时器/计数器时,控制定时器T0启动和停止的关键字是( )B
A.TMODB.TR0C.ET0D.TF0 解析:我们来看下TCON(定时寄存器)的结构,TR1、TR0是控制启动和停止的(right权力);TF1、TF0是标志溢出的(full)
TF0、TF1是标志溢出位实例演示
可以对比记忆下TMOD
5.使MCS-51系列单片机的定时器T0停止计数的语句是( )C
A.TR0=1B.TR1=1C.TR0=0D.TF1=1 解析:我们来看下TCON(定时寄存器)的结构,TR1、TR0是控制启动和停止的(right权力);TF1、TF0是标志溢出的(full)
1为启动,0停止
6.AT89C51中与定时计数器中断无关的寄存器是( )B
A.TCONB.SCONC.TMODD.IP 解析:我们回顾下中断的相关知识点;已知,SCON全程为( Serial port Control 即串行控制寄存器)——用于控制串行通信的参数设置,例如波特率、数据位、停止位等。
二.定时计数器的工作方式 7.单片机定时计数器根据需要可有多种工作方式,其中工作方式1是()A
A.16位定时计数器B.13位定时计数器C.8位可自动重载的定时计数器D.两个独立的8位定时计数器 解析:如下图所示,为16位的定时计数器
8位可自动重载的定时计数器是下图中的方式2
8.定时器工作方式()可溢出后不用重装计数初值。C
A.0B.1C.2D.3 9.定时器/计数器为自动重装初值的方式为()C
A.方式0B.方式1C.方式2D.方式3
解析:如下图所示,定时器工作方式2中,定时器的溢出后会自动重新从预设的初值开始计数,因此不需要手动重装计数初值。 10.定时/计数器有()种工作方式。D
A.1B.2C.3D.4 解析:一共有4中,由TMOD控制
TMOD的M0M1位控制
遗传算法 优点:
与问题领域无关且快速随机的搜索能力,不会陷入局部最优解;搜索从群体出发,具有潜在的并行性,提高运行速度,鲁棒性高;搜索使用评价函数启发,过程简单;使用概率机制进行迭代,具有随机性;具有可扩展性,容易与其他算法结合。
缺点:
1.遗传算法的编程实现比较复杂,首先需要对问题进行编码,找到最优解之后还需要对问题进行解码;
2.另外三个算子的实现也有许多参数,如交叉率和变异率,并且这些参数的选择严重影响解的品质,而目前这些参数的选择大部分是依靠经验;
3.没有能够及时利用网络的反馈信息,故算法的搜索速度比较慢,要得要较精确的解需要较多的训练时间;
4.算法对初始种群的选择有一定的依赖性,能够结合一些启发算法进行改进;
5.在实际应用中,遗传算法容易产生早熟收敛的问题,在选择方法既要使优良个体得以保留,又要维持群体的多样性。 演化策略(实变量/一个新个体)与遗传算法的区别 (染色体编码/两个新个体):
前者直接作用于实变量,后者使用优化变量的染色体编码前者使用的杂交算子是从两个个体产生一个个体,后者产生两个新的个体
进化程序:只利用变异算子,没有引用杂交机制。 模拟退火算法 优点:
具有摆脱局部最优解的能力,能够以随机搜索技术从概率的意义上找出目标函数的全局最小点,已被证明有渐进收敛性;简单、通用、易实现;具有并行性。
缺点:
1.对参数(如初始温度)的依赖性较强;
2.优化过程长,效率不高。 蚁群算法 优点:
在求解性能上,具有很强的鲁棒性(对基本蚁群算法模型稍加修改,便可以应用于其他问题)和搜索较好解的能力;蚁群算法是一种基于种群的进化算法,具有并行性;蚁群算法很容易与多种启发式算法结合,以改善算法性能。
缺点:
1.蚁群算法中初始信息素匮乏;
2.收敛速度慢、易陷入局部最优;
3.蚁群算法一般需要较长的搜索时间,其复杂度可以反映这一点;
4.容易出现停滞现象,即搜索进行到一定程度后,所有个体发现的解完全一致,不能对解空间进一步进行搜索,不利于发现更好的解。 粒子群算法 优点:
优化具有相当快的逼近最优解的速度,可以有效的对系统的参数进行优化;其个体充分利用自身经验和群体经验调整自身的状态;无集中约束控制,不会因个体的故障影响整个问题的求解,确保了具备很强的鲁棒性。对种群大小不十分敏感
缺点:
1.数学基础薄弱,不能严格证明它在全局最优点上的收敛性;
2.容易产生早熟收敛,陷入局部最优,主要归咎于种群在搜索空间中多样性的丢失;
3.由于缺乏精密搜索方法的配合 ,最优往往得不到最优解。
4.对离散数据不佳
1设计需求 通过stm32f103c8t6实现一个简易示波器功能,该示波器可以检测0-3.6khz频率范围内的波形。
也可以输出波形,输出方波、三角波、正弦波。
2技术方案 通过stm32的ADC功能,采集输入信号,最后由oled屏进行显示。
采样频率通过定时器控制,定时器触发ADC采样,然后通过DMA搬运数据,从而达到最大效率。
通过测试,ADC功能正常,可以采集波形,但是DAC输出波形异常,无法输出波形,查阅资料,发现stm32f103c8t6是小容量的单片机,没有DAC功能,所以无法直接通过dac配置输出。
3代码实现 直接看demo
https://download.csdn.net/download/weixin_51248645/88707820
4stm32f103zet6示波器 没有DAC的示波器叫什么示波器,换平台,采用stm32f103zet6进行配置。
4.1ADC配置 ADC最大频率计算:
由于stm32f103外部时钟频率最大为14M,所以配置定时器触发时,也不能超出这个值。
ADC最大频率:ADCCLK=14MHz,采样时间=1.5周期。
则:TCONV = 1.5 + 12.5 = 14 周期 = 1μs,采样频率为1Mhz。
1Mhz ?真的是极限吗?
当然不是,有两个方法提升。
1.正规方法:采用4通道ADC,分别在1/4周期进行采样,通过拼接的方式,实现1*4=4M频率的采样。
2.瞎整方法:外部时钟频率最大14M,这不能突破吗?
这次先弄个1M的进行测试。
ADC采用6分频,12M的时钟。采样时间=1.5周期。频率为0.86Mhz。
通过定时器配置,系统时钟是72M,定时器触发时间应大于1/0.86Mhz,则
TIM2_PWM_Init(T-1,pre-1); T*pre/72M>1/0.86M 取pre=1,得T>83.7。
取T=84,PWM的Pulse取12。
4.2DAC配置
0. 引言 我们之前讲解的一直是nginx的反向代理配置,关于正向代理的实现一直没有涉及,但在实际生产中正向代理也有非常广泛的应用场景,因此,今天我们将针对正向代理来深入学习。
1. 相关概念 1.1 什么是反向代理 所谓反向代理,就是用一个代理服务器,来接收客户端的各种请求,而客户端并不知道各类后台实际服务的地址,统一通过代理服务器来实现转发,这样的核心目的是为了保护后台服务对客户端不可见。我们之前演示的配置都基于反向代理的模式,实现各类服务的转发。
这样对于客户端来说,不需要知道各种后台服务,只需要向代理服务器发送请求即可,由代理服务器发出请求。
一般来说反向代理中代理服务器和后台服务是一伙儿的,绑定在一起。
一句话:客户端不知道自己实际请求的到底是谁
1.2 什么是正向代理 正向代理与反向代理相反,目的是为了隐藏客户端,也就是请求的发起者,让服务提供者感知到的是一个代理服务器,这样可以保护客户端的安全。一些对安全性要求较高的企业,可以基于正向代理实现安全隔离环境。
同时正向代理,也可以帮我们实现一种特殊的主备机制,这也是我们后续主要演示的。
一句话:服务器不知道实际请求自己的到底是谁
1.3 正向代理的应用场景 1、安全隔离 客户端服务器无法访问外网或者针对部分网络有限制,可以使用代理服务器进行访问
2、隐藏客户端ip 某些情况,客户端为了安全考虑,不想暴露自己的真实ip,就可以通过代理服务器来访问
3、加快访问速度 可以在代理服务器上部署缓存,比如利用nginx缓存静态资源等,这样可以加快客户端对于部分自资源的访问速度
2. Nginx正向代理实现步骤 1、配置nginx,设置转发通过 $scheme://$http_host$request_uri;三个参数来拼接转发地址。注意一定要声明DNS服务器,否则会报错502
server { listen 80; resolver 223.5.5.5 8.8.8.8; # 指定DNS服务器IP地址 location / { proxy_set_header HOST $host; proxy_http_version 1.1; proxy_pass $scheme://$http_host$request_uri; } } 上述配置仅能实现转发http的请求,如果实际要请求的地址是https的就不能实现了,会报错400
,这是因为正向代理转发默认不支持https的,我们需要安装ngx_http_proxy_connect_module插件来实现,该插件是国人开发的,非官方支持,所以会出现部分版本不支持,具体下文说明。
github地址:https://github.com/chobits/ngx_http_proxy_connect_module
2、如果是用yum安装的nginx,则下载一个与当前nginx同版本的nginx源码包,保证nginx安装目录下有configure文件,如果之前是编译安装的则不用了
cd /data wget http://nginx.org/download/nginx-1.18.0.tar.gz # 解压 tar -zxvf nginx-1.18.0.tar.gz 3、下载ngx_http_proxy_connect_module插件
yum install git cd /data git clone # 访问github慢的,就使用这里的gitee地址 https://gitee.
PyTorch 初级教程PyTorch 深度学习 开发环境搭建 全教程深度学习bug笔记深度学习基本理论 1:(MLP/激活函数/softmax/损失函数/梯度/梯度下降/学习率/反向传播/深度学习面试)深度学习基本理论 2:(梯度下降/卷积/池化/归一化/AlexNet/归一化/Dropout/卷积核/深度学习面试)深度学习 基本理论 3 :之物体检测(Anchor base/NMS/softmax/损失函数/BCE/CE/zip)
一、MATLAB插值函数概览 1)本节重点介绍的插值函数 MATLAB插值函数适用情况基础句式interp1 函数interp1 主要用于一维数据的插值interp1(x, y, x_interp, ‘linear’); 其中 x 和 y 是已知数据点,x_interp 是要插值的目标点。interp2 函数interp2 用于在二维平面上进行插值。适用于网格化的数据。interp2(X, Y, Z, X_interp, Y_interp, ‘linear’); 其中 X、Y、Z 是已知数据网格,X_interp 和 Y_interp 是要插值的目标点。interpn 函数多维插值,适用于处理高维数据。interpn(X1, X2, …, V, Xq1, Xq2, …);griddata 函数griddata 用于在不规则的数据点上进行插值,支持生成二维或高维的插值结果。适用于处理散乱的数据。interp_values = griddata(x, y, z, x_interp, y_interp, ‘linear’); 其中,x、y、z 是已知的数据点和值。x_interp、y_interp 是要插值的目标点。griddedInterpolant 类griddedInterpolant 类是 MATLAB 中用于多维数据插值的类。这个类提供了一种高效的方法来进行插值,特别适用于规则网格上的数据,是 interp1、interp2、interp3 的通用化。
(区别:griddedInterpolant 类适用于规则网格上的数据,也就是说,输入的坐标 X 应该是一个多维的规则网格,而 griddata 函数适用于不规则的或者散乱的数据点,坐标信息 x、y 可以是任意形状。)F = griddedInterpolant(X, V, method);
Vq = F(Xq); 其中,X:规则网格上的坐标信息,可以是一个多维数组,表示每个维度上的坐标。V:规则网格上对应坐标的值,与 X 的大小应该一致。method:插值方法,可以是 ‘linear’、‘nearest’、‘cubic’ 等。 Xq:待插值点的坐标,可以是一个数组或多维数组。scatteredInterpolant 类scatteredInterpolant 类提供了更灵活的方式进行不规则数据点的插值,支持多种插值方法。适用于处理不规则或散乱的数据点,类似于 griddata 但提供更多的控制选项。F = scatteredInterpolant(x, y, z, ‘linear’);
点击下方“JavaEdge”,选择“设为星标”
第一时间关注技术干货!
免责声明~
任何文章不要过度深思!
万事万物都经不起审视,因为世上没有同样的成长环境,也没有同样的认知水平,更「没有适用于所有人的解决方案」;
不要急着评判文章列出的观点,只需代入其中,适度审视一番自己即可,能「跳脱出来从外人的角度看看现在的自己处在什么样的阶段」才不为俗人。
怎么想、怎么做,全在乎自己「不断实践中寻找适合自己的大道」
1 我又开始劝退了 昨天劝旁边一个刚入行两年的程序员,对他说:
首先你要把市面一些视频教程都看遍,如多线程,SpringCloud,Redis,RPC框架,MQ
然后找一个培训班项目跟着敲一遍。其实瑞吉外卖、谷粒商城之类虽不适合往简历写,但若涉及技术栈较全面且主流,并且你都掌握了,你已经比大多跟你在一个层次的外包程序员强了
适当的背背八股应付面试,记住余麻子的一句话,甭管是不是真懂,背也要背会,大部分面试官他也只能问到这一步。如XX新生代老年代Aden区的,我保证你从入职到离职大概率都用不到,JVM要优化大概率也轮不到你,仅仅调整参数
到这里,努力的效用是最大的,ROI 很高,大部分人也就到此为止了,开始迷茫无措,浑浑噩噩度日等着被裁。
2 但你是外包呢? 但你到这水平,写CRUD和稍复杂业务比较快了,也能解决大多数问题,在此基础,再往上刷完两千道leetcode或研究CS底层。这些对一个外包程序员,你的努力已经开始边际递减。因为学历和经历,你大概率进不了BAT等更高平台,即便进去,你发现大部分时间做的事情不比外包高级多少,还是写PPT,定期汇报,承担更严重绩效压力。
每个人的定位不同,如果你是985本硕,入职就是大厂算法岗,虽然咱们都是程序员,但你跟我们其实不一样了,不是一个层次,这些写的对你没用。
3 终将离开 但是对于大部分低级程序员,终究或主动或被动会离开这行,但如果正在干着,也不要瞎听网上的唱衰真干保安外卖滴滴进厂进修:
外卖员即便轻车熟路,地区单王也不超过一万五,有算法控制着你的总收入,大部分外卖员一个月七八千,这还是很努力才行
保安确实有包吃住并且管理松懈的神仙岗,但月薪大多4500,你算算多久能存库两万,万一家里急用钱咋办?
996很苦,但也不是最苦,找到自己最舒适的节奏是最好的,至于通勤时间长也可以慢慢解决。
作为一个合格程序员,起码要知道在一个公司混下去,苟下去的办法,每次试用期就被开了,那你无疑是完全的自我失败,真的一点不适合当今职场环境了。只要苟住,那就慢慢找到自己的舒适区(也就是高级的摸鱼和甩锅技巧)。
克制不必要消费,多存点钱吧。千万别上高杠杆,给自己未来背上几百万的债务,加上自己工作也不稳定,这是极端不明智
4 很现实的案例 有个哥们能从工厂工人,高中学历,培训到前端,还入行干了几年,拿到十几k,还补上一个学信可查的非全日制大专。(再努力下本科也可以补上)已经算逆天改命了。放在几年前,他干五年时候能要到20K。不过他女友来句,不买房没商量,过去一趟几千几千的送礼金。我要是他,我就及时止损。如此不稳定的工作+不稳定的预期,买房彩礼结婚生子,起码几百万债务,掏空三代人腰包才行。
参考:
编程严选网
写在最后 编程严选网(www.javaedge.cn),程序员的终身学习网站已上线!
点击阅读原文,即可访问网站!
欢迎长按图片加好友,我会第一时间和你分享软件行业趋势,面试资源,学习途径等等。
添加好友备注【技术群交流】拉你进群,更多教程资源应有尽有
关注公众号后,在后台私信:
回复【架构师】,获取架构师学习资源教程
回复【面试】,获取最新最全的互联网大厂面试资料
回复【简历】,获取各种样式精美、内容丰富的简历模板
回复 【路线图】,获取直升Java P7技术管理的全网最全学习路线图
回复 【大数据】,获取Java转型大数据研发的全网最全思维导图
微信【ssshflz】私信 【副业】,进副业交流群
点击【阅读原文】,即可访问程序员一站式学习网站
最近在准备面试,为大家准备一份2024最新最全Java学习路线一条龙 程序员职业/技术发展知识星球(24 年首月仅需 25 最低价!)
Android15 OneUI电池优化 三星最近完成了对其所有设备的稳定版 One UI 6.0 更新的推出,引起了用户的极大兴奋。据新出现的互联网统计数据显示,即将发布的基于 Android 15 的 One UI 7 将通过优化电池和功耗来重新定义用户体验,这是一项具有突破性的进展。
据 Android Police 发布的全面报告指出,Android 15 更新将革新电池优化,承诺显著减少功耗。智能手机在经历多次充放电循环或使用时间较长后,其电池性能会逐渐下降。而这次即将推出的更新将引入电池健康菜单,向用户透明地显示手机电池的健康状况,及时提醒更换。
除了电池寿命的改进,Android 15 更新的目标还在于提升硬件性能,实现无缝多任务体验。三星致力于满足当今科技迷们不断变化的需求,用户可以期待更流畅的操作和更高效的性能。
此外,三星还致力于提供卓越的用户体验,即将发布的 Galaxy 设备的 One UI 7 将在 Android 15 更新之后推出,预计将带来一系列的新功能和增强措施,确保三星用户始终处于技术创新的前沿。
安卓14已经发布,但谷歌已经开始展望明年推出的安卓15。尽管安卓14引入了一些基于人工智能的新功能,但并未包含谷歌早期测试版中展示的所有功能。
通过广泛使用安卓14的测试版以及主要安卓皮肤(One UI 6、ColorOS 13和MIUI 14),以下是我希望在安卓15中看到的一些功能的简要列表:
1. 浮动窗口 安卓15需要引入浮动窗口功能。ColorOS和MIUI在三年前就推出了浮动窗口,这是一个非常有用的工具,可以最大限度地利用屏幕空间。浮动窗口允许调整应用程序大小,使其适应屏幕而不占据整个宽度,并且可以覆盖在其他应用程序上方,非常方便。例如,在需要计算几个数字时,可以在浮动窗口中启动计算器,这将非常实用。
如果谷歌打算将浮动窗口添加到安卓15中,可以参考ColorOS的实现方式,而不是MIUI。小米将浮动窗口默认启用,没有关闭此功能的选项。这意味着每当下拉通知时,浮动窗口都会打开,有时可能会误触。
2. 图标定制功能改进 谷歌需要提供更好的图标定制功能。尽管在安卓12中引入了主题图标,但在发布两年后,这个功能仍然不够完善。问题不在于谷歌,而是应用开发者。因为这个功能没有被强制要求,大多数应用开发者选择忽略它,导致主屏幕上的图标不够协调。即使像印象笔记这样的知名服务也没有提供这个功能,这令人感到困扰。
另外,如果谷歌能够推出改变图标形状和大小的能力,将会非常棒。目前,我对Pixel手机在这方面的定制性感到有些失望,希望谷歌能够改进。
3. 借鉴iOS的屏幕距离功能 屏幕距离是iOS 17中的一个巧妙新功能,它利用前置摄像头判断手机是否放得太靠近眼睛。它的目标是减少眼部疲劳,如果摄像头检测到您离脸部不到12英寸的距离使用设备,它会触发一个全屏警告要求您将手机或平板电脑远离一些。
这个功能在iPhone 15 Pro Max上非常有用,尤其是当晚上使用手机时容易让人靠得更近。屏幕距离功能旨在降低儿童近视的风险,但对于经常在床上使用手机的人来说也很方便。谷歌应该在安卓中引入类似的实用功能,利用相机来测量距离,应该很容易实现。
4. 改进Always On Display(常亮显示) 谷歌对于Always On Display(常亮显示)的实现一直不够出色,安卓14并没有改变这一情况。在选择常亮屏幕时,您只能显示时间和日期,并在底部显示通知图标,没有其他可定制选项。
与此同时,其他界面在这方面提供了广泛的定制功能。我喜欢ColorOS中可用的各种样式,而且我可以设计自己的模式显示在锁定屏幕上。尽管One UI在出厂时没有提供太多功能,但您总是可以安装Good Lock并解锁一系列的定制选项。
5. 应用程序克隆功能 大多数安卓品牌都提供了应用程序克隆的选项,这样您就可以运行两个实例。如果您有两张SIM卡并且想充分利用WhatsApp或Telegram等消息服务,这将非常方便。但在Pixel手机上却无法进行这个操作。谷歌曾在早期的安卓14测试版中预告这个功能,但在后续的测试版中却不见了,而稳定版本也没有包含这个功能。
安卓15即将到来 谷歌通常会在公开发布前几个月推出安卓的预览版,以确保开发者有足够的时间适应最新功能。如果以往经验可信,安卓15的开发者预览版可能会在2024年2月份发布,两个月后会有公开测试版。一旦可用,我将有更多关于安卓15的讨论。现在,请告诉我您希望在下一个安卓版本中看到哪些功能。
员工管理系统(部门管理) 1.新建项目 2.创建app python manage.py startapp app01 2.1 注册app 3. 设计表结构(django) from django.db import models class Department(models.Model): """部门表""" title = models.CharField(verbose_name="标题", max_length=32) class UserInfo(models.Model): """员工表""" name = models.CharField(verbose_name="姓名", max_length=32) password = models.CharField(verbose_name="密码", max_length=64) age = models.IntegerField(verbose_name="年龄") account = models.DecimalField(verbose_name="账户余额", max_digits=10, decimal_places=2, default=0) create_time = models.DateTimeField(verbose_name="入职时间") # 1.约束 # to:与那一张表关联 # to_field: 表中的那一列关联 # 2.django内部会把depart自动生成depart_id depart = models.ForeignKey(to="Department", to_field="id") # 3.部门表被删除 # 3.1 级联删除 # depart = models.ForeignKey(to="Department", to_field="id", on_delete=models.CASCADE) # 3.
响应式开发的原理Bootstrap前端开发框架Bootstrap栅格系统阿里百秀首页案例 响应式开发原理
1 响应式需要一个父级做为布局容器,来配合子级元素来实现变化效果。
2 在不同屏幕下,通过媒体查询来改变这个布局容器的大小,再改变里面子元素的排列方式和大小,从而实现不同屏幕下,看到不同的页面布局和样式变化
简单就是使用媒体查询针对不同宽度的设备进行布局和样式的设置,从而适配不同设备的目的。
Bootstrap 简介
Bootstrap 来自 Twitter(推特),是目前最受欢迎的前端框架。Bootstrap 是基于 HTML、CSS 和 JAVASCRIPT 的,它简洁灵活,使得 Web 开发更加快捷。
中文官网: http://www.bootcss.com/官网: http://getbootstrap.com/ 推荐使用: http://bootstrap.css88.com/ 框架:顾名思义就是一套架构,它有一套比较完整的网页功能解决方案,而且控制权在框架本身,有预制样式库、组件和插件。使用者要按照框架所规定的某种规范进行开发。
bootstrap 优点
标准化的html+css编码规范提供了一套简洁、直观、强悍的组件有自己的生态圈,不断的更新迭代让开发更简单,提高了开发的效率 Bootstrap 使用
1. 创建文件夹结构
2. 创建 html 骨架结构
3. 引入相关样式文件
4. 书写内容
这里就是直接去他那里的文档哪里,查看它的使用方法。
布局容器
Bootstrap 栅格系统
栅格系统英文为“grid systems”,也有人翻译为“网格系统”,它是指将页面布局划分为等宽的列,然后通过列数 的定义来模块化页面布局。
Bootstrap 提供了一套响应式、移动设备优先的流式栅格系统,随着屏幕或视口(viewport)尺寸的增加,系统会 自动分为最多12列。
栅格选项参数
栅格系统用于通过一系列的行(row)与列(column)的组合来创建页面布局,你的内容就可以放入这些创建好的布局中。
按照不同屏幕划分为1~12 等份
行(row) 可以去除父容器作用15px的边距
xs-extra small:超小; sm-small:小; md-medium:中等; lg-large:大;
列(column)大于 12,多余的“列(column)”所在的元素将被作为一个整体另起一行排列
每一列默认有左右15像素的 padding(这个可以将其内容加入到row中就可以去除)
目录
前瞻
关系型数据库
非关系型数据库
关系型数据库和非关系型数据库区别
数据存储方式不同
扩展方式不同
对事务性的支持不同
非关系型数据库产生背景
总结 Redis简介
什么是Redis
Redis具有的优点
Redis使用场景
哪些数据适合放入缓存中?
Redis为什么这么快?
Redis安装部署
Redis命令工具
redis-cli 命令行工具
redis-benchmark 测试工具
Redis数据库常用命令
Redis多数据库常用命令
Redis五大数据类型的增查删
String数据类型
SET/GET/APPEND/STRLEN
INCR/DECR/INCRBY/DECRBY GETSET SETEX SETNX
MSET/MGET/MSETNX
List数据类型
LPUSH/LPUSHX/LRANGE
LPOP/LLEN LREM/LSET/LINDEX/LTRIM LINSERT RPUSH/RPUSHX/RPOP/RPOPLPUSH Hash数据类型(散列类型)
HSET/HGET/HDEL/HEXISTS/HLEN/HSETNX
HINCRBY HGETALL/HKEYS/HVALS/HMGET/HMSET
Set数据类型(无序集合) SADD/SMEMBERS/SCARD/SISMEMBER
SPOP/SREM/SRANDMEMBER/SMOVE Sorted Set数据类型(zset、有序集合)
ZADD/ZCARD/ZCOUNT/ZREM/ZINCRBY/ZSCORE/ZRANGE/ZRANK
ZRANGEBYSCORE/ZREMRANGEBYRANK/ZREMRANGEBYSCORE
ZREVRANGE/ZREVRANGEBYSCORE/ZREVRANK 前瞻 关系型数据库 关系型数据库是一个结构化的数据库,创建在关系模型(二维表格模型)基础上,一般面向于记录。
SQL 语句(标准数据查询语言)就是一种基于关系型数据库的语言,用于执行对关系型数据库中数据的检索和操作。
主流的关系型数据库包括 Oracle、MySQL、SQL Server、Microsoft Access、DB2、PostgreSQL 等。
以上数据库在使用的时候必须先建库建表设计表结构,然后存储数据的时候按表结构去存,如果数据与表结构不匹配就会存储失败。
非关系型数据库 NoSQL(NoSQL = Not Only SQL ),意思是“不仅仅是 SQL”,是非关系型数据库的总称。
这里写目录标题 总览MySQl各个阶段基础篇总览 MySQL概述数据库相关概念查看本机MySQL版本号启停mysql打开windows服务管理windows命令行启停 连接mysql客户端mysql运行逻辑数据模型关系型数据库 总结 SQL总览SQL通用语法SQL语句分类DDL数据库操作表操作查询表创建表结构数据类型数值类型字符串类型日期类型案例 对表:修改&删除表修改表删除 总览 MySQl各个阶段 基础篇总览 MySQL概述 数据库相关概念 数据库是数据的仓库,存储数据
数据库管理系统,是一个大型软件,他操作着数据库,是人与数据库沟通的桥梁
SQL,是数据库编程语言,通过他可以通过数据库管理系统操作数据库
查看本机MySQL版本号 win + r
cmd
mysql --version
(侧面可以查看本机是否安装了mysql)
启停mysql 打开windows服务管理 windows命令行启停 注意,本机MySQL注册服务就叫MySQL(通过services.msc就可以看到)
连接mysql客户端 配置好环境变量之后,cmd以管理员身份运行,输入
mysql -u -root -p
(-h -p选项可以不写,默认是127.0.0.1 3306,即本机IP的3306端口)
之后输入密码
即可进入到mysql客户端,通过这个窗口输入sql语句,就可以操作mysql数据库了
mysql运行逻辑 数据模型 客户端就是我们的sql语句输入窗口,
而当我们安装了mysql之后,我们的计算机就变成了mysql数据库服务器
mysql整个服务自带dbms(即数据库管理系统),他可以翻译sql语句,去操作数据库中的数据
在一个数据库服务器中,可以创建多个数据库,而一个数据库又可以创建多个表
关系型数据库 即多张二维表,且,二维表之间有关系
总结 SQL 总览 SQL通用语法 可以多行可以单行
SQL语句可以使用空格/缩进来增强语句可读性
不区分大小写
注释:–单行注释
/* */ 多行注释
SQL语句分类 DDL针对数据库,用来制作数据库、删除数据库,制作表的字段
DML针对数据库表中的数据,用来操作数据库表中的数据,进行增删改
DQL针对数据库表中的数据,查询数据库中表的数据
DCL针对数据库的控制,创建数据库用户、控制数据库访问权限
DDL 数据库操作 几个注意点:
查询:
1、查询所有数据库时,要加database要加s
创建:
2、创建数据库时,database不用加s 且有几个可选项,第一个可选项是if not exists 加上之后的意思是:如果这个数据库名不存在,我再创建这个数据库,如果名称被占用,那么不会再创建,如下是加选项的语句:
文章目录 1. 创建Kubernetes命名空间2. 添加Prometheus社区helm chart3. 安装prometheus4. 检查Prometheus Pod运行状况5. 检查Prometheus Service部署情况6. 修改服务访问端口类型7. 访问Prometheus数据收集情况8. 访问Grafana9. 设置数据源10. 查看Kubernetes各类性能可视化参数信息 1. 创建Kubernetes命名空间 首先,创建一个 Kubernetes 命名空间,并使用 helm 来部署 stable/monitoring 软件包:
$ kubectl create namespace monitoring 操作过程演示:
[ec2-user@ip-172-31-37-104 ~]$ kubectl create namespace monitoring namespace/monitoring created [ec2-user@ip-172-31-37-104 ~]$ kubectl get ns NAME STATUS AGE default Active 153m kube-node-lease Active 153m kube-public Active 153m kube-system Active 153m monitoring Active 86m 2. 添加Prometheus社区helm chart 其次,添加 Prometheus 社区helm chart:
$ helm repo add prometheus-community https://prometheus-community.
1.什么是大模型幻觉? 在语言模型的背景下,幻觉指的是一本正经的胡说八道:看似流畅自然的表述,实则不符合事实或者是错误的。
幻觉现象的存在严重影响LLM应用的可靠性,本文将探讨大型语言模型(LLMs)的幻觉问题,以及解决幻觉现象的一些常见方法。
2.为什么需要解决LLM的幻觉问题? LLMs的幻觉可能会产生如传播错误信息或侵犯隐私等严重后果。 比如在医疗应用中,对患者生成的报告如果存在幻觉可能导致错误诊断甚至影响生命安全。
幻觉影响了模型的可靠性和可信度,因此需要解决LLM的幻觉问题。
3.幻觉一定是有害的吗? 幻觉不一定是有害的,特别是在一些需要创造力或灵感的场合,比如写电影剧情,幻觉的存在可能带来一些奇思妙想,使得生成的文本充满想象力。
因此,对幻觉的容忍度取决于具体的应用场景。
4.幻觉有哪些不同类型? 幻觉主要可以分为两类:即内在幻觉和外在幻觉。
内在幻觉:生成的内容与源内容相矛盾。外部幻觉:生成的内容不能从源内容中得到验证,既不受源内容支持也不受其反驳。 5.为什么LLM会产生幻觉? 有一些研究也在致力于分析幻觉出现的不同原因,已知的一些原因包括:
源与目标的差异:当我们在存在源与目标差异的数据上训练模型时,模型产生的文本可能与原始源内容产生偏差。这种差异,有时可能是在数据收集过程中不经意间产生的,有时则是故意为之。无意识的源-目标差异:这种差异的产生有多种原因。例如,数据可能是基于某种经验法则编制的,使得目标信息并不总是完全依赖源信息。举例来说,如果从两家不同的新闻网站获得相同事件的报道作为源与目标,目标报道中可能包含源报道没有的信息,从而导致二者不同。有意识的源-目标差异:某些任务在本质上并不追求源与目标的严格一致,尤其是在需要多样性输出的情境下。训练数据的重复性:训练过程中使用的数据,如果存在大量重复,可能导致模型在生成时过于偏好某些高频短语,这也可能引发“幻觉”。数据噪声的影响:使用充斥噪声的数据进行训练,往往是导致“幻觉”出现的关键因素之一。解码过程中的随机性:某些旨在增加输出多样性的解码策略,如top-k采样、top-p方法以及温度调节,有时会增加“幻觉”的产生。这往往是因为模型在选择输出词汇时引入了随机性,而没有始终选择最可能的词汇。模型的参数知识偏向:有研究表明,模型在处理信息时,可能更依赖其在预训练阶段所积累的知识,而忽略了实时提供的上下文信息,从而偏离了正确的输出路径。训练与实际应用中的解码差异:在常见的训练方法中,我们鼓励模型基于真实数据预测下一个词汇。但在实际应用中,模型则是根据自己先前生成的内容进行预测。这种方法上的差异,尤其在处理长文本时,可能会导致模型的输出出现“幻觉”。 最后,如GPT之类的生成模型,其实只是学会了文本中词汇间的统计规律,所以它们生成内容的准确性仍然是有限的。
6.如何度量幻觉? 最有效可靠的方式当然是靠人来评估,但是人工评估的成本太高了。因此有了一些自动化评估的指标:
命名实体误差:命名实体(NEs)是“事实”描述的关键组成部分,我们可以利用NE匹配来计算生成文本与参考资料之间的一致性。直观上,如果一个模型生成了不在原始知识源中的NE,那么它可以被视为产生了幻觉(或者说,有事实上的错误)。蕴含率:该指标定义为被参考文本所蕴含的句子数量与生成输出中的总句子数量的比例。为了实现这一点,可以采用成熟的蕴含/NLI模型。基于模型的评估:应对复杂的句法和语义变化。利用问答系统:此方法的思路是,如果生成的文本在事实上与参考材料一致,那么对同一个问题,其答案应该与参考材料相似。具体而言,对于给定的生成文本,问题生成模型会创建一组问题-答案对。接下来,问答模型将使用原始的参考文本来回答这些问题,并计算所得答案的相似性。利用信息提取系统:此方法使用信息提取模型将知识简化为关系元组,例如<主体,关系,对象>。这些模型从生成的文本中提取此类元组,并与从原始材料中提取的元组进行比较。 7.如何缓解LLM幻觉? 与幻觉有关的数据问题可以(至少理论上)通过创建高质量无噪声的数据集来解决。但是,验证和清理数百GB的文本语料库难度太大了。
因此也有了一些其他的方法:
利用外部知识验证正确性修改解码策略采样多个输出并检查其一致性 7.1 通过使用外部知识验证主动检测和减轻幻觉 《A Stitch in Time Saves Nine: Detecting and Mitigating Hallucinations of LLMs by Validating Low-Confidence Generation》
作者发现
幻觉的生成是会传播的,比如一句话出现幻觉,后续生成的文本可能也会出现幻觉甚至更严重。这意味着,如果我们能够“主动”检测并减轻幻觉,那么我们也可以阻止其在后续生成的句子中的传播。logit输出值(输出词汇表上的概率分布)可以用来获取幻觉的信号。具体地说,我们计算了一个概率得分,并展示了当这个得分很低时,模型更容易产生幻觉。因此,它可以作为幻觉的一个信号,当得分很低时,可以对生成的内容进行信息验证。 基于这两个发现,作者提出了主动检测和减轻的方法。
在检测阶段,首先确定潜在幻觉的候选者,即生成句子的重要概念。然后,利用其logit输出值计算模型对它们的不确定性并检索相关知识。
在减轻阶段,使用检索到的知识作为证据修复幻觉句子。将修复的句子附加到输入(和之前生成的句子)上,并继续生成下一个句子。这个过程不仅减轻了检测到的幻觉,而且还阻止了其在后续生成的句子中的传播。
7.2 事实核心采样 《Factuality Enhanced Language Models for Open-Ended Text Generation》
在这种方法中,作者认为,采样的“随机性”在用于生成句子的后半部分时,对事实性的损害比在句子的开头更大。因为在句子的开始没有前文,所以只要它在语法和上下文上是正确的,LM就可以生成任何内容。然而,随着生成的进行,前提变得更为确定,只有更少的单词选择可以使句子成为事实。因此,他们引入了事实核心采样算法,该算法在生成每个句子时动态调整“核心”p。在事实核心采样中,生成每个句子的第t个标记的核心概率pt为,
其中,λ是top-p概率的衰减因子,ω是概率的下限衰减。
7.3 SelfCheckGPT SelfCheckGPT的主要思想是:如果模型真的掌握某个事实,那么多次生成的结果应该是相似的且事实一致的;相反,如果模型在胡扯,那么随机采样多次的结果会发散甚至矛盾。
因此,他们从模型中采样多个response(比如通过变化温度参数)并测量不同response之间的信息一致性,以确定哪些声明是事实,哪些是幻觉。这种信息一致性可以使用各种方法计算,比如可以使用神经方法计算语义等价(如BERTScore)或使用IE/QA-based方法。
8.LLMs什么时候最容易产生幻觉? 数值混淆:当LLM处理与数字有关的文本,如日期或数值时,容易产生幻觉。处理长文本:在需要解读长期依赖关系的任务中,例如文档摘要或长对话历史,模型可能会生成自相矛盾的内容。逻辑推断障碍:若模型误解了源文本中的信息,它有可能产生不准确的结论。因此,模型的逻辑推理能力至关重要。上下文与内置知识的冲突:模型在处理信息时,可能会过度依赖于预训练阶段获取的知识,而忽略实际上下文,导致输出不准确。错误的上下文信息:当给定的上下文包含错误信息或基于错误的假设时(如:“为什么高尔夫球比篮球大?”或“氦的原子序数为什么是1?”),模型可能无法识别这些错误,并在其回答中产生幻觉。 参考资料:
The Hallucination Problem of Large Language Models
目录 【linux笔记1】文件内容的理解用户管理用户管理命令添加用户切换用户修改用户信息删除用户 用户组 【linux笔记1】 文件内容的理解 etc文件夹:etc是拉丁语"et cetera"的缩写,意思是“和其他的”或“等等”。在linux系统中,“etc”目录用于存放系统的配置文件。
用户管理 linux用户可以分为2类
1.普通用户:这是大多数人使用的用户类型。普通用户可以使用系统资源、运行程序,但通常不能更改系统设置或访问其他用户的文件。
2.root用户:root是linux系统的管理员账户。root用户有权限做任何事情,包括访问和修改所有文件、安装和卸载程序、以及更改系统设置。通常为了避免意外损坏系统,不建议长期作为root用户操作。
3.系统用户:这些用户运行特定的服务或进程。
/etc/passwd存储用户信息,它有七个字段:依次为用户名、密码、用户标识号UID、用户所属的主要群组标识号GID、用户名全称、用户主目录、用户所使用的shell类型。
/etc/shadow是passwd的影子文件,用于存储用户密码或者其他/etc/passwd不能包含的信息,比如用户账号的有效期,该文件只有root用户可以读取和操作。
用户管理命令 添加用户 切换用户 su 用户名 修改用户信息 删除用户 用户组
矩形区域不超过K的最大数值和 题目要求 解题思路 来自[宫水三叶]
从题面来看显然是一道[二维前缀和]的题目。本题预处理前缀和的复杂度为O(m* n)
搜索所有子矩阵需要枚举[矩形左上角]和[矩形右下角],复杂度是 O ( m 2 ∗ n 2 ) O(m^2 * n^2) O(m2∗n2),因此,如果把本题当作二维前缀和模板题来做的话,整体复杂度为 O ( m 2 ∗ n 2 ) O(m^2 * n^2) O(m2∗n2).
数据范围是 1 0 2 10^2 102,对应的计算量是 1 0 8 10^8 108,理论上会超时,但当我们枚举[矩形左上角](i,j)的时候,我们只需要搜索位于(i,j)的右下方的点(p,q)作为[矩形右下角],所以其实我们是取不满 m 2 ∗ n 2 m^2 * n^2 m2∗n2的,但是,仍然存在超时风险。
前缀和 & 二分(抽象一维) 我们来细想一下[朴素二维前缀和]解法是如何搜索答案(子矩阵):通过枚举[左上角] & [右下角]来确定某个矩阵
换句话说是通过枚举(i,j)和(p,q)来唯一确定子矩阵的四条边,每个坐标点可以看作确定子矩阵的某条边。
既然要确定的边有四条,我们如何降低复杂呢?
简单的,我们先思考一下同样是枚举的[两数之和]问题
在[两数之和]中可以暴力枚举两个数,也可以只枚举其中一个数,然后使用数据结构(哈希表)来加速找另一个数(这是一个通用的[降低枚举复杂度]思考方向)。
对应到本题,我们可以枚举其中三条边,然后使用数据结构来加速找第四条边。
当我们确定了三条边(红色)之后,形成的子矩阵就单纯取决于第四条边的位置(黄色):
于是问题转换为[如何快速求得第四条边(黄色)的位置在哪]。
我们可以进一步将问题缩小,考虑矩阵之有一行(一维)的情况:
这时候问题进一步转换为[在一维数组中,求解和不超过K的最大连续子数组之和]。
对于这个一维问题,我们可以先预处理出[前缀和],然后枚举子数组的左端点,然后通过[二分]来求解其右端点的位置。
假定我们已经求得一维数组的前缀和数组sum,即可得下标范围[i,j]的和为:
areaSum(i,j) = sum[j] - sum[i-1] <=k
在Python中,如果一个函数被标记为async,这意味着它是一个异步函数。但是,仅仅因为一个函数被标记为异步并不意味着它会自动异步执行。为了使异步函数真正异步,你需要在函数内部使用await关键字来调用其他异步函数或操作。以下是一个简单的例子来说明这一点:
import asyncio async def my_async_function(): print("This is an asynchronous function.") # 调用异步函数 asyncio.run(my_async_function()) 在上面的例子中,my_async_function被标记为异步,但没有使用await。因此,当调用这个函数时,它实际上会同步执行。
如果你想让它真正异步执行,你需要使用await来调用其他异步操作,例如:
import asyncio import time async def my_async_function(): print("Starting the asynchronous function.") await asyncio.sleep(2) # 等待2秒 print("Done with the asynchronous function.") # 调用异步函数 asyncio.run(my_async_function()) 输出结果,如下所示:
Starting the asynchronous function. Done with the asynchronous function. 在上面的例子中,my_async_function使用了await来调用asyncio.sleep(2),这是一个异步操作。因此,my_async_function本身会异步执行,等待2秒后才会继续执行。
一、信息收集 收集的内容包括目标系统的组织架构、IT资产、敏感信息泄露、供应商信息等各个方面,通过对收集的信息进行梳理,定位到安全薄弱点,从而实施下一步的攻击行为。
域名收集 1.备案查询
天眼查爱企查官方ICP备案查询 通过以上三个平台,可以查询获得一批主域名、微博、邮箱等。 2.FOFA、Google查询:直接输入公司名称、主域名等进行搜索
domain="xxxx.com" header="xxxx.com" cert="xxxx.com" host="xxxx.com" body="xxxx.com" 3.证书查询
4.使用浏览器查询
点击小锁–安全连接–更多信息–查看证书(有些可能没有),可以得到一些主域名以及子域名。
5.dns查询
用dnsdumpster.com查询是否存在自建NS服务器,再将ns名带入https://hackertarget.com/find-shared-dns-servers/进行查询,可以获得一批主域名:
6.whois查询
通过查询目标的WHOIS信息,对联系人、联系邮箱等信息进行反查以及查看whois历史信息,获取更多相关的域名信息;微步在线也可以根据IP、邮箱等查询历史域名。
7.通过众测平台查询资产范围,在众测平台上有些厂商会把资产范围放出来。
8.通过主域名对子域名进行搜索,可使用工具、搜索引擎等。
* OneForAll:集成多种方式搜集子域名,包括dns查询、证书查询等; * Amass:kali自带,集成多种收集方式,强烈推荐; * [https://crt.sh/](https://crt.sh/):通过证书查找子域名和指纹识别; * [https://dnsdumpster.com](https://dnsdumpster.com):是一个在线实用程序,可以查找子域、目标的DNS记录。 9.直接访问收集到的主域名,对网页上指向的域名链接进行收集(可能会放一些OA等办公系统的跳转)。
10.枚举域名
https://github.com/infosec-au/altdns, Altdns是一个DNS侦察工具,允许发现符合模式的子域。Altdns接收可能出现在域下的子域中的单词(如 test、dev、staging),并接收您知道的子域列表。
11.收集应用资产
11.1 天眼查、企查查
11.2 微信APP搜索(小程序、公众号)
11.3 支付宝搜索(小程序、公众号)
11.4 工具ENScan(可查询企业APP信息、微信公众号信息、供应商信息等)
11.5 APP 查找应用商店、豌豆荚(可下载历史app)
11.6 PC可通过官网进行查找下载
12.根据前几种方式获取相关IP,然后探测可能存在的C段,可获取一些没有相关联信息的隐藏资产,再通过IP反查域名(https://github.com/Sma11New/ip2domain)
IP收集 1.真实IP查找
CDN判断:
多地ping,全球ping,查看解析IP是否一致;NSlookup:通过nslookup查看不同DNS域名解析情况来判断是否使用了CDN;在线检测:https://www.cdnplanet.com/tools/cdnfinder/;通过https证书:有的cdn颁发的证书带有cdn名称,可通过https证书进行cdn识别; 真实IP查找:通过查询历史DNS记录站点在做CDN之前可能将域名解析到真实IP,通过查询DNS历史记录可能会找到CDN使用前的真实IP;子域查询法:CDN服务的使用成本还是挺高的,所以很多的站点只对流量大的主站做了CDN,这种情况下我们通过子域枚举就能获取到子站的真实IP,再进行C段;全球ping:很多CDN厂商因为某些原因仅对国内线路做了解析,这种情况下使用国外主机直接访问就可能获取到真实IP;通过网站漏洞,如:phpinfo;需要找xiaix.me网站的真实IP,我们首先从apnic获取IP段,然后使用Zmap的banner-grab扫描出来80端口开放的主机进行banner 抓取,最后在http-req中的Host写xiaix.me;利用应用功能,抓取反向连接查找服务器IP,或者根据应用返回/报错查看。 2.通过IP地址注册信息查询:https://ipwhois.cnnic.net.cn/ 3.对上面域名解析获得的单个IP输入查询框,会有一个IP范围
4.使用FOFA等互联网资产收集工具直接搜索公司名称
5.C段扫描
rustscan:速度快;goby:图形化直观,支持漏洞验证,端口扫描;fscan:速度快,主机存活探测、端口扫描、常见服务的爆破。 敏感信息收集 1.利用Google
Google常用语法:site:*.test.cn filetype:xlsx 学号 site:*.test.cn filetype:docx | pdf | csv | json搜集管理后台:site:xxx.
1.引言 在数据分析和数据科学领域,数据聚合和分组是非常常见的操作。它提供了大量的功能,用于读取,清洗和处理各种类型的数据。Pandas是一个流行的Python库,提供了丰富的数据分析和处理功能。本文将介绍如何使用Pandas进行数据分组和聚合,包括分组操作和聚合函数的使用,以及使用transform和apply方法进行数据变换。
2.分组操作基础讲解 Pandas的groupby方法是数据分组和聚合的核心。groupby方法可以对数据进行分组,并在每个组上应用聚合函数。下面是一个示例代码:
import pandas as pd df = pd.read\_csv('data.csv') grouped = df.groupby('column\_name') 上面的代码将数据框按照“column_name”列进行分组,并将结果保存在grouped对象中。现在,我们可以在每个组上应用聚合函数。
2.1聚合函数 Pandas提供了各种聚合函数,如mean,sum,max和min等。这些函数可以应用于groupby对象中的每个组。下面是一些常用的聚合函数:
grouped.mean() # 每个组的平均值 grouped.sum() # 每个组的总和 grouped.max() # 每个组的最大值 grouped.min() # 每个组的最小值 2.2使用transform进行数据变换 transform方法可以**在每个组上应用一个函数,并将结果广播回原始数据框中的每个元素。**这个函数必须返回与原始数据框具有相同大小的对象。下面是一个示例代码:
import pandas as pd df = pd.read\_csv('data.csv') grouped = df.groupby('column\_name') mean\_values = grouped.transform(lambda x: x.mean()) 上面的代码将数据框按照“column_name”列进行分组,并在每个组上应用mean函数。然后,mean函数的结果被广播回原始数据框中的每个元素。
2.3使用apply进行数据变换 apply方法可以在每个组上应用一个函数,并将结果作为新的数据框返回。这个函数可以返回任何大小的对象。下面是一个示例代码:
import pandas as pd df = pd.read\_csv('data.csv') grouped = df.groupby('column\_name') result = grouped.apply(lambda x: x + 1) 上面的代码将数据框按照“column_name”列进行分组,并在每个组上应用一个函数。
3.具体例子、实例演示 当然,以下是一些使用Pandas进行数据分组和聚合的更具体的例子。
简介: 在这篇博客中,我们将深入探索如何在 C++ 程序中实现子进程的创建与执行,以及父子进程间的管道通信。核心代码提供了一个框架,用于接收用户命令、创建子进程并利用 execvp 系统调用执行这些命令。此外,我们通过创建管道(pipe),展示了如何在父子进程间安全地传递数据。
本文重点介绍 fork, pipe, 和 execvp 的使用方法,并解释了如何将标准输出和标准错误从子进程重定向到父进程。这一过程涉及对 Unix 系统调用的深入理解,尤其是进程间通信(IPC)的概念。我们的目标是提供一个清晰的指南,帮助读者理解和实现在现代操作系统中广泛应用的进程创建、执行和通信机制。
该教程适合对操作系统、进程管理以及 Unix/Linux 系统编程感兴趣的读者。无论是系统编程新手还是有经验的开发者,都可以通过这个实例加深对进程间通信和命令行界面(CLI)应用编程的理解。
exec相关 一共有六个分三组记忆
execlp -> execvp execl -> execv execle -> execve 这几个函数的速记 记忆口诀如下:
0、exec是通用前缀
1、 p 代表第一个参数是file 也就是程序的名字比如 ls, 如果名字没带p, 代表第一个参数是path, 比如 /bin/ls
2、 l 代表参数传递的是list, 参数是一个个传递的,最后一个参数为NULL
3、 v 代表argv, 参数是用char* 数组传递的
4、 e 代表环境变量
1、execlp l->list,p-> file 参数就是(file, a1, a2, a3,..., NULL); 2、execvp v->argv,p->file. 参数就是file, aegv) 3、execl l->list,没p -> path 参数就是(path, a1, a2, a3, .
目录
一.视图
1.1 含义
1.2 操作
二.案例
三.思维导图
一.视图 1.1 含义 虚拟表,查询方面和普通表一样使用。
1.2 操作 1.创建视图:
create or replace view 视图名
as
查询语句; 2.视图的修改:
方式1 create or replace view 视图名
as
查询语句;方式2 alter view 视图名
as
查询语句; 3.删除视图:
drop view 视图名,视图名,... 4.查看视图:
DESC 视图名; —— 查看视图相关字段SHOW CREATE VIEW 视图名; —— 查看视图相关语句 二.案例 01)查询" 01 "课程比" 02 "课程成绩高的学生的信息及课程分数
1.涉及表:t_mysql_student, t_mysql_score2.连接方式:内连接3.行转列:流程函数SELECT
s.*,
(case when t1.cid = '01' then t1.score end) 语文,
(case when t2.
css 弹性布局 flex布局,弹性布局,代替float,针对div容器
任何一个容器都可以指定为Flex布局。
flex布局的使用步骤:
1、开启flex布局,display:flex; 布局块级元素
display: inline-flex;布局行内元素
2、设置主轴方向,默认的主轴是横向,
flex-direction
3、设置侧轴(交叉轴): align-items
注意:行内元素也可以使用Flex布局。以下写法代表将display:inline和display:flex结合起来
/* 启用弹性布局,并变为行内元素 */ .box{ display: inline-flex; } 注意:设为Flex布局以后,子元素的float、clear和vertical-align属性将失效。
flex-direction属性
flex-direction属性决定主轴的方向(即项目的排列方向)。
.box { flex-direction: row | row-reverse | column | column-reverse; } 它可能有4个值。
row(默认值):主轴为水平方向,起点在左端。row-reverse:主轴为水平方向,起点在右端。column:主轴为垂直方向,起点在上沿。column-reverse:主轴为垂直方向,起点在下沿。 flex-wrap属性
默认情况下,项目都排在一条线(又称”轴线”)上。flex-wrap属性定义,如果一条轴线排不下,如何换行。
.box{ flex-wrap: nowrap | wrap | wrap-reverse; } 它可能取三个值。
(1)nowrap(默认):不换行。
(2)wrap:换行,第一行在上方。
(3)wrap-reverse:换行,第一行在下方。
justify-content属性
justify-content属性定义了项目在主轴上的对齐方式。也就是水平对齐。
它可能取5个值,具体对齐方式与轴的方向有关。下面假设主轴为从左到右。
.box { justify-content: flex-start | flex-end | center | space-between | space-around | space-evenly; } flex-start(默认值):左对齐flex-end:右对齐center: 居中space-between:两端对齐,项目之间的间隔都相等。space-around:每个项目两侧的间隔相等。所以,项目之间的间隔比项目与边框的间隔大一倍。space-evenly:平均对齐,在CSS3后续才加入的,是平均对齐 align-items属性
在构建云原生应用的过程中,对于技术组件的云化选择是非常重要的。 1. 简介 Elasticsearch是一个基于Lucene的搜索服务器。它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口。Elasticsearch是用Java语言开发的,并作为Apache许可条款下的开放源码发布,是一种流行的企业级搜索引擎。Elasticsearch用于云计算中,能够达到实时搜索,稳定,可靠,快速,安装使用方便。官方客户端在Java、.NET(C#)、PHP、Python、Apache Groovy、Ruby和许多其他语言中都是可用的。
2. 迁移原理 快照适用场景: 离线迁移; 源端数据量较大(GB、TB、PB级别)的场景;
同账号下,同区域或跨区域快照数据迁移的场景; Logstash适用场景: 在线迁移,需要开启白名单;迁移全量或同步增量数据,对实时性要求不高的场景; 仅对查询结果进行迁移的场景;
需对待迁移数据进行过滤的场景; 版本跨度较大的数据迁移场景,例如5.x迁移到6.x或7.x;
elasticsearch-migration(elasticsearch-exporter)适用场景: 在线迁移,需要开启白名单; 开源工具,安装简单,解压即可使用;
可以部分跨版本;
elasticsearch-dump适用场景: 数据量较小的场景,需要开启白名单。
reindex适用场景: 慢,需要开启白名单。 3. 迁移方案 搭建目标环境
快照备份索引目标集群重建
目录
1.新建空文件
2.修改文件权限
3.修改文件内容
4.文件查找与复制
5.文件移动与删除
6.文件压缩与解压
1.新建空文件 touch file.txt touch {file1,file2,file3}.txt 2.修改文件权限 文件权限的修改与文件夹是相同的,使用chmod命令即可,具体可看Linux常用指令二:目录以及文件夹的常用操作
3.修改文件内容 如果只是查看文件内容,可以用 cat </path/filename>指令,文件内容会直接在命令行中输出。
①使用vi/vim (sudo)vim test.txt // 按i键开始编辑,编辑完成后,按下Esc键回到命令模式,输入:wq保存并退出。 :q 退出 :q! 强制退出 :wq 保存并退出 ②使用gedit (sudo)gedit test.txt //会弹出类似记事本的编辑界面(vim则是在命令行界面中编辑) 4.文件查找与复制 find -name file.txt //在当前目录下查找指定文件 cp path1/file1 path2/ //复制文件到path2 5.文件移动与删除 mv path1/file1 path2/ //移动文件到path2 mv oldname newname //也可用于文件重命名 rm -r file //删除非空文件 rm -rf file //强制删除文件,不询问 6.文件压缩与解压 个人还是会感觉在图形化界面下解压缩比较舒服。。。 tar -cvf test.tar file1 file2 file3 //将三个文件压缩到test.tar tar -czvf test.
简介 ESP32是一款功能强大的低功耗微控制器,由乐鑫(Espressif)公司开发。它集成了Wi-Fi和蓝牙功能,适用于各种物联网应用。Thonny是一款基于Python的开源集成开发环境(IDE),专为MicroPython设计。Thonny安装包自带了Python3,使得初学者也能轻松学习编程。对于ESP32的开发,我们主要使用MicroPython,这是一种特殊的Python解释器,针对硬件做了特殊处理。尽管与PyCharm、Jupyter、VSCode等专业的Python IDE相比,Thonny在功能上可能不够强大。在本教程中,我们将使用Thonny和MicroPython开发一个简单的ESP32点灯实验。
环境准备 为了完成本教程,您需要以下材料
一台安装了Thonny的PC。我用自已的mac电脑安装了最新的Thonny,下载地址一块ESP32开发板。我采用普中科技的esp32开发板一根USB数据线跳线
开发板子如图:
配置解释器 USB数据线连接你的开发板(如ESP32-S3)到计算机上,并确保它被正确识别。点击运行,打开配置解释器,并选择esp32,如图:
此时,打开你的开发板开关,我们需要通过跳线来连接我们的15引脚和LED中的D1口。如图:
编写程序 创建一个新文件名为main.py的文件,并在其中输入以下代码:
from machine import Pin import time # 定义LED引脚 led = Pin(15, Pin.OUT) while True: # 点亮LED led.value(1) time.sleep(0.5) # 熄灭LED led.value(0) time.sleep(0.5) 代码解析:
我们使用了MicroPython的machine模块,machine模块中的Pin类是用于控制板上的GPIO引脚的类。它提供了一些方法来读取和设置引脚的值,以及配置引脚的模式(输入模式或输出模式)。
Pin类的方法:
Pin(number, mode):创建一个Pin对象,指定引脚号和模式。
value(value):设置引脚的值为1(高电平)或0(低电平)。
time.sleep()是Python中的一个函数,用于暂停程序的执行。它接受一个参数,表示暂停的秒数。
点击运行,查看开发板的效果,我们可以看到D1的灯将每隔0.5秒闪烁一次。
总结 本文介绍了如何使用Thonny开发环境来编写代码,控制ESP32上的LED灯。我们安装了Thonny开发环境,并编写了Python代码来控制LED的开关状态。最后,我们将代码上传到ESP32开发板上进行测试,成功实现了LED灯的交替闪烁。Thonny是一个非常适合初学者使用的ESP32开发工具,它可以帮助读者快速入门物联网开发领域。
本文于网络整理,版权归原作者所有
自己写 Python 也有四五年了,一直是用自己的“强迫症”在维持自己代码的质量。都有去看Google的Python代码规范,对这几年的工作经验,做个简单的笔记,如果你也在学pythpn,准备要学习python,希望这篇文章对你有用。
1. 首先 建议1、理解Pythonic概念—-详见Python中的《Python之禅》
建议2、编写Pythonic代码
(1)避免不规范代码,比如只用大小写区分变量、使用容易混淆的变量名、害怕过长变量名等。有时候长的变量名会使代码更加具有可读性。
(2)深入学习Python相关知识,比如语言特性、库特性等,比如Python演变过程等。深入学习一两个业内公认的Pythonic的代码库,比如Flask等。
建议3:理解Python与C的不同之处,比如缩进与{},单引号双引号,三元操作符?,Switch-Case语句等。
建议4:在代码中适当添加注释
建议5:适当添加空行使代码布局更加合理
建议6:编写函数的4个原则
(1)函数设计要尽量短小,嵌套层次不宜过深
(2)函数声明应该做到合理、简单、易用
(3)函数参数设计应该考虑向下兼容
(4)一个函数只做一件事,尽量保证函数粒度的一致性
建议7:将常量集中在一个文件,且常量名尽量使用全大写字母
2. 编程惯用法 建议8:利用assert语句来发现问题,但要注意,断言assert会影响效率
建议9:数据交换值时不推荐使用临时变量,而是直接a, b = b, a
建议10:充分利用惰性计算(Lazy evaluation)的特性,从而避免不必要的计算
建议11:理解枚举替代实现的缺陷(最新版Python中已经加入了枚举特性)
建议12:不推荐使用type来进行类型检查,因为有些时候type的结果并不一定可靠。如果有需求,建议使用isinstance函数来代替
建议13:尽量将变量转化为浮点类型后再做除法(Python3以后不用考虑)
建议14:警惕eval()函数的安全漏洞,有点类似于SQL注入
建议15:使用enumerate()同时获取序列迭代的索引和值
建议16:分清==和is的适用场景,特别是在比较字符串等不可变类型变量时(详见评论)
建议17:尽量使用Unicode。在Python2中编码是很让人头痛的一件事,但Python3就不用过多考虑了
建议18:构建合理的包层次来管理Module
3. 基础用法 建议19:有节制的使用from…import语句,防止污染命名空间
建议20:优先使用absolute import来导入模块(Python3中已经移除了relative import)
建议21:i+=1不等于++i,在Python中,++i前边的加号仅表示正,不表示操作
建议22:习惯使用with自动关闭资源,特别是在文件读写中
建议23:使用else子句简化循环(异常处理)
建议24:遵循异常处理的几点基本原则
(1)注意异常的粒度,try块中尽量少写代码
(2)谨慎使用单独的except语句,或except Exception语句,而是定位到具体异常
(3)注意异常捕获的顺序,在合适的层次处理异常
(4)使用更加友好的异常信息,遵守异常参数的规范
建议25:避免finally中可能发生的陷阱
建议26:深入理解None,正确判断对象是否为空。
建议27:连接字符串应优先使用join函数,而不是+操作
建议28:格式化字符串时尽量使用.format函数,而不是%形式
建议29:区别对待可变对象和不可变对象,特别是作为函数参数时
建议30:[], {}和():一致的容器初始化形式。使用列表解析可以使代码更清晰,同时效率更高
建议31:函数传参数,既不是传值也不是传引用,而是传对象或者说对象的引用
建议32:警惕默认参数潜在的问题,特别是当默认参数为可变对象时
建议33:函数中慎用变长参数 args和 kargs
(1)这种使用太灵活,从而使得函数签名不够清晰,可读性较差
(2)如果因为函数参数过多而是用变长参数简化函数定义,那么一般该函数可以重构
建议34:深入理解str()和repr()的区别
(1)两者之间的目标不同:str主要面向客户,其目的是可读性,返回形式为用户友好性和可读性都比较高的字符串形式;而repr是面向Python解释器或者说Python开发人员,其目的是准确性,其返回值表示Python解释器内部的定义
(2)在解释器中直接输入变量,默认调用repr函数,而print(var)默认调用str函数
这个靶场是一个对渗透新手很友好的靶场。而且,该靶场包含了渗透测试的信息收集,漏洞利用和权限提升的全过程,对新手理解渗透测试的流程有很好的帮助。
靶场地址: https://hackmyvm.eu/machines/machine.php?vm=Hundred
靶场基本情况:
KALI靶机:192.168.1.3/24 主机:192.168.1.146/24 目标:普通用户flag和管理员flag
信息收集阶段: nmap -sn 192.168.1.0/2
sudo nmap -v -T4 -p- -A -oN nmap.log 192.168.1.146
nmap -A 192.168.1.146
这里我们看到开启了21端口,22端口和80端口:
【一>所有资源关注我,私信回复“资料”获取<一】 1、网络安全学习路线 2、电子书籍(白帽子) 3、安全大厂内部视频 4、100份src文档 5、常见安全面试题 6、ctf大赛经典题目解析 7、全套工具包 8、应急响应笔记
漏洞利用阶段: 我们连接下21端口:
用户名和密码都是ftp,然后查看当前目录文件,可见密钥文件和users.txt文件。
其实用户名是ftp,密码是什么,都可以登录!
这里采用mget,将所有文件下载到本地!这里采用mget可以一次性下载多个文件!
id_rsa文件:私钥是个兔子!
公钥文件,看着挺正常!
接下来,查看下id_rsa.pem文件!这个像是私钥文件!
然后,查看用户名文件!最后那个感谢的像是真正的用户名!
可以这里我们试着用着这个私钥文件通过SSH登录下hmv这个文件!
嘿嘿嘿,不行!
这条路暂时不同,接着咱们看下那个开放的80端口,直接访问下看看!!!
一个方块?
貌似出题人,打靶场打的魔怔了!
查看源代码,发现了端倪!
上面是个文件,下面是个目录!?先下载下来看看
wget http://192.168.1.146/h4ckb1tu5.enc
这个页面作为一个整体告诉我们可以通过这个key值获取一个目录。而且,我们也可以从logo图片获取一些信息通过图片隐写术。回到这个key值,我们可以通过RSA私钥和OpenSSL rsautl解码信息。通过解码信息获取一个文件。
接下来,我们用私钥文件和下载下来不知道啥玩意的文件生成目录!
访问下看看!192.168.1.146/,方向没错!!!
查看源代码?啥也没有?
网站的目录扫描有要点,一层一层的扫描!!!
来个超级字典!
https://github.com/danielmiessler/SecLists/releases/tag/2022.1
扫一波目录:
gobuster dir -w /root/Web-Content/common.txt -u http://192.168.1.146/softyhackb4el7dshelldredd/
然后,把这个私钥下载下来:
wget http://192.168.1.146/softyhackb4el7dshelldredd/id_rsa
目录
1.查看当前运行的进程信息
2.结束某个进程
3.查看磁盘空间
4.查看内存占用
1.查看当前运行的进程信息 top -d5 //实时查看系统所有进程所使用的资源,ctrl+Z或者q 退出,每5秒更新一次,默认为3秒 top -o %MEM //按照内存占用排序,同理使用 %CPU 按CPU使用率排序 ps -l //查看当前shell运行进程 ps -le //系统中的运行进程以及父子进程信息 ps aux //查看系统中所有运行进程 clear //清空命令行界面 2.结束某个进程 kill <pid> //结束进程(通过进程ID) kill -9 <pid> //强制结束进程 pkill <进程名> //结束进程(通过进程名) 3.查看磁盘空间 df -h 显示磁盘空间 sudo fdisk -l 可以显示磁盘大小以及磁盘分区信息。 4.查看内存占用 上述top指令也会输出总内存的占用情况。命令都是从 /proc/meminfo 虚拟文件中获取内存使用信息的,所以可以直接读取该文件。
cat /proc/meminfo //系统以及内核内存使用情况 free -h //显示系统中空闲和已用内存大小 (更加简单明了,有点像上面cat指令的简化总结版) du -sh <文件名> //输出文件占用内存大小,不加文件名则输出当前所在目录占用内存 du -sh ./* //当前目录下所有文件和文件夹分别占用的内存
摘要: 了解用户想要什么信息是信息科学和技术面临的最大挑战。隐式反馈是解决这一挑战的关键,因为它允许信息系统了解用户的需求和偏好。然而,可用的反馈往往是有限的,而且其解释也很困难。为了应对这一挑战,我们提出了一项用户研究,探索追踪眼动是否可以解开相关性和相关性决策固有的部分复杂性。将阅读18篇新闻文章的 30名参与者的眼睛行为与他们在话语层面上主观评价的理解力和兴趣进行了比较。 使用线性回归模型,眼球追踪信号解释了49.93%(可理解性)和 30.41%(兴趣)的方差 (p < .001)。 我们得出结论,眼睛行为提供了超准确性的隐式反馈,从而为个性化信息系统提供了新形式的适应和交互支持。
1.引言 理解和了解用户在信息方面的需求是信息系统面临的最大挑战(Saracevic, 2007)。文本挖掘技术目前用于通过估计文档是否与查询相似(信息检索)、是否在相似的人或朋友中流行(协同过滤)或与用户模型相似(认知过滤)来推断用户的信息需求。尽管这些技术无疑是成功的,但它们似乎被一个神奇的障碍所困扰:它们预测信息价值的潜力有限(Said & Bellogín, 2018; Voorhees, 2002)。当前的技术难以适应用户之间的差异,例如他们的知识和偏好,以及用户内部的差异,例如不断变化的信息需求和兴趣(Hill, 1995)。由于每个用户的信息价值不同,并且会随时间变化(Belkin, 2008; Saracevic, 2007),因此需要持续反馈以更好地预测信息是否以及何时对用户有价值(Ghorab, 2013; Liu, 2020)。
要求用户就他们想要的信息提供大量和持续的输入是不可能成功的。相反,不需要用户进行任何交互的隐式反馈是一个更可行的选择(Barra, 2016; Ghorab, 2013; Liu, 2020)。基本的在线措施已经成功地用于文本挖掘。 来自点击流数据、浏览数据和查询文本关系的特征将二进制排名精度提高到高达 31%(Agichtein, 2006)、预测分级相关性评估高达 r = .411(Guo & Agichtein, 2012)。此外,生理信号(Barral, 2016 ),尤其是眼动追踪(Li,2018)有望扩展这些结果(Cole, 2015)。对于相关和不相关的结果,人类的注意力遵循一种独特且可识别的模式(Li, 2018)。眼球追踪数据可以显示关注了哪些搜索结果或文档的哪些部分,并将其用作查询扩展、优化(Buscher, 2012)甚至构建(Ajanki, 2009)。 在二进制文本挖掘精度上,可以通过眼动追踪检测到相关性,精度为 64%(Liu,2014)、74%(Gwizdka,2014)、80%(Bhattacharya,2020)和 86%(Gwizdka,2017)。
从眼动数据预测(二元)相关性决策的表现证实了其在隐式反馈方面的潜力。尽管如此,相关性的直观概念包含了人类判断和经验的巨大复杂性。用户在判断相关性时会应用一系列标准,例如文档的时事性、可信度、风格和阅读水平 (Schamber, 1994) 以及电影的故事和视觉效果 (Adomavicius & Kwon, 2015)。 人类判断的这种巨大复杂性随后形成了相关的认知情感体验(Ruthven,2021)。在一个不断发展的交互会话中,一套特定的元认知判断和体验展开了,比如用户对处理动态的反思。认知上的轻松通常与满意的感觉相关(Al-Maskari & Sanderson, 2010),而中间的复杂性似乎与兴趣的感觉相关(Dubey & Griffiths, 2020; van der Sluis, 2014)。在互动过程中,这些认知-情感判断和体验的重要性表明了 "超越传统准确性指标 "的反馈潜力(McNee, 2006)
【深度学习:数据增强】计算机视觉中数据增强的完整指南 为什么要做数据增强?等等,什么是数据增强?数据增强技术数据增强的注意事项和潜在陷阱什么时候应该做数据增强?类不平衡的数据增强那么我应该选择哪些转换呢?视频数据增强 如何实现数据增强专业人士使用哪些技术?高级技术,即“我不能使用 GAN 生成完全独特的数据吗”?结论 为什么要做数据增强? 可能面临的一个常见挑战是模型的过拟合。这种情况发生在模型记住了训练样本的特征,但却无法将其预测能力应用到新的、未见过的图像上。过拟合在计算机视觉中尤为重要,在计算机视觉中,我们处理高维图像输入和大型、过度参数化的深度网络。有许多现代建模技术可以解决这个问题,包括基于丢弃的方法、标签平滑或架构,这些方法可以减少所需的参数数量,同时仍能保持拟合复杂数据的能力。但是,对抗过拟合的最有效方法之一是数据本身。
深度学习模型通常需要大量数据,而提高模型性能的一种有效方法是提供更多数据,这是深度学习的核心要素。这可以通过两种方式完成:
增加原始数据量。这是通过增加数据集中的图像数量来实现的,从而扩充了图像的基本分布,并有助于优化模型的决策边界,对抗过拟合。您拥有的样本越多(比如来自分类问题的特定类别),您就能更准确地描述该类别的特征。增加数据集的多样性。值得一提的是,无法泛化到新数据也可能是由数据集/分布偏移引起的。想象一下,使用一组训练后的狗在公园里的图像对狗品种进行分类,但在生产中的其他地方看到狗。扩大训练数据集以包含这些类型的图像可能会对模型的泛化能力产生巨大影响。(但大多数时候,图像增强将无法解决这个问题)。 然而,收集数据通常既昂贵又耗时。例如,在医疗保健应用中,收集更多数据通常需要接触患有特定疾病的患者,熟练的医疗专业人员花费大量时间和精力来收集和注释数据,并且通常使用昂贵的成像和诊断设备。在许多情况下,“获取更多数据”的解决方案将非常不切实际。此外,除了在迁移学习中使用之外,公共数据集通常并不适用于定制的计算机视觉问题。如果有某种方法可以在不返回数据收集阶段的情况下增加数据集的大小,那不是很好吗?这就是数据增强。
等等,什么是数据增强? 数据增强是通过各种转换从现有训练样本中生成新的训练样本。它是一种非常有效的正则化工具,几乎所有 CV 问题和模型的专家都在使用它。数据增强可以以一种非常简单有效的方式将几乎任何图像训练集的大小增加 10 倍、100 倍甚至无限大。从数学上讲:
更多的数据=更好的模型。数据增强 = 更多数据。因此,数据增强 = 更好的机器学习模型。
数据增强技术 用于数据增强的常见图像转换。 上图所示的方法列表绝不是详尽无遗的。还有无数其他方法可以操作图像和创建增强数据。你只受限于自己的创造力!
也不要觉得只限于孤立地使用每种技术。您可以(并且应该)将它们链接在一起,如下所示:
外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传
多重转换 单源图像增强组合的更多示例。 数据增强的注意事项和潜在陷阱 毋庸置疑,在将数据集拆分为训练、验证和测试子集后,应该进行任何数据增强。否则,您将在模型中造成重大数据泄漏,并且您的测试结果将毫无用处。如果您正在执行基于本地化的任务(如对象检测或分割),则在应用几何变换(如反射(翻转)、旋转、平移和裁剪)时,您的标签将发生变化。因此,您还需要将相同的转换应用于标签注释。裁剪图像时,会更改模型输入的大小和形状。对于卷积神经网络模型,您需要所有输入(包括测试集)具有相同的维度。处理此问题的常用方法是将裁剪转换也应用于测试集和验证集。调整图像大小是另一种选择。其中一些转换(如平移、旋转或缩放)可能会导致“空白区域”,即转换后的图像未完全覆盖输入模型的网格空间。在这些情况下,您可以使用恒定的黑/白/灰像素、随机噪声或扩展原始图像内容的插值来填充多余的像素。注意不要裁剪或平移太多,以免从图像中完全删除相关对象。当您知道对象检测任务中的边界框时,这很容易检测到,但如果完全裁剪掉与标签对应的对象,则可能会成为图像分类的问题。数据增强通常只在训练集上执行。虽然它也可以用作在非常小的验证甚至测试集中减少方差的策略,但在对测试集进行任何更改时应始终非常小心。您希望测试数据是对推理时间分布中看不见的示例的性能的无偏估计,而增强数据集可能与该分布不同。不建议同时使用过多的增强技术。你可能会想通过组合所有列出的转换来一次把所有东西都扔进去,厨房水槽,但这会很快使生成的图像变得非常不真实,人类无法识别,并且还会导致上述点中概述的潜在问题。使用所有这些转换并没有错,只是不要一次组合所有这些转换。 话虽如此,转换后的图像并不需要完美才能有用。数据量往往会超过数据质量。示例越多,异常值/错误图像对模型的不利影响就越小,数据集的多样性就越大。
尽管数据增强几乎总是对模型性能有积极影响,但它并非解决所有与数据集大小相关问题的灵丹妙药。你不能指望使用50张图像的微小数据集,使用上述技术将其放大到50,000张,并获得50,000张数据集的所有好处。数据增强可以帮助使模型对旋转、平移、照明和相机伪影等内容更加鲁棒,但不适用于其他变化,例如不同的背景、透视、对象外观的变化、场景中的相对位置等。
什么时候应该做数据增强? 您可能想知道“我应该在什么时候使用数据增强?什么时候有好处?答案是:总是!数据增强通常有助于规范化和改进您的模型,如果您以合理的方式应用它,则不太可能有任何缺点。唯一可以跳过它的情况是,如果你的数据集非常庞大和多样化,以至于增强不会为其增加任何有意义的多样性。但是我们大多数人都没有奢侈地使用这样的童话数据集🙂。
类不平衡的数据增强 扩增法也可用于处理类不平衡问题。与使用基于抽样或加权的方法相比,你可以简单地增加较小的类,使所有类的大小相同。
那么我应该选择哪些转换呢? 没有一个确切的答案,但你应该从思考自己的问题开始。转换生成的图像是否完全超出了现实世界的支持范围?即使公园里一棵树的倒立图像不是你在现实生活中会看到的,你也可能会看到一棵倒下的树的类似方向。不过,有些变换可能需要重新考虑,例如:
垂直反射(倒置)十字路口的停车标志,用于自动驾驶中的物体识别。倒置的身体部位或模糊/彩色图像,用于放射学图像,其方向、光照和清晰度始终保持 一致。道路和社区卫星图像上的网格失真。(尽管这可能是应用轮换的最佳位置之一)。数字分类 (MNIST) 的 180 度旋转。这种转换将使您的 6 看起来像 9,反之亦然,同时保留原始标签。 你的转换不一定是完全现实的,但你绝对应该使用在实践中可能发生的任何转换。
除了对任务和领域的了解,对数据集的了解也很重要。更好地了解数据集中图像的分布情况,可以让您更好地选择哪种增强技术能为您带来合理的结果,甚至可能帮助您填补数据集中的空白。Encord Active 是帮助您探索数据集、可视化图像属性分布和检查图像数据质量的一个很好的工具。
然而,我们是工程师和数据科学家。我们不只是根据猜想做出决定,我们还要尝试和进行实验。我们拥有久经考验的模型验证和超参数调整技术。我们可以简单地尝试不同的技术,并选择在验证集上性能最大化的组合。
如果您需要一个良好的起点:水平反射(水平翻转)、裁剪、模糊、噪点和图像擦除方法(如剪切或随机擦除)是一个良好的基础。然后,你可以尝试将它们组合在一起,并添加亮度和色彩变化。
视频数据增强 视频数据的增强技术与图像数据非常相似,但有一些区别。通常,所选的变换将以相同的方式应用于视频中的每一帧(噪点除外)。修剪视频以创建较短的片段也是一种流行的技术(时间裁剪)。
如何实现数据增强 实施的具体细节取决于硬件、所选的深度学习库、所选的转换等。但通常有两种策略可以实现数据增强:离线和在线。
离线增强: 离线数据增强是指计算一个新的数据集,其中包括所有原始图像和转换后的图像,并将其保存到磁盘中。然后像往常一样,使用增强数据集而不是原始数据集来训练模型。这可能会大大增加所需的磁盘存储空间,因此我们不建议您这样做,除非您有特殊原因(如验证增强图像的质量或控制训练过程中显示的准确图像)。
在线扩增: 这是最常见的数据增强方法。在在线增强中,每次加载图像时都会对图像进行转换。在这种情况下,模型在每个时间点都会看到不同的图像变换,变换结果不会保存到磁盘中。通常情况下,变换会在每个纪元随机应用于图像。例如,您将在每个时区随机决定是否翻转图像、执行随机裁剪、采样模糊/锐化量等。
在线和离线数据扩增过程。 专业人士使用哪些技术? 您可能仍然想知道:"训练最先进模型的人是如何使用图像增强技术的?让我们一起来看看:
论文数据增强技术LeNet-5 Translate, Scale, Squeeze, ShearAlexNet Translate, Flip, Intensity ChangingResNet Crop, FlipMobileNet Flip, Crop, TranslateNasNet Crop, Elastic distortionResNeStAutoAugment, Mixup, CropDeiTAutoAugment, RandAugment, Random erasing, Mixup, CutMixSwin Transformer RandAugment, Mixup, CutMix, Random erasingU-Net Translate, Rotate, Gray value variation, Elastic deformationFaster R-CNNFlipYOLO Scale, Translate, Color spaceSSD Crop, Resize, Flip, Color Space, DistortionYOLOv4 Mosaic, Distortion, Scale, Color space, Crop, Flip, Rotate, Random erase, Cutout, Hide and Seek, GridMask, Mixup, CutMix, StyleGAN Erasing/Cutout: 等等,这些剪切-混合-然后-修改的东西是什么?其中一些像剪切、随机擦除和网格掩码都是图像擦除方法。执行擦除时,您可以在图像中剪切出正方形、不同形状的矩形,甚至多个单独的剪切/蒙版。还有多种方法可以使该过程随机化。擦除是一种流行的策略,例如,在图像分类的背景下,可以迫使模型学习识别每个单独部分的对象,而不仅仅是通过擦除最独特的部分来识别最独特的部分(例如学习识别狗)通过爪子和尾巴,而不仅仅是脸)。擦除可以被认为是一种“输入空间中的丢失”。
使用Spring Cache优化数据库访问 在这篇博客中,我们将学习如何使用Spring Cache来优化数据库访问,提高系统性能。我们将创建一个简单的图书管理应用作为示例,并演示如何通过缓存减少对数据库的频繁查询。
1. 项目结构 首先,我们看一下项目的基本结构:
lfsun-study-cacheable |-- src | |-- main | |-- java | |-- com.lfsun.cacheable | |-- controller | |-- BookController.java | |-- dao | |-- BookRepository.java | |-- entity | |-- Book.java | |-- service | |-- BookService.java | |-- impl | |-- BookServiceImpl.java | |-- LfsunStudyCacheableApplication.java | |-- resources | |-- application.properties |-- pom.xml 2. 项目依赖 我们使用了Spring Boot和Spring Data JPA来简化项目配置。以下是主要的Maven依赖:
<!-- Spring Boot Starter --> <dependency> <groupId>org.
一、什么是网络安全 网络安全是一种综合性的概念,涵盖了保护计算机系统、网络基础设施和数据免受未经授权的访问、攻击、损害或盗窃的一系列措施和技术。经常听到的 “红队”、“渗透测试” 等就是研究攻击技术,而“蓝队”、“安全运营”、“安全运维”则研究防御技术。作为一个合格的网络安全工程师,应该做到攻守兼备,毕竟知己知彼,才能百战百胜。 二、网络安全怎么入门 安全并非孤立存在,而是建立在其计算机基础之上的应用技术。脱离这个基础,就容易陷入纸上谈兵的境地,出现“知其然,不知其所以然”的情况,这在安全职业道路上难以取得长远成就。
如果你之前是从事网工的,可以选择网络安全方向入门;
如果你之前是从事程序开发的,推荐选择Web安全/渗透测试方向入门。
然而,随着学习深入或者工作经验的积累,不同方向的技术耦合逐渐增加,要求在各个方向都能有一定的了解。
网安技能表
《----------学习资源免费领取,一个评论即可----------》
1、网安学习线路图2、老师教学笔记50份PDF3、渗透测试技巧及电子书86份4、攻防演练记录及笔记35份5、网安工具包,32G6、网安自学必看书籍352份PDF,28G7、120个漏洞实战演练案例8、网安面试题、CTF竞赛题等130份9、专业老师搭建实战靶场30个10、实训社群资源13000人 →→→→→→→→→&关注告诉我,点赞收藏评论区留言 “已关注 求 ” !&
三、网络安全的知识多而杂,怎么合理安排学习? 1、基础阶段
中华人民共和国网络安全法 (包含19个知识点)Linux操作系统 (包含15个知识点)计算机网络 (包含15个知识点)SHELL (包含13个知识点)HTML/CSS (包含45个知识点)JavaScript (包含42个知识点)PHP入门(包含13个知识点)MySQL数据库 (包含32个知识点)Python (包含19个知识点) 入门的首要步骤是有系统地学习计算机基础知识,即深入研究以下几个基础知识领域:操作系统、协议/网络、数据库、开发语言以及常见漏洞原理。一旦掌握了前述基础知识,就应着手进行实际操作。 2、渗透阶段
SQL注入的渗透与防御(包含38个知识点)XSS相关渗透与防御(包含15个知识点)上传验证渗透与防御(包含14个知识点)文件包含渗透与防御(包含13个知识点)CSRF渗透与防御(包含8个知识点)SSRF渗透与防御(包含6个知识点)XXE渗透与防御(包含7个知识点)远程代码执行渗透与防御(包含8个知识点) 熟悉常见漏洞的原理、使用方法和防御等方面的知识是必要的。在进行Web渗透的阶段,了解一些关键工具也是重要的。需要掌握的主要工具和平台包括:Burp、AWVS、Appscan、Nessus、Sqlmap、Nmap、Shodan、Fofa、以及代理工具SSRS、Hydra、Medusa、Airspoof等。对这些工具的实践可以通过上述提到的开源靶场进行,足以满足需求。 3、安全管理(提升)
渗透报告编写(包含22个知识点)等级保护2.0(包含51个知识点)应急响应(包含6个知识点)代码审计(包含9个知识点)风险评估(包含12个知识点)安全巡检(包含14个知识点)数据安全(包含26个知识点) 主要内容包括渗透测试报告的编写、网络安全等级的定级、应急响应、代码审计、风险评估、安全巡检、数据安全、法律法规汇编等方面。这个阶段主要面向那些已经从事网络安全相关工作,希望提升至管理层职位的人员。如果你的职业方向是网络安全工程师,那么这个阶段的学习可能是可选的。 4、提升阶段(提升)
密码学(包含35个知识点)JavaSE入门(包含95个知识点)C语言(包含145个知识点)C++语言(包含186个知识点)Windows逆向(包含48个知识点)CTF夺旗赛(包含38个知识点)Android逆向(包含42个知识点) 涵盖的内容主要有密码学、JavaSE、C语言、C++、Windows逆向、CTF夺旗赛、Android逆向等。这个阶段的学习主要面向那些已经从事网络安全相关工作,希望提升至进阶安全架构领域的人员。 四、网络安全学习路线 若你真心希望通过自学方式初探Web安全领域,我建议你查阅以下学习路线图。该路线图详细指导每个知识点的学习时长和学习方法,全程自学时间约为半年左右,亲测有效(文末有惊喜)。
1. 网络安全概念学习(2周)
掌握基本概念,包括SQL注入、文件上传、XSS、CSRF、一句话木马等。使用关键字(SQL注入、文件上传、XSS、CSRF、一句话木马等)进行Google/SecWiki搜索。阅读《精通脚本黑客》。尽管内容古老并可能存在错误,但仍适合入门。查阅渗透笔记/视频,了解整个渗透实战过程。使用搜索词(渗透笔记、渗透过程、入侵过程等)。 2. 渗透工具熟悉(3周)
熟悉AWVS、sqlmap、Burp、Nessus、Chopper、Nmap、Appscan等相关工具的使用。了解这些工具的用途和使用场景,首先通过软件名字在Google/SecWiki上搜索。下载这些工具的无后门版本进行安装。学习并实践使用,搜索SecWiki上的具体教材,如Burp的教程、sqlmap。熟练掌握这些常用工具后,可以考虑安装音速启动,构建渗透工具箱。 3. 渗透实战操作(5周)
掌握渗透的整个阶段,能够独立渗透小型站点。在网上找渗透视频,思考其中的思路和原理,使用关键字(渗透、SQL注入视频、文件上传入侵、数据库备份、dedecms漏洞利用等等)。自己找站点或搭建测试环境进行测试,注意隐藏个人身份。思考渗透主要分为几个阶段,每个阶段需要做哪些工作,例如PTES渗透测试执行标准。研究SQL注入的种类、注入原理、手动注入技巧。研究文件上传的原理,包括如何进行截断、双重后缀欺骗(IIS、PHP)、解析漏洞利用(IIS、Nginx、Apache)等,参考上传攻击框架。研究XSS形成的原理和种类,具体学习方法可以在Google/SecWiki搜索,也可以参考XSS。研究Windows/Linux提权的方法和具体使用,参考提权。可以参考开源渗透测试脆弱系统。 4. 关注安全领域动态(1周)
关注安全领域的最新漏洞、安全事件和技术文章。通过SecWiki浏览每日的安全技术文章和事件。在Weibo/Twitter关注安全领域的从业人员,尤其是大牛或者同行,每天抽时间浏览。使用feedly/鲜果订阅国内外安全技术博客,不仅限于国内,多积累关键信息。SecWiki的聚合栏目也是一个不错的选择。养成习惯,每天主动提交安全技术文章链接到SecWiki,进行分享和积累。多关注最新漏洞信息,推荐一些平台:exploit-db、CVE中文库、乌云等,实践公开漏洞利用。 5. 熟悉Windows/Kali Linux(3周)
学习Windows/Kali Linux的基本命令和常用工具。熟悉Windows下的常用cmd命令,例如ipconfig、nslookup、tracert、net、tasklist、taskkill等。熟悉Linux下的基本命令,如ifconfig、ls、cp、mv、vi、wget、service、sudo等。掌握Kali Linux系统下的常用工具,可以参考SecWiki、《Web Penetration Testing with Kali Linux》、《Hacking with Kali》等。熟悉metasploit工具的使用,可以参考SecWiki、《Metasploit渗透测试指南》。 6. 服务器安全配置(3周)
学习服务器环境配置,能够通过思考发现配置中存在的安全问题。针对Windows 2003/2008环境下的IIS配置,特别注意配置安全和运行权限,参考SecWiki-配置。针对Linux环境下的LAMP安全配置,主要考虑运行权限、跨目录、文件夹权限等,参考SecWiki-配置。进行远程系统加固,限制用户名和口令登录,通过iptables限制端口。配置软件WAF以加强系统安全,在服务器配置mod_security等系统,参见SecWiki-ModSecurity。使用Nessus软件对配置环境进行安全检测,发现未知安全威胁。 7.
🥳🥳Welcome Huihui's Code World ! !🥳🥳 接下来看看由辉辉所写的关于SpringCloud的相关操作吧
目录
🥳🥳Welcome Huihui's Code World ! !🥳🥳
一.注册中心组件是什么
二.注册中心组件的详解 生活例子
例子分析
三. 代码演示注册中心组件的特点
1.依赖引入
(1)pom
(2)yml
①消费者
②生产者
2.生产者
启动类
controller
3.消费者
启动类
controller
上篇我详细的讲解了SpringCloud到底是什么,也通过生活中的例子去生动说明了,大家如果对于SpringCloud还是又疑问的话,可以看一下上一篇博文
那么这篇我就来详述一下SpringCloud中的核心组件--注册中心组件,也还是会结合生活例子来说明,这样也利于理解。
一.注册中心组件是什么 注册中心是一种分布式系统中的组件,用于管理服务实例的注册和发现。在微服务架构中,服务可以被拆分成多个小的模块,这些模块可能部署在不同的主机和容器中。因此,为了让一个服务可以访问其他服务,它需要知道其他服务的地址和端口信息。而注册中心就是用来管理这些信息的。
注册中心组件通常提供以下功能:
服务注册:服务提供者将自己的服务注册到注册中心中,包括服务名称、IP地址、端口号等信息。服务发现:服务消费者从注册中心中查询可用的服务列表,并选择一个可用的服务进行调用。服务健康检查:注册中心能够检测服务是否健康,及时剔除不健康的服务实例,避免服务调用失败。负载均衡:注册中心可以根据一定的负载均衡策略,为服务消费者选择一个合适的服务实例进行调用。 二.注册中心组件的详解 如果只是说注册中心组件的定义,感觉太官方了,脑海中不能出现一个画面感,所以我这里按照自己的理解,给大家举一个通俗易懂的例子
生活例子 假设你需要看病
你去了一家大型医院
这个医院有很多个科室(类似于微服务)
...
每个科室都提供不同的医疗服务。你需要看的是内科,但是你不知道内科是在哪个楼层、哪个区域。这个时候你通常会找到导诊台,去询问内科位于哪个楼层的哪个区域
然后导诊台中的工作人员便会去告诉你具体的位置
例子分析 例子中的导诊台就相当于注册中心的这个组件,导诊台中管理着这个医院各个科室的信息,注册中心组件中管理着其他服务的地址和端口信息。有了导诊台,我们看病就不需要在整个医院中无脑寻找对应科室了,同样的,有了注册中心的组件,我们也不需要在整个服务中去寻找对应的服务。这样就可以节省很多的时间,提高效率。
三. 代码演示注册中心组件的特点 这里写的代码就是一个生产者拿取消费者中返回回来的信息【水蜜桃】
1.依赖引入 (1)pom 这里写一个module代表生产者,一个module代表消费者。其中也需要引入依赖,两个module中肯定有相同的依赖,那么我们可以把整个两个module都写在同一个maven项目下,
然后再把相同的依赖放在那个大项目中,如果两个module有用到其他的依赖,则可以直接在自身的pom文件中引入相应依赖。
父项目的依赖
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <!-- 项目组织ID --> <groupId>org.example</groupId> <!
OpenCV直方图是一种可以对整幅图的灰度分布进行整体了解的图示。它是带有像素值(从0到255,不总是)的图在X轴上,在y轴上的图像对应的像素个数。通过观察图像的直方图,我们可以直观的了解图像的对比度、亮度、亮度分布等。
在直方图中,横坐标表示图像中各个像素点的灰度级,纵坐标表示具有该灰度级的像素个数。直方图的左边部分显示了图像中较暗像素的数量,右边区域显示了更明亮的像素。
直方图是非常常用的图像处理方法,有时在很多图像预处理中能起到特别好的效果。
一维直方图 OpenCV中,直方图是调用calxHist函数,该函数的参数比较多,不太好理解
The function cv::calcHist calculates the histogram of one or more arrays. The elements of a tuple used to increment a histogram bin are taken from the corresponding input arrays at the same location. The sample below shows how to compute a 2D Hue-Saturation histogram for a color image. : @include snippets/imgproc_calcHist.cpp @param images Source arrays. They all should have the same depth, CV_8U, CV_16U or CV_32F , and the same size.