前端技术
HTML
CSS
Javascript
前端框架和UI库
VUE
ReactJS
AngularJS
JQuery
NodeJS
JSON
Element-UI
Bootstrap
Material UI
服务端和客户端
Java
Python
PHP
Golang
Scala
Kotlin
Groovy
Ruby
Lua
.net
c#
c++
后端WEB和工程框架
SpringBoot
SpringCloud
Struts2
MyBatis
Hibernate
Tornado
Beego
Go-Spring
Go Gin
Go Iris
Dubbo
HessianRPC
Maven
Gradle
数据库
MySQL
Oracle
Mongo
中间件与web容器
Redis
MemCache
Etcd
Cassandra
Kafka
RabbitMQ
RocketMQ
ActiveMQ
Nacos
Consul
Tomcat
Nginx
Netty
大数据技术
Hive
Impala
ClickHouse
DorisDB
Greenplum
PostgreSQL
HBase
Kylin
Hadoop
Apache Pig
ZooKeeper
SeaTunnel
Sqoop
Datax
Flink
Spark
Mahout
数据搜索与日志
ElasticSearch
Apache Lucene
Apache Solr
Kibana
Logstash
数据可视化与OLAP
Apache Atlas
Superset
Saiku
Tesseract
系统与容器
Linux
Shell
Docker
Kubernetes
[对象属性元信息管理与控制]的搜索结果
这里是文章列表。热门标签的颜色随机变换,标签颜色没有特殊含义。
点击某个标签可搜索标签相关的文章。
点击某个标签可搜索标签相关的文章。
ElasticSearch
...领域的数据资产元数据管理、数据血缘上可谓是专家,也涉及资产搜索的特性,它的实现思路就是:从搜索库中做搜索、拿到key、再去存储库中做查询。 搜索库:上图右下角,可以看到使用的是elasticsearch、solr或lucene,多个选一个 存储库:上图左下角,可以看到使用的是Cassandra、HBase或BerkeleyDB,多个选一个 虽然apache atlas在只有搜索库或只有存储库的时候也可以很好的工作,但只针对于数据量并不大的场景。 搜索库,擅长搜索!存储库,擅长海量存储!搜索库多样化搜索,然后去存储库做点查。 当你的数据达到海量的时候,es+hbase也是一种很好的解决方案,不在这里展开说明了。
2024-01-27 17:49:04
538
admin-tim
Mongo
...分区策略。 - 内存管理:MapReduce操作可能会消耗大量内存,特别是在处理大型数据集时。合理设置maxTimeMS选项,限制任务运行时间,避免内存溢出。 - 错误处理:在实际应用中,处理潜在的错误和异常情况非常重要。例如,使用try-catch块捕获并处理可能出现的异常。 4. 进阶技巧与高级应用 对于那些追求更高效率和更复杂数据处理场景的开发者来说,以下是一些进阶技巧: - 使用索引:在Map阶段,如果数据集中有大量的重复键值对,使用索引可以在键的查找过程中节省大量时间。 - 异步执行:对于高并发的应用场景,可以考虑将MapReduce操作异步化,利用MongoDB的复制集和分片集群特性,实现真正的分布式处理。 结语 MapReduce在MongoDB中的应用,为我们提供了一种高效处理大数据集的强大工具。哎呀,看完这篇文章后,你可不光是知道了啥是MapReduce,啥时候用,还能动手在自己的项目里把MapReduce用得溜溜的!就像是掌握了新魔法一样,你学会了怎么给这玩意儿加点料,让它在你的项目里发挥出最大效用,让工作效率蹭蹭往上涨!是不是感觉整个人都精神多了?这不就是咱们追求的效果嘛!嘿,兄弟!听好了,掌握新技能最有效的办法就是动手去做,尤其是像MapReduce这种技术。别光看书上理论,找一个你正在做的项目,大胆地将MapReduce实践起来。你会发现,通过实战,你的经验会大大增加,对这个技术的理解也会更加深入透彻。所以,行动起来吧,让自己的项目成为你学习路上的伙伴,你肯定能从中学到不少东西!让我们继续在数据处理的旅程中探索更多可能性!
2024-08-13 15:48:45
149
柳暗花明又一村
NodeJS
...json文件,用于管理项目的依赖。接下来,我们随便写点代码让这个项目动起来。比如新建一个index.js文件,内容如下: javascript // index.js const http = require('http'); const hostname = '127.0.0.1'; const port = 3000; const server = http.createServer((req, res) => { res.statusCode = 200; res.setHeader('Content-Type', 'text/plain'); res.end('Hello World\n'); }); server.listen(port, hostname, () => { console.log(Server running at http://${hostname}:${port}/); }); 现在你可以直接运行它看看效果: bash node index.js 打开浏览器访问http://127.0.0.1:3000/,你会看到“Hello World”。不错,我们的基础项目已经搭建好了! --- 4. 第一步 编写Dockerfile 接下来我们要做的就是给这个项目添加Docker的支持。为此,我们需要创建一个特殊的文件叫Dockerfile。这个名字是固定的,不能改哦。 进入项目根目录,创建一个空文件名为Dockerfile,然后在里面输入以下内容: dockerfile 使用官方的Node.js镜像作为基础镜像 FROM node:16-alpine 设置工作目录 WORKDIR /app 将当前目录下的所有文件复制到容器中的/app目录 COPY . /app 安装项目依赖 RUN npm install 暴露端口 EXPOSE 3000 启动应用 CMD ["node", "index.js"] 这段代码看起来有点复杂,但其实逻辑很简单: 1. FROM node:16-alpine 告诉Docker从官方的Node.js 16版本的Alpine镜像开始构建。 2. WORKDIR /app 指定容器内的工作目录为/app。 3. COPY . /app 把当前项目的文件拷贝到容器的/app目录下。 4. RUN npm install 在容器内执行npm install命令,安装项目的依赖。 5. EXPOSE 3000 声明应用监听的端口号。 6. CMD ["node", "index.js"]:定义容器启动时默认执行的命令。 保存完Dockerfile后,我们可以试着构建镜像了。 --- 5. 构建并运行Docker镜像 在项目根目录下运行以下命令来构建镜像: bash docker build -t my-node-app . 这里的. 表示当前目录,my-node-app是我们给镜像起的名字。构建完成后,可以用以下命令查看是否成功生成了镜像: bash docker images 输出应该类似这样: REPOSITORY TAG IMAGE ID CREATED SIZE my-node-app latest abcdef123456 2 minutes ago 150MB 接着,我们可以启动容器试试看: bash docker run -d -p 3000:3000 my-node-app 参数解释: - -d:以后台模式运行容器。 - -p 3000:3000:将主机的3000端口映射到容器的3000端口。 - my-node-app:使用的镜像名称。 启动成功后,访问http://localhost:3000/,你会发现依然可以看到“Hello World”!这说明我们的Docker化部署已经初步完成了。 --- 6. 进阶 多阶段构建优化镜像大小 虽然上面的方法可行,但生成的镜像体积有点大(大约150MB左右)。有没有办法让它更小呢?答案是有!这就是Docker的“多阶段构建”。 修改后的Dockerfile如下: dockerfile 第一阶段:构建阶段 FROM node:16-alpine AS builder WORKDIR /app COPY package.json ./ RUN npm install COPY . . RUN npm run build 假设你有一个build脚本 第二阶段:运行阶段 FROM node:16-alpine WORKDIR /app COPY --from=builder /app/dist ./dist 假设build后的文件存放在dist目录下 COPY package.json ./ RUN npm install --production EXPOSE 3000 CMD ["node", "dist/index.js"] 这里的关键在于“--from=builder”,它允许我们在第二个阶段复用第一个阶段的结果。这样就能让开发工具和测试依赖 stays 在它们该待的地方,而不是一股脑全塞进最终的镜像里,这样一来镜像就能瘦成一道闪电啦! --- 7. 总结与展望 写到这里,我相信你已经对如何用Docker部署Node.js应用有了基本的认识。虽然过程中可能会遇到各种问题,但每一次尝试都是成长的机会。记得多查阅官方文档,多动手实践,这样才能真正掌握这项技能。 未来,随着云计算和微服务架构的普及,容器化将成为每个开发者必备的技能之一。所以,别犹豫啦,赶紧去试试呗!要是你有什么不懂的,或者想聊聊自己的经历,就尽管来找我聊天,咱们一起唠唠~咱们一起进步! 最后,祝大家都能早日成为Docker高手!😄
2025-05-03 16:15:16
35
海阔天空
Hive
...性,尤其是在涉及敏感信息的情况下。因此,在采用新的压缩技术时,企业需要仔细评估其安全性、兼容性和维护成本,确保技术的实际效益最大化。总之,随着技术的不断进步,数据压缩正成为大数据领域的一个重要研究方向,未来还有很大的发展空间。
2025-04-19 16:20:43
45
翡翠梦境
转载文章
...表本站的立场。 作为信息平台,本站仅提供文章转载服务,并不拥有其所有权,也不对文章内容的真实性、准确性和合法性承担责任。 如发现本文存在侵权、违法、违规或事实不符的情况,请及时联系我们,我们将第一时间进行核实并删除相应内容。 前言 相信搞Java开发的同学都经常会接触到Class类文件,了解了JVM虚拟机之后也会大量接触到class字节码,那么它到底是什么样的文件?内部由什么构成?虚拟机又是如何去识别它的?这篇文章就来学习一下Class类文件的结构。 ps:我在面试蚂蚁的时候被问到过这个问题!你没看错,面试也有可能会问。 一、什么是Class文件 Class文件又称字节码文件,一种二进制文件,它是由某种语言经过编译而来,注意这里并不一定是Java语言,还有可能是Clojure、Groovy、JRuby、Jython、Scala等,Class文件运行在Java虚拟机上。Java虚拟机不与任何一种语言绑定,它只与Class文件这种特定的二进制文件格式所关联。 虚拟机具有语言无关性,它不关心Class文件的来源是何种语言,它只关心Class文件中的内容。Java语言中的各种变量、关键字和运算符号的语义最终都是由多条字节码命名组合而成的,因此字节码命令所能提供的语义描述能力比Java语言本身更加强大。 二、Class文件的结构 虚拟机可以接受任何语言编译而成的Class文件,因此也给虚拟机带来了安全隐患,为了提供语言无关性的功能就必须做好安全防备措施,避免危险有害的类文件载入到虚拟机中,对虚拟机造成损害。所以在类加载的第二大阶段就是验证,这一步工作是虚拟机安全防护的关键所在,其中检查的步骤就是对class文件按照《Java虚拟机规范》规定的内容来对其进行验证。 1.总体结构 Class文件是一组以8位字节为基础单位的二进制流,各个数据项目严格按照顺序紧凑地排列在Class文件之中,中间没有添加任何分隔符,Class文件中存储的内容几乎全部是程序运行的必要数据,没有空隙存在。当遇到需要占用8位字节以上空间的数据项时,就按照高位在前的方式分割成若干个8位字节进行存储。 Class文件格式采用类似于C语言结构体的伪结构来存储数据,这种伪结构只有两种数据类型:无符号数和表。 无符号数属于基本的数据类型,以u1、u2、u4、u8来分别代表1个字节、2个字节、4个字节、8个字节的无符号数,无符号数可以来描述数字、索引引用、数量值或者按照UTF-8编码构成字符串值。 表是由多个无符号数或者其他表作为数据项构成的复合数据类型,所有表都习惯性的以“_info”结尾。表用于描述有层次关系的复合结构的数据,整个Class文件本质上就是一张表,它的数据项构成如下图。 2.魔数(Magic Number) 每一个Class文件的头4个字节成为魔数(Magic Number),它的唯一作用是确定这个文件是否是一个能被虚拟机接收的Class文件。很多文件存储标准中都是用魔数来进行身份识别,比如gif、png、jpeg等都有魔数。使用魔数主要是来识别文件的格式,相比于通过文件后缀名识别,这种方式准确性更高,因为文件后缀名可以随便更改,但更改二进制文件内容的却很少。Class类文件的魔数是Oxcafebabe,cafe babe?咖啡宝贝?至于为什么是这个, 这个名字在java语言诞生之初就已经确定了,它象征着著名咖啡品牌Peet's Coffee中深受欢迎的Baristas咖啡,Java的商标logo也源于此。 3.文件版本(Version) 在魔数后面的4个字节就是Class文件的版本号,第5和第6个字节是次版本号(Minor Version),第7和第8个字节是主版本号(Major Version)。Java的版本号是从45开始的,JDK1.1之后的每个JDK大版本发布主版本号向上加1(JDK1.0~1.1使用的版本号是45.0~45.3),比如我这里是十六进制的Ox0034,也就是十进制的52,所以说明该class文件可以被JDK1.8及以上的虚拟机执行,否则低版本虚拟机执行会报java.lang.UnsupportedClassVersionError错误。 4.常量池(Constant Pool) 在主版本号紧接着的就是常量池的入口,它是Class文件结构中与其他项目关联最多的数据类型,也是占用空间最大的数据之一。常量池的容量由后2个字节指定,比如这里我的是Ox001d,即十进制的29,这就表示常量池中有29项常量,而常量池的索引是从1开始的,这一点需要特殊记忆,因为程序员习惯性的计数法是从0开始的,而这里不一样,所以我这里常量池的索引范围是1~29。设计者将第0项常量空出来是有目的的,这样可以满足后面某些指向常量池的索引值的数据在特定情况下需要表达“不引用任何一个常量池项目”的含义。 通过javap -v命令反编译出class文件之后,我们可以看到常量池的内容 常量池中主要存放两大类常量:字面量和符号引用。比如文本字符、声明为final的常量值就属于字面量,而符号引用则包含下面三类常量: 类和接口的全限名 字段的名称和描述符 方法的名称和描述符 在之前的文章(详谈类加载的全过程)中有详细讲到,在加载类过程的第二大阶段连接的第三个阶段解析的时候,会将常量池中的符号引用替换为直接引用。相信很多人在开始了解那里的时候也是一头雾水,作者我也是,当我了解到常量池的构成的时候才明白真正意思。Java代码在编译的时候,是在虚拟机加载Class文件的时候才会动态链接,也就是说Class文件中不会保存各个方法、字段的最终内存布局信息,因此这些字段、方法的符号引用不经过运行期转换的话无法获得真正的内存入口地址,也就无法直接被虚拟机使用。当虚拟机运行时,需要从常量池获得对应的符号引用,再在类创建时或运行时解析、翻译到具体的内存地址之中。 常量池中每一项常量都是一张表,这里我只找到了JDK1.7之前的常量池项目类型表,见下图。 常量池项目类型表: 常量池常量项的结构总表: 比如我这里测试的class文件第一项常量,它的标志位是Ox0a,即十进制10,即表示tag为10的常量项,查表发现是CONSTANT_Methodref_info类型,和上面反编译之后的到的第一个常量是一致的,Methodref表示类中方法的符号引用。查上面《常量池常量项的结构总表》可以看到Methodref中含有3个项目,第一个tag就是上述的Ox0a,那么第二个项目就是Ox0006,第三个项目就是Ox000f,分别指向的CONSTANT_Class_info索引项和CONSTANT_NameAndType_info索引项为6和15,那么反编译的结果该项常量指向的应该是6和15,查看上面反编译的图应证我们的推测是对的。后面的常量项就以此类推。 这里需要特殊说明一下utf8常量项的内容,这里我以第29项常量项解释,也就是最后一项常量项。查《常量池常量项的结构总表》可以看到utf8项有三个内容:tag、length、bytes。tag表示常量项类型,这里是Ox01,表示是CONSTANT_Utf8_info类型,紧接着的是长度length,这里是Ox0015,即十进制21,那么再紧接着的21个字节都表示该项常量项的具体内容。特别注意length表示的最大值是65535,所以Java程序中仅能接收小于等于64KB英文字符的变量和变量名,否则将无法编译。 5.访问标志(Access Flags) 在常量池结束后,紧接着的两个字节代表访问标志(Access Flags),该标志用于识别一些类或者接口层次的访问信息,其中包括:Class是类还是接口、是否定义为public、是否定义为abstract类型、类是否被声明为final等。 访问标志表 标志位一共有16个,但是并不是所有的都用到,上表只列举了其中8个,没有使用的标志位统统置为0,access_flags只有2个字节表示,但是有这么多标志位怎么计算而来的呢?它是由标志位为true的标志位值取或运算而来,比如这里我演示的class文件是一个类并且是public的,所以对应的ACC_PUBLIC和ACC_SIPER标志应该置为true,其余标志不满足则为false,那么access_flags的计算过程就是:Ox0001 | Ox0020 = Ox0021 篇幅原因,未完待续...... 参考文献:《深入理解Java虚拟机》 END 本篇文章为转载内容。原文链接:https://javar.blog.csdn.net/article/details/97532925。 该文由互联网用户投稿提供,文中观点代表作者本人意见,并不代表本站的立场。 作为信息平台,本站仅提供文章转载服务,并不拥有其所有权,也不对文章内容的真实性、准确性和合法性承担责任。 如发现本文存在侵权、违法、违规或事实不符的情况,请及时联系我们,我们将第一时间进行核实并删除相应内容。
2024-01-09 17:46:36
645
转载
Hadoop
...柱”之一,它专门用来管理海量的数据,就像一个超级大的仓库,能把成千上万的数据文件整整齐齐地存放在不同的电脑上,还能保证它们既安全又容易取用。简单来说,就是把一个大文件分成很多小块,然后把这些小块分散存储在不同的服务器上。这么做的好处嘛,简直太明显了!就算哪台机器突然“罢工”了,数据也能稳稳地保住,完全不会丢。而且呢,还能同时对这些数据进行处理,效率杠杠的! 但是,任何技术都有它的局限性。HDFS虽然功能强大,但在实际应用中也可能会遇到各种问题,比如读取速度慢。这可能是由于网络延迟、磁盘I/O瓶颈或者其他因素造成的。那么,具体有哪些原因会导致HDFS读取速度变慢呢?接下来,我们就来一一分析。 二、可能的原因及初步排查 1. 网络延迟过高 想象一下,你正在家里看电影,突然发现画面卡顿了,这是因为你的网络连接出了问题。同样地,在HDFS中,如果网络延迟过高,也会导致读取速度变慢。比如说,假如你的数据节点散落在天南海北的各种数据中心里,那数据跑来跑去就得花更多时间,就像你在城市两端都有家一样,来回折腾肯定比在同一个小区里串门费劲得多。 示例代码: java Configuration conf = new Configuration(); FileSystem fs = FileSystem.get(conf); Path filePath = new Path("/user/hadoop/input/file.txt"); FSDataInputStream in = null; try { in = fs.open(filePath); byte[] buffer = new byte[1024]; int bytesRead = in.read(buffer); while (bytesRead != -1) { bytesRead = in.read(buffer); } } catch (IOException e) { e.printStackTrace(); } finally { if (in != null) { try { in.close(); } catch (IOException e) { e.printStackTrace(); } } } 这段代码展示了如何从HDFS中读取文件。如果你发现每次执行这段代码时都需要花费很长时间,那么很可能是网络延迟的问题。 2. 数据本地性不足 还记得小时候玩过的接力赛吗?如果接力棒总是从一个人传到另一个人再传回来,效率肯定不高。这就跟生活中的事儿一样啊,在HDFS里头,要是数据没分配到离客户端最近的那个数据节点上,那不是干等着嘛,多浪费时间呀! 解决方案: 可以通过调整副本策略来改善数据本地性。比如说,默认设置下,HDFS会把文件的备份分散存到集群里的不同机器上。不过呢,如果你想让这个过程变得更高效或者更适合自己的需求,完全可以去调整那个叫dfs.replication的参数! xml dfs.replication 3 3. 磁盘I/O瓶颈 磁盘读写速度是影响HDFS性能的一个重要因素。要是你的服务器用的是那些老掉牙的机械硬盘,那读文件的速度肯定就慢得像乌龟爬了。 实验验证: 为了测试磁盘I/O的影响,可以尝试将一部分数据迁移到SSD上进行对比实验。好啦,想象一下,你手头有一堆日志文件要对付。先把它们丢到普通的老硬盘(HDD)里待着,然后又挪到固态硬盘(SSD)上,看看读取速度变了多少。是不是感觉像在玩拼图游戏,只不过这次是在折腾文件呢? 三、进阶优化技巧 经过前面的分析,我们可以得出结论:要提高HDFS的读取速度,不仅仅需要关注硬件层面的问题,还需要从软件配置上下功夫。以下是一些更高级别的优化建议: 1. 增加带宽 带宽就像是高速公路的车道数量,车道越多,车辆通行就越顺畅。对于HDFS来说,增加带宽意味着可以同时传输更多的数据块。 实际操作: 联系你的网络管理员,询问是否有可能升级现有的网络基础设施,比如更换更快的交换机或者部署新的光纤线路。 2. 调整副本策略 默认情况下,HDFS会将每个文件的三个副本均匀分布在整个集群中。然而,在某些特殊场景下,这种做法并不一定是最优解。比如说,你家APP平时就爱扎堆在那几个服务器节点上干活儿,那就可以把副本都放一块儿,这样它们串门聊天、传文件啥的就方便多了,也不用跑太远浪费时间啦! 配置修改: xml dfs.block.local-path-access.enabled true 3. 使用缓存机制 缓存就像冰箱里的剩饭,拿出来就能直接吃,不用重新加热。HDFS也有类似的机制,叫做“DataNode Cache”。打开这个功能之后啊,那些经常用到的数据就会被暂时存到内存里,这样下次再用的时候就嗖的一下快多了! 启用步骤: bash hadoop dfsadmin -setSpaceQuota 100g /cachedir hadoop dfs -cache /inputfile /cachedir 四、总结与展望 通过今天的讨论,我相信大家都对HDFS读取速度慢的原因有了更深的理解。其实,无论是网络延迟、数据本地性还是磁盘I/O瓶颈,都不是不可克服的障碍。其实吧,只要咱们肯花点心思去琢磨、去试试,肯定能找出个适合自己情况的办法。 最后,我想说的是,作为一名技术人员,我们应该始终保持好奇心和探索精神。不要害怕失败,也不要急于求成,因为每一次挫折都是一次成长的机会。希望这篇文章能给大家带来启发,让我们一起努力,让Hadoop变得更加高效可靠吧! --- 以上就是我对“HDFS读取速度慢”的全部看法和建议。如果你还有其他想法或者遇到类似的问题,请随时留言交流。咱们共同进步,一起探索大数据世界的奥秘!
2025-05-04 16:24:39
103
月影清风
转载文章
...表本站的立场。 作为信息平台,本站仅提供文章转载服务,并不拥有其所有权,也不对文章内容的真实性、准确性和合法性承担责任。 如发现本文存在侵权、违法、违规或事实不符的情况,请及时联系我们,我们将第一时间进行核实并删除相应内容。 原文地址为: 大数据——海量数据处理的基本方法总结 声明: 原文引用参考July大神的csdn博客文章 => 海量处理面试题 海量数据处理概述 所谓海量数据处理,就是数据量太大,无法在较短时间内迅速解决,无法一次性装入内存。本文在前人的基础上总结一下解决此类问题的办法。那么有什么解决办法呢? 时间复杂度方面,我们可以采用巧妙的算法搭配合适的数据结构,如Bloom filter/Hash/bit-map/堆/数据库或倒排索引/trie树。空间复杂度方面,分而治之/hash映射。 海量数据处理的基本方法总结起来分为以下几种: 分而治之/hash映射 + hash统计 + 堆/快速/归并排序; 双层桶划分; Bloom filter/Bitmap; Trie树/数据库/倒排索引; 外排序; 分布式处理之Hadoop/Mapreduce。 前提基础知识: 1 byte= 8 bit。 int整形一般为4 bytes 共32位bit。 2^32=4G。 1G=2^30=10.7亿。 1 分而治之+hash映射+快速/归并/堆排序 问题1 给定a、b两个文件,各存放50亿个url,每个url各占64字节,内存限制是4G,让你找出a、b文件共同的url? 分析:50亿64=320G大小空间。 算法思想1:hash 分解+ 分而治之 + 归并 遍历文件a,对每个url根据某种hash规则求取hash(url)/1024,然后根据所取得的值将url分别存储到1024个小文件(a0~a1023)中。这样每个小文件的大约为300M。如果hash结果很集中使得某个文件ai过大,可以在对ai进行二级hash(ai0~ai1024)。 这样url就被hash到1024个不同级别的目录中。然后可以分别比较文件,a0VSb0……a1023VSb1023。求每对小文件中相同的url时,可以把其中一个小文件的url存储到hash_map中。然后遍历另一个小文件的每个url,看其是否在刚才构建的hash_map中,如果是,那么就是共同的url,存到文件里面就可以了。 把1024个级别目录下相同的url合并起来。 问题2 有10个文件,每个文件1G,每个文件的每一行存放的都是用户的query,每个文件的query都可能重复。要求你按照query的频度排序。 解决思想1:hash分解+ 分而治之 +归并 顺序读取10个文件a0~a9,按照hash(query)%10的结果将query写入到另外10个文件(记为 b0~b9)中。这样新生成的文件每个的大小大约也1G(假设hash函数是随机的)。 找一台内存2G左右的机器,依次对用hash_map(query, query_count)来统计每个query出现的次数。利用快速/堆/归并排序按照出现次数进行排序。将排序好的query和对应的query_cout输出到文件中。这样得到了10个排好序的文件c0~c9。 对这10个文件c0~c9进行归并排序(内排序与外排序相结合)。每次取c0~c9文件的m个数据放到内存中,进行10m个数据的归并,即使把归并好的数据存到d结果文件中。如果ci对应的m个数据全归并完了,再从ci余下的数据中取m个数据重新加载到内存中。直到所有ci文件的所有数据全部归并完成。 解决思想2: Trie树 如果query的总量是有限的,只是重复的次数比较多而已,可能对于所有的query,一次性就可以加入到内存了。在这种假设前提下,我们就可以采用trie树/hash_map等直接来统计每个query出现的次数,然后按出现次数做快速/堆/归并排序就可以了。 问题3: 有一个1G大小的一个文件,里面每一行是一个词,词的大小不超过16字节,内存限制大小是1M。返回频数最高的100个词。 类似问题:怎么在海量数据中找出重复次数最多的一个? 解决思想: hash分解+ 分而治之+归并 顺序读文件中,对于每个词x,按照hash(x)/(10244)存到4096个小文件中。这样每个文件大概是250k左右。如果其中的有的文件超过了1M大小,还可以按照hash继续往下分,直到分解得到的小文件的大小都不超过1M。 对每个小文件,统计每个文件中出现的词以及相应的频率(可以采用trie树/hash_map等),并取出出现频率最大的100个词(可以用含100个结点的最小堆),并把100词及相应的频率存入文件。这样又得到了4096个文件。 下一步就是把这4096个文件进行归并的过程了。(类似与归并排序) 问题4 海量日志数据,提取出某日访问百度次数最多的那个IP 解决思想: hash分解+ 分而治之 + 归并 把这一天访问百度的日志中的IP取出来,逐个写入到一个大文件中。注意到IP是32位的,最多有2^32个IP。同样可以采用hash映射的方法,比如模1024,把整个大文件映射为1024个小文件。 再找出每个小文中出现频率最大的IP(可以采用hash_map进行频率统计,然后再找出频率最大的几个)及相应的频率。 然后再在这1024组最大的IP中,找出那个频率最大的IP,即为所求。 问题5 海量数据分布在100台电脑中,想个办法高效统计出这批数据的TOP10。 解决思想: 分而治之 + 归并。 注意TOP10是取最大值或最小值。如果取频率TOP10,就应该先hash分解。 在每台电脑上求出TOP10,采用包含10个元素的堆完成(TOP10小,用最大堆,TOP10大,用最小堆)。比如求TOP10大,我们首先取前10个元素调整成最小堆,如果发现,然后扫描后面的数据,并与堆顶元素比较,如果比堆顶元素大,那么用该元素替换堆顶,然后再调整为最小堆。最后堆中的元素就是TOP10大。 求出每台电脑上的TOP10后,然后把这100台电脑上的TOP10组合起来,共1000个数据,再利用上面类似的方法求出TOP10就可以了。 问题6 在2.5亿个整数中找出不重复的整数,内存不足以容纳这2.5亿个整数。 解决思路1 : hash 分解+ 分而治之 + 归并 2.5亿个int数据hash到1024个小文件中a0~a1023,如果某个小文件大小还大于内存,进行多级hash。每个小文件读进内存,找出只出现一次的数据,输出到b0~b1023。最后数据合并即可。 解决思路2 : 2-Bitmap 如果内存够1GB的话,采用2-Bitmap(每个数分配2bit,00表示不存在,01表示出现一次,10表示多次,11无意义)进行,共需内存2^322bit=1GB内存。然后扫描这2.5亿个整数,查看Bitmap中相对应位,如果是00变01,01变10,10保持不变。所描完事后,查看bitmap,把对应位是01的整数输出即可。 注意,如果是找出重复的数据,可以用1-bitmap。第一次bit位由0变1,第二次查询到相应bit位为1说明是重复数据,输出即可。 问题7 一共有N个机器,每个机器上有N个数。每个机器最多存O(N)个数并对它们操作。如何找到N^2个数中的中数? 解决思想1 : hash分解 + 排序 按照升序顺序把这些数字,hash划分为N个范围段。假设数据范围是2^32 的unsigned int 类型。理论上第一台机器应该存的范围为0~(2^32)/N,第i台机器存的范围是(2^32)(i-1)/N~(2^32)i/N。hash过程可以扫描每个机器上的N个数,把属于第一个区段的数放到第一个机器上,属于第二个区段的数放到第二个机器上,…,属于第N个区段的数放到第N个机器上。注意这个过程每个机器上存储的数应该是O(N)的。 然后我们依次统计每个机器上数的个数,一次累加,直到找到第k个机器,在该机器上累加的数大于或等于(N^2)/2,而在第k-1个机器上的累加数小于(N^2)/2,并把这个数记为x。那么我们要找的中位数在第k个机器中,排在第(N^2)/2-x位。然后我们对第k个机器的数排序,并找出第(N^2)/2-x个数,即为所求的中位数的复杂度是O(N^2)的。 解决思想2: 分而治之 + 归并 先对每台机器上的数进行排序。排好序后,我们采用归并排序的思想,将这N个机器上的数归并起来得到最终的排序。找到第(N^2)/2个便是所求。复杂度是O(N^2 lgN^2)的。 2 Trie树+红黑树+hash_map 这里Trie树木、红黑树或者hash_map可以认为是第一部分中分而治之算法的具体实现方法之一。 问题1 上千万或上亿数据(有重复),统计其中出现次数最多的钱N个数据。 解决思路: 红黑树 + 堆排序 如果是上千万或上亿的int数据,现在的机器4G内存可以能存下。所以考虑采用hash_map/搜索二叉树/红黑树等来进行统计重复次数。 然后取出前N个出现次数最多的数据,可以用包含N个元素的最小堆找出频率最大的N个数据。 问题2 1000万字符串,其中有些是重复的,需要把重复的全部去掉,保留没有重复的字符串。请怎么设计和实现? 解决思路:trie树。 这题用trie树比较合适,hash_map也应该能行。 问题3 一个文本文件,大约有一万行,每行一个词,要求统计出其中最频繁出现的前10个词,请给出思想,给出时间复杂度分析。 解决思路: trie树 + 堆排序 这题是考虑时间效率。 1. 用trie树统计每个词出现的次数,时间复杂度是O(nlen)(len表示单词的平准长度)。 2. 然后找出出现最频繁的前10个词,可以用堆来实现,前面的题中已经讲到了,时间复杂度是O(nlg10)。 总的时间复杂度,是O(nle)与O(nlg10)中较大的哪一个。 问题4 搜索引擎会通过日志文件把用户每次检索使用的所有检索串都记录下来,每个查询串的长度为1-255字节。假设目前有一千万个记录,这些查询串的重复读比较高,虽然总数是1千万,但是如果去除重复和,不超过3百万个。一个查询串的重复度越高,说明查询它的用户越多,也就越热门。请你统计最热门的10个查询串,要求使用的内存不能超过1G。 解决思想 : trie树 + 堆排序 采用trie树,关键字域存该查询串出现的次数,没有出现为0。最后用10个元素的最小推来对出现频率进行排序。 3 BitMap或者Bloom Filter 3.1 BitMap BitMap说白了很easy,就是通过bit位为1或0来标识某个状态存不存在。可进行数据的快速查找,判重,删除,一般来说适合的处理数据范围小于82^32。否则内存超过4G,内存资源消耗有点多。 问题1 已知某个文件内包含一些电话号码,每个号码为8位数字,统计不同号码的个数。 解决思路: bitmap 8位最多99 999 999,需要100M个bit位,不到12M的内存空间。我们把0-99 999 999的每个数字映射到一个Bit位上,所以只需要99M个Bit==12MBytes,这样,就用了小小的12M左右的内存表示了所有的8位数的电话 问题2 2.5亿个整数中找出不重复的整数的个数,内存空间不足以容纳这2.5亿个整数。 解决思路:2bit map 或者两个bitmap。 将bit-map扩展一下,用2bit表示一个数即可,00表示未出现,01表示出现一次,10表示出现2次及以上,11可以暂时不用。 在遍历这些数的时候,如果对应位置的值是00,则将其置为01;如果是01,将其置为10;如果是10,则保持不变。需要内存大小是2^32/82=1G内存。 或者我们不用2bit来进行表示,我们用两个bit-map即可模拟实现这个2bit-map,都是一样的道理。 3.2 Bloom filter Bloom filter可以看做是对bit-map的扩展。 参考july大神csdn文章 Bloom Filter 详解 4 Hadoop+MapReduce 参考引用july大神 csdn文章 MapReduce的初步理解 Hadoop框架与MapReduce模式 转载请注明本文地址: 大数据——海量数据处理的基本方法总结 本篇文章为转载内容。原文链接:https://blog.csdn.net/hong2511/article/details/80842704。 该文由互联网用户投稿提供,文中观点代表作者本人意见,并不代表本站的立场。 作为信息平台,本站仅提供文章转载服务,并不拥有其所有权,也不对文章内容的真实性、准确性和合法性承担责任。 如发现本文存在侵权、违法、违规或事实不符的情况,请及时联系我们,我们将第一时间进行核实并删除相应内容。
2024-03-01 12:40:17
541
转载
转载文章
...表本站的立场。 作为信息平台,本站仅提供文章转载服务,并不拥有其所有权,也不对文章内容的真实性、准确性和合法性承担责任。 如发现本文存在侵权、违法、违规或事实不符的情况,请及时联系我们,我们将第一时间进行核实并删除相应内容。 s_msckf:采用多状态约束的双目vio系统 !!!注意imuCallback:接收IMU数据,将IMU数据存到imu_msg_buffer中,这里只会利用开头200帧IMU数据进行静止初始化,不做其他处理。featureCallback:接收双目特征,进行后端处理。利用IMU进行EKF Propagation,利用双目特征进行EKF Update。静止初始化(initializeGravityAndBias):将前200帧加速度和角速度求平均, 平均加速度的模值g作为重力加速度, 平均角速度作为陀螺仪的bias, 计算重力向量(0,0,-g)和平均加速度之间的夹角(旋转四元数), 标定初始时刻IMU系与world系之间的夹角. 因此MSCKF要求前200帧IMU是静止不动的 sudo apt-get install libsuitesparse-devcd ~/catkin_ws/srcgit clone KumarRobotics/msckf_viocd ..catkin_make --pkg msckf_vio --cmake-args -DCMAKE_BUILD_TYPE=Release激活环境变量很关键source /devel/setup.bashroslaunch msckf_vio msckf_vio_euroc.launch注意文件路径rosrun rviz rviz -d rviz/rviz_euroc_config.rviz (改成你自己的rviz文件)rosbag play ~/data/euroc/MH_04_difficult.bag(改成你自己的rosbag文件) 可以看到,s_msckf的输出是没有轨迹的,可以增加如下脚本,将/odom存为/path,在rviz订阅即可可视化轨迹 脚本来自其issue:https://github.com/KumarRobotics/msckf_vio/issues/13 !/usr/bin/env pythonimport rospyfrom nav_msgs.msg import Odometry, Pathfrom geometry_msgs.msg import PoseStampedclass OdomToPath:def __init__(self):self.path_pub = rospy.Publisher('/slz_path', Path, latch=True, queue_size=10)self.odom_sub = rospy.Subscriber('/firefly_sbx/vio/odom', Odometry, self.odom_cb, queue_size=10)self.path = Path()def odom_cb(self, msg):cur_pose = PoseStamped()cur_pose.header = msg.headercur_pose.pose = msg.pose.poseself.path.header = msg.headerself.path.poses.append(cur_pose)self.path_pub.publish(self.path)if __name__ == '__main__':rospy.init_node('odom_to_path')odom_to_path = OdomToPath()rospy.spin() 或者增加一个draw_path的功能包: cpp为: include <stdio.h>include <stdlib.h>include <unistd.h>include <ros/ros.h>include <ros/console.h>include <nav_msgs/Path.h>include <std_msgs/String.h>include <nav_msgs/Odometry.h>include <geometry_msgs/Quaternion.h>include <geometry_msgs/PoseStamped.h>nav_msgs::Path path;ros::Publisher path_pub;ros::Subscriber odomSub;ros::Subscriber odom_raw_Sub;void odomCallback(const nav_msgs::Odometry::ConstPtr& odom){geometry_msgs::PoseStamped this_pose_stamped;this_pose_stamped.header= odom->header;this_pose_stamped.pose = odom->pose.pose;//this_pose_stamped.pose.position.x = odom->pose.pose.position.x;//this_pose_stamped.pose.position.y = odom->pose.pose.position.y;//this_pose_stamped.pose.orientation = odom->pose.pose.orientation;//this_pose_stamped.header.stamp = ros::Time::now();//this_pose_stamped.header.frame_id = "world";//frame_id 是消息中与数据相关联的参考系id,例如在在激光数据中,frame_id对应激光数据采集的参考系 path.header= this_pose_stamped.header;path.poses.push_back(this_pose_stamped);//path.header.stamp = ros::Time::now();//path.header.frame_id= "world";path_pub.publish(path);//printf("path_pub ");//printf("odom %.3lf %.3lf\n",odom->pose.pose.position.x,odom->pose.pose.position.y);}int main (int argc, char argv){ros::init (argc, argv, "showpath");ros::NodeHandle ph;path_pub = ph.advertise<nav_msgs::Path>("/trajectory",10, true);odomSub = ph.subscribe<nav_msgs::Odometry>("/firefly_sbx/vio/odom", 10, odomCallback);//ros::Rate loop_rate(50);while (ros::ok()){ros::spinOnce(); // check for incoming messages//loop_rate.sleep();}return 0;} cmakelists.txt cmake_minimum_required(VERSION 2.8.3)project(draw) Compile as C++11, supported in ROS Kinetic and newer add_compile_options(-std=c++11) Find catkin macros and libraries if COMPONENTS list like find_package(catkin REQUIRED COMPONENTS xyz) is used, also find other catkin packagesfind_package(catkin REQUIRED COMPONENTSgeometry_msgsroscpprospystd_msgsmessage_generation)catkin_package( INCLUDE_DIRS include LIBRARIES learning_communicationCATKIN_DEPENDS geometry_msgs roscpp rospy std_msgs message_runtime DEPENDS system_lib) Build include_directories(include${catkin_INCLUDE_DIRS})add_executable(draw_path draw.cpp)target_link_libraries(draw_path ${catkin_LIBRARIES}) package.xml <?xml version="1.0"?><package><name>draw</name><version>0.0.0</version><description>The learning_communication package</description><!-- One maintainer tag required, multiple allowed, one person per tag --><!-- Example: --><!-- <maintainer email="jane.doe@example.com">Jane Doe</maintainer> --><maintainer email="hcx@todo.todo">hcx</maintainer><!-- One license tag required, multiple allowed, one license per tag --><!-- Commonly used license strings: --><!-- BSD, MIT, Boost Software License, GPLv2, GPLv3, LGPLv2.1, LGPLv3 --><license>TODO</license><!-- Url tags are optional, but multiple are allowed, one per tag --><!-- Optional attribute type can be: website, bugtracker, or repository --><!-- Example: --><!-- <url type="website">http://wiki.ros.org/learning_communication</url> --><!-- Author tags are optional, multiple are allowed, one per tag --><!-- Authors do not have to be maintainers, but could be --><!-- Example: --><!-- <author email="jane.doe@example.com">Jane Doe</author> --><!-- The _depend tags are used to specify dependencies --><!-- Dependencies can be catkin packages or system dependencies --><!-- Examples: --><!-- Use build_depend for packages you need at compile time: --><!-- <build_depend>message_generation</build_depend> --><!-- Use buildtool_depend for build tool packages: --><!-- <buildtool_depend>catkin</buildtool_depend> --><!-- Use run_depend for packages you need at runtime: --><!-- <run_depend>message_runtime</run_depend> --><!-- Use test_depend for packages you need only for testing: --><!-- <test_depend>gtest</test_depend> --><buildtool_depend>catkin</buildtool_depend><build_depend>geometry_msgs</build_depend><build_depend>roscpp</build_depend><build_depend>rospy</build_depend><build_depend>std_msgs</build_depend><run_depend>geometry_msgs</run_depend><run_depend>roscpp</run_depend><run_depend>rospy</run_depend><run_depend>std_msgs</run_depend><build_depend>message_generation</build_depend><run_depend>message_runtime</run_depend><!-- The export tag contains other, unspecified, tags --><export><!-- Other tools can request additional information be placed here --></export></package> vins_fusion: 双目vio等多系统 mkdir -p vins-catkin_ws/srccd vins-catkin_ws/srcgit clone https://github.com/HKUST-Aerial-Robotics/VINS-Fusion.gitcd ..catkin_makesource devel/setup.bash按照readme 3.1 Monocualr camera + IMUroslaunch vins vins_rviz.launchrosrun vins vins_node ~/catkin_ws/src/VINS-Fusion/config/euroc/euroc_mono_imu_config.yaml (optional) rosrun loop_fusion loop_fusion_node ~/catkin_ws/src/VINS-Fusion/config/euroc/euroc_mono_imu_config.yaml rosbag play YOUR_DATASET_FOLDER/MH_01_easy.bag 3.2 Stereo cameras + IMUroslaunch vins vins_rviz.launchrosrun vins vins_node ~/catkin_ws/src/VINS-Fusion/config/euroc/euroc_stereo_imu_config.yaml (optional) rosrun loop_fusion loop_fusion_node ~/catkin_ws/src/VINS-Fusion/config/euroc/euroc_stereo_imu_config.yaml rosbag play YOUR_DATASET_FOLDER/MH_01_easy.bag 3.3 Stereo camerasroslaunch vins vins_rviz.launchrosrun vins vins_node ~/catkin_ws/src/VINS-Fusion/config/euroc/euroc_stereo_config.yaml (optional) rosrun loop_fusion loop_fusion_node ~/catkin_ws/src/VINS-Fusion/config/euroc/euroc_stereo_config.yaml rosbag play YOUR_DATASET_FOLDER/MH_01_easy.bag<img src="https://github.com/HKUST-Aerial-Robotics/VINS-Fusion/blob/master/support_files/image/euroc.gif" width = 430 height = 240 /> 4. KITTI Example 4.1 KITTI Odometry (Stereo)Download [KITTI Odometry dataset](http://www.cvlibs.net/datasets/kitti/eval_odometry.php) to YOUR_DATASET_FOLDER. Take sequences 00 for example,Open two terminals, run vins and rviz respectively. (We evaluated odometry on KITTI benchmark without loop closure funtion)roslaunch vins vins_rviz.launch(optional) rosrun loop_fusion loop_fusion_node ~/catkin_ws/src/VINS-Fusion/config/kitti_odom/kitti_config00-02.yamlrosrun vins kitti_odom_test ~/catkin_ws/src/VINS-Fusion/config/kitti_odom/kitti_config00-02.yaml YOUR_DATASET_FOLDER/sequences/00/ 4.2 KITTI GPS Fusion (Stereo + GPS)Download [KITTI raw dataset](http://www.cvlibs.net/datasets/kitti/raw_data.php) to YOUR_DATASET_FOLDER. Take [2011_10_03_drive_0027_synced](https://s3.eu-central-1.amazonaws.com/avg-kitti/raw_data/2011_10_03_drive_0027/2011_10_03_drive_0027_sync.zip) for example.Open three terminals, run vins, global fusion and rviz respectively. Green path is VIO odometry; blue path is odometry under GPS global fusion.roslaunch vins vins_rviz.launchrosrun vins kitti_gps_test ~/catkin_ws/src/VINS-Fusion/config/kitti_raw/kitti_10_03_config.yaml YOUR_DATASET_FOLDER/2011_10_03_drive_0027_sync/ rosrun global_fusion global_fusion_node<img src="https://github.com/HKUST-Aerial-Robotics/VINS-Fusion/blob/master/support_files/image/kitti.gif" width = 430 height = 240 /> 5. VINS-Fusion on car demonstrationDownload [car bag](https://drive.google.com/open?id=10t9H1u8pMGDOI6Q2w2uezEq5Ib-Z8tLz) to YOUR_DATASET_FOLDER.Open four terminals, run vins odometry, visual loop closure(optional), rviz and play the bag file respectively. Green path is VIO odometry; red path is odometry under visual loop closure.roslaunch vins vins_rviz.launchrosrun vins vins_node ~/catkin_ws/src/VINS-Fusion/config/vi_car/vi_car.yaml (optional) rosrun loop_fusion loop_fusion_node ~/catkin_ws/src/VINS-Fusion/config/vi_car/vi_car.yaml rosbag play YOUR_DATASET_FOLDER/car.bag 本篇文章为转载内容。原文链接:https://blog.csdn.net/slzlincent/article/details/104364909。 该文由互联网用户投稿提供,文中观点代表作者本人意见,并不代表本站的立场。 作为信息平台,本站仅提供文章转载服务,并不拥有其所有权,也不对文章内容的真实性、准确性和合法性承担责任。 如发现本文存在侵权、违法、违规或事实不符的情况,请及时联系我们,我们将第一时间进行核实并删除相应内容。
2023-09-13 20:38:56
310
转载
转载文章
...表本站的立场。 作为信息平台,本站仅提供文章转载服务,并不拥有其所有权,也不对文章内容的真实性、准确性和合法性承担责任。 如发现本文存在侵权、违法、违规或事实不符的情况,请及时联系我们,我们将第一时间进行核实并删除相应内容。 目录 一、建模背景及目的及数据源说明 二、描述性分析 2.1 连续自变量与连续因变量的相关性分析 2.2 二分类变量与连续变量的相关性分析 2.3 多分类变量与连续变量的相关性分析 三、模型建立与诊断 3.1 一元线形回归及模型解读 3.2 残差可视化分析 3.3 多元线性回归 一、建模背景及目的及数据源说明 本案例数据来源于常国珍等人的《Python数据科学》一书第7章中的信用卡公司客户申请信息(年龄、收入、地区等信息)以及已有开卡客户的申请信息和信用卡消费信息数据,案例希望通过对该数据的分析和建模,根据已有的开卡用户的用户信息和消费来线形回归模型,来预测未开卡用户的消费潜力。数据下载见如下链https://download.csdn.net/download/baidu_26137595/85101874 数据读入及示例: raw = pd.read_csv('./data/creditcard_exp.csv', skipinitialspace = True)raw.head() 数据字段及说明: Acc: 是否开卡, 为0说明未开卡,对应的 avg_exp 为NaN;为1说明已开卡,对应avg_exp有值 avg_exp: 月均信用卡支出 avg_exp_ln:月均信用卡支出的对熟 gender : 性别 Ownrent: 是否自有住房 Selfempl: 是否自谋职业 Income:收入 dist_home_val: 所住小区均价 w dist_avg_income: 当地人均收入 age2: 年龄的平方 high_avg: 高出当地平均收入 edu_class:教育等级,0、1、2、3 依次是小学、初中、高中、大学 二、描述性分析 首先可筛选Acc为1的数据,分别以avg_exp为因变量,其余变量为自变量进行数据探索,主要是发现自变量和因变量是否有线形关系。 raw_1 = raw[raw['Acc'] == 1] 2.1 连续自变量与连续因变量的相关性分析 首先对连续变量和目标变量进行相关性分析,因变量avg_exp为连续变量,一般可以用相关系数来看其线形相关性。 cons_vasr = ['avg_exp', 'avg_exp_ln', 'Age', 'Income', 'dist_home_val', 'dist_avg_income', 'age2', 'high_avg']raw_1[cons_vasr].corr()vg']].corr() 结果如下,可以看到收入 Income 和当地人均收入 dist_avg_income这两个变量和avg_exp月均信用卡支出有较强的相关性,同时观察自变量间的相关性可发现人均收入 Income 和当地人均收入 dist_avg_income 之间也有较强的相关性,相关系数为0.99,说明接下来我们可以把这两个变量加入模型,但要注意可能会存在多重共线性。 2.2 二分类变量与连续变量的相关性分析 分类变量和连续变量之间的相关性可以用t检验进行,接下来以是否自有住房 Ownrent 变量 和 月均收入之间进行相关性检验。首先查看Ownrent 不同取值的数量以及avg_exp均值分布情况如何: pd.pivot_table(raw_1, values = ['avg_exp'], index = ['Ownrent'], aggfunc = {'avg_exp': ['count', np.mean]}) 接着分别对 Ownrent 为0、1的 avg_exp 进行t检验: import scipy.stats as st 引入scipy.stats进行t检验 创建变量Ownrent_0 = raw_1[raw_1['Ownrent'] == 0]['avg_exp'].valuesOwnrent_1 = raw_1[raw_1['Ownrent'] == 1]['avg_exp'].valuesst.ttest_ind(Ownrent_0, Ownrent_1, equal_var = True) p值为0.01 < 0.05,可以拒绝原假设,即认为是否自有住房和月均信用卡支出是相关的。 2.3 多分类变量与连续变量的相关性分析 多分类变量和连续变量之间的相关性检验可以用多次t检验进行,但较为繁琐,用方差分析进行快速检验相关性,然后再运用多重检验查看具体是哪些处理之间存在差异。以教育水平edu_class为例进行分析,同理首先查看分布 raw_1.pivot_table(index = 'edu_class', values = ['avg_exp'], aggfunc={'avg_exp': ['count', np.mean]}) 可以看到不同教育水平之间消费水平有明显差异,接下来通过方差分析进行检验差异是否明显。 from statsmodels.stats.anova import anova_lm 引入anova_lm进行方差分析from ststsmodels.stats.formula import ols 引入ols进行线性回归建模lm = ols('avg_exp~C(edu_class)', data = raw_1).fit() C(edu_class) 将数值型的变量指定为分类型anova_lm(lm, typ = 2) 可以看到不同教育水平之间的月均消费支出之间的差异是显著的,继续用多重检验来看哪些处理之间是显著的。 from statsmodels.stats.multicomp import MultiComparison 引入MultiComparison进行tukey多重检验mc = MultiComparison(raw_1['avg_exp'],raw_1['edu_class'])tukey_result = mc.tukeyhsd(alpha = 0.5)print(tukey_result) 结果是每个处理之间因变量差异的显著性,最后一列reject都为True说明各组之间均存在显著差异。 三、模型建立与诊断 3.1 一元线性回归及模型解读 以Income为自变量,以avg_exp为因变量建立一元线形回归并对模型结果进行解释 lm_1 = ols('avg_exp ~ Income', data = raw_1).fit()print(lm_1.summary()) 首先从第一部分可以看到R^2为0.454,整个模型的F检验p值小于0.05,说明模型通过显著性检验。 其次模型结果的第二块也表明自变量和截距也通过显著性检验。 最后一部分主要是对残差进行检验,左侧Omnibus、Prob(Omnibus)主要是对偏度Skew和峰度Kurtosis进行检验,正态分布的偏度为0,峰度为3,模型的Prob(Omnibus)值为0.156大于0.05,说明不能拒绝残差符合正态分布。 右侧Durbin-Watson主要是对残差的自相关性进行检(改检验可表示为,为残差之间的相关系数),Durbin-Watson的取值范围是0-4,越接近2说明残差不存在自相关性,越接近0说明存在正相关,越接近4说明存在负相关性。 右侧Jarque-Bera (JB)、Prob(JB)是对残差正态性检验,可以用来判断残差是否符合正态分布,本案例中Prob(JB)值为0.173 > 0.05,基不能拒绝残差服从正态分布。 右侧Cond. No.是多重共线性检验,该值越大,共线性越严重。 整体上看模型虽然拟合效果没那么好,但是显著性通过了检验。接下来看一下模型具体的系数,Income的系数为97.7说明模型收入越高信用卡消费越高,是符合业务预期的。 3.2 残差可视化分析 接下来对残差进一步进行可视化分析,主要看残差是否满足以下几个假定,并尝试通过对自变量、因变量进行调整来优化模型。首先来回顾一下残差需要满足的几个假定: a.残差的要服从均值为0,方差为的正态分布; b.残差之间要相互独立 c.残差和自变量没有相关性 (1)通过残差图进行模型优化 模型avg_exp ~ Income的自变量与残差分布图、残差qq图、模型拟合情况图即自变量与因变量及其预测值的图像 lm_1 = ols('avg_exp ~ Income', data = raw_1).fit() 建模raw_1['resid_1'] = lm_1.resid 模型残差raw_1['resid_1_rank'] = raw_1['resid_1'].rank(ascending = False, pct = True) 计算残差的百分位数raw_1['pred_1'] = lm_1.predict() 添加预测值plt.figure(figsize = (20, 6)) 自变量与残差分布图ax1 = plt.subplot(131)ax1.scatter('Income', 'resid', data = raw_1)ax1.set_title('Income & resid') 残差的qq图ax2 = plt.subplot(132)stats.probplot(raw_1['resid_1_rank'], dist = 'norm', plot = ax2) 模型拟合情况图,自变量与因变量以及模型预测值ax3 = plt.subplot(133)ax3.scatter('Income', 'avg_exp', data = raw_1)ax3.plot('Income', 'pred_1', data = raw_1, color = 'red')ax3.legend()ax3.text(12, 1920, 'pred func R^2: %.2f'% lm_1.rsquared)ax3.set_title('Income & avg_exp') 从第一个自变量和残差散点图可以看出,残差基本符合对称分布,但随着自变量增大,残差也在变大,存在方差不齐的情况。第二个图残差的qq图可以看出,残差近似正态分布。第三个图可以看模型的拟合效果并不是很好,R^2只有0.45。对avg_exp取对数,能够改善预测值越大残差越大的情况,但由于只对因变量取对数导致模型不好解释,对自变量Income同时取对数,代码和以上类似,只是改变因变量和自变量形式而已,以下是残差图,可以看到残差的异方差现象被有效的抑制,并且R^2也得到了提高。 (2)通过残差图发现强影响点 仔细观察以上图像结果,左下侧有两个较为异常的数据,对模型的拟和效果有较大的影响, 对于这种影响较大的可将其进行删除并重新建模: 计算学生化残差raw_1['resid_t'] = (raw_1['resid_2'] - raw_1['resid_2'].mean())/raw_1['resid_2'].std() raw_1[abs(raw_1['resid_t']) > 2] 将残差大于2的筛选出来 将强影响点删除后,得到的结果如下,模型结果更稳定。 3.3 多元线性回归 上一篇文章有说到多重共线性会对模型产生致命的影响,用方差膨胀因子来处理的话会非常繁琐。通过正则化处理如Lasso回归,能够产生某些严格等于0的系数,从而达到变量筛选的目的。接下来以Lasso为例,首先用LassoCV来找到最优的alpha。由于statsmodels中的ols的fit_regularized方法没有很好的实现,所以用sklearn中linear_model模块来进行建模 from sklearn.preprocessing import StandardScaler sklearn进行线性回归前必须要进行标准化from sklearn.linear_model import LassoCV Lasso的交叉验证方法con_xcols = ['Age', 'Income', 'dist_home_val', 'dist_avg_income']scaler = StandardScaler()X = scaler.fit_transform(raw_1[con_xcols])y = raw_1['avg_exp_ln']lasso_alphas = np.logspace(-3, 0, 100, base = 10)lcv = LassoCV(alphas = lasso_alphas, cv = 10)lcv.fit(X, y)print('best alpha %.4f' % lcv.alpha_)print('the r-square %.4f' % lcv.score(X, y)) 接下来画出不同alpha下的岭迹图,来看alpha值对系数的影响 from sklearn.linear_model import Lassocoefs = []lasso = Lasso()for i in lasso_alphas:lasso.set_params(alpha = i)lasso.fit(X, y)coefs.append(lasso.coef_)ax = plt.gca()ax.plot(lasso_alphas, coefs)ax.set_xscale('log')ax.set_xlabel('$\\alpha$')ax.set_ylabel('coefs value') 从图中可以看到随着alpha的增大,系数不断在减小,有些系数会优先收缩为0,再继续增大时所欲系数都会为0,通过该特性从而达到变量筛选的目的。将LassoCV得到的系数打印出来,可以看到用户月均信用卡支出和当地小区均价、当地人均收入成正比,当地人均收入水平的影响更大。 以上就是线形回归在应用时的注意事项。 本篇文章为转载内容。原文链接:https://blog.csdn.net/baidu_26137595/article/details/123766191。 该文由互联网用户投稿提供,文中观点代表作者本人意见,并不代表本站的立场。 作为信息平台,本站仅提供文章转载服务,并不拥有其所有权,也不对文章内容的真实性、准确性和合法性承担责任。 如发现本文存在侵权、违法、违规或事实不符的情况,请及时联系我们,我们将第一时间进行核实并删除相应内容。
2023-11-23 15:52:56
106
转载
转载文章
...表本站的立场。 作为信息平台,本站仅提供文章转载服务,并不拥有其所有权,也不对文章内容的真实性、准确性和合法性承担责任。 如发现本文存在侵权、违法、违规或事实不符的情况,请及时联系我们,我们将第一时间进行核实并删除相应内容。 相关阅读: 阿里云Redis开发规范 千万级规模高性能、高并发的网络架构经验分享 互联网技术(java框架、分布式、集群)干货视频大全,不看后悔!(免费下载) 本文转自:公众号老板思维与智库(ID:laobanzhiku88),欢迎大家关注 笔者搬家前有个邻居,两口子典型的中年夫妻。 时不时由着一些鸡毛蒜皮的小事突然爆发争吵,但为了孩子老人和自己的颜面又要在人前假装和睦。 吵架的内容无非几样,孩子学业、老人赡养... 以及,丈夫人到中年,却还只是个普普通通的员工,业绩上不高不低,不至于垫底,也不足以升迁,家庭经济压力不小。 老话说,贫贱夫妻百事衰,一点没错。 一生压力最大的时期无非上有老下有小的中年。 事业上年纪已经失去了竞争力,脑力体力精力都比不过后来的年轻人。 无数的争吵、矛盾、压力,说明白点,大都来自于经济上的缺乏。 这样的家庭在中国并不少见。 扪心自问,兢兢业业十几年,没有功劳也有苦劳,为什么现在还只是个普通员工? 甚至比自己晚入行几年的新人都早早升迁小有成就了。 无目标无计划 大部分到了中年仍旧一事无成的人多在年轻时对自己的人生没有长远的规划。 年纪轻轻就失去梦想,只想当咸鱼。 做一天和尚撞一天钟,不知不觉,最适合奋斗的那几年都在这种平淡中弹指一挥间,回过神来人已经不惑之年。 普通员工不可怕,可怕的是你是个没有自己“小目标”的普通员工。 过度满足于现状只会增加你的职场生存隐患,很可能老板没有开除你单单念在你勤恳付出多年的三分情面上。 但是仅仅不犯过错不应该成为工作的准则。 都说学如逆水行舟,只要处在不断前进的社会里,人就要努力向前,才不至于被抛在人后。 原地停留,不过是变相的倒退罢了。 无论青年还是中年,当着手当下,给自己定下前行的目标,不断寻求突破与进展。 人要做的,是永远比昨天的自己更优秀。 实际行动力差 笔者接触到的中年人,大部分实际行动力都不强。 说起人生道理、励志格言他们如数家珍,一说一箩筐,分分钟能登台做演讲。 但真真切切落实到实际行动里,完全又是另外一回事。 具体到某一件事的时候,他们会有各种各样的理由来拒绝改变和行动。 好似他们的境况永远特殊,永远比别人更加糟糕,旁人永远难以体会。 常听朋友抱怨起他的父亲,说父亲年轻时喜欢钓鱼,偶尔也会在周末带他出去垂钓。 这本是极好的一项爱好,修身养性还能给餐桌添些鲜味。 但随着他的长大,父亲步入中年,钓鱼这项活动就只存在于父亲和外人的谈天说地里。 当他邀请父亲一同出门垂钓的时候,总是被各种理由拒绝。 那可能是伯父真的有重要的事情要做嘛,笔者笑道。 朋友无奈直摇头,他给我的理由无非几样。 要么是嫌钓鱼地方不好,找到了好地方又嫌路途远,两者都不错的又说天气不适合,林林总总说起来无非就三个字,不想动。 一件自己喜欢的事都不愿意花时间去享受,更不用说繁琐的工作了。 再高的思想觉悟、再充分的理论知识,没有实战,终究不过是纸上谈兵,虚吹一场,没有任何实际效用。 脚踏实地,踏踏实实做实事,才可能有收获。 不懂得投资自己 股神巴菲特在《福布斯》杂志的采访中说道,有一种投资好过其他所有的投资,那就是投资自己。 没有人能夺走你自身学到的东西,每个人都有这样的投资潜力。 无论处在什么阶段,保持学习都是十分重要的一件事。 工作的十几年间,为什么别人都升职了自己却留在原地? 常常会疑惑,刚进公司的时候也是优秀的潜力股一枚,升职的时候老板怎么就看不见我? 很简单,因为潜力股要经过挖掘投资才能成为优质股。 人就像一方活水,有源源不断的补给才能保持自身不干涸,才能掀得起浪花。 不断增加自己的学识、磨练出过硬的技能,在职场中你的综合考察才会不断加分! 不懂的投资自己,提升能力,只会让你被淘汰的更快。 心态老得比身体快 明明还是个中年人,精神面貌看着还不如小区里跳广场舞的大妈大爷们。 整个人的心态衰老程度已经远远超过身体的衰老程度。 从内里散发出消极颓废的负能量。 试想谁会把重要的工作交给一个丧气满满的人呢? 职场上的中年人在做事的时候难免受家庭、他人眼光、年龄的牵绊,畏手畏脚,瞻前顾后。 他们总在想,我这样做,会显得自己过于出彩,会畏惧别人“一把年纪还想出风头”的闲言碎语和轻信别人“老了老了,都是年轻人的天下”的衰言败语。 妈妈常教导我,让我养成良好习惯。这样长大才能成为一个有用的人。良好的习惯是尊敬师长这样长大才能成为一个有用的人。良好的习惯是尊敬师长,爱护同学,对人有礼貌;是不粗心,做事情不拖拉;还是爱护公物,不浪费粮食。为什么呢?因为拥有良好习惯,做一个品德高尚的人,懂得尊重别人,才会得到别人的尊重。我要努力地做到这些。我有一些坏习惯,有时候学习很粗心,把一些会做的题做错。在生活上,也很粗心,有一次早上起床居然穿反了衣服。我吃饭很慢,有的时候还剩饭。我还起床磨蹭,本来应该迅速地穿好衣服,但是,我总是磨磨蹭蹭地,速度很慢。“我打算在这学期里,改掉这些坏习惯。早上起来,迅速地穿好衣服,不拖拉。学习不粗心,仔细完成每一道题。吃饭的时候,要很快的把饭吃完,不剩饭。我要从一点一滴做起,逐渐养成良好习惯。我相信自己一定能成为一名品学兼优的好学生!我打算在这学期里,改掉这些坏习惯。早上起来,迅速地穿好衣服,不拖拉。学习不粗心,仔细完成每一道题。吃饭的时候,要很快的把饭吃完,不剩饭。我要从一点一滴做起,逐渐养成良好习惯。我相信自己一定能成为一名品学兼优的好学生!” 在上幼儿园以前,我什么也不会干,就连穿衣服也是妈妈给我穿好,就要上幼儿园了,这样可不行,妈妈锻炼我要学会自己穿衣服。 有一天,妈妈把衣服摆在我面前,开始让我自己穿。一开始。我又哭又叫就是不穿,还把衣服扔的满地都是,然后坐在地上开始大哭,等了好长时间,妈妈还是不理我,我只好自己乖乖的把衣服穿好, 一出了房间门,妈妈就笑了起来,再看看我的衣服,毛衣和裤子都穿反了,我赶紧回房间又重新穿了一遍,这次穿好了,拿起外套,可是外套的扣子又扣不上了,扣子可调皮了,好像故意和我作对,我把扣子往扣眼——人类邪恶的根源;爱情——幸福和光明的源泉。我一直在这些思想的舞台上徘徊。突然我发现两个身影从我面前经过,坐在不远的草地上。这是一对从农田那边走过来的青年男女。农田那边有农民的茅舍。在一阵令人伤心的沉默之后,随着一声长叹,我听见从一个肺痨病人的嘴里说出了这样的话:幸福和光明的源泉。我一直在这些思想的舞台上徘徊。突然我发现两个身影从我面前经过,坐在不远的草地上。这是一对从农田那边走过来的青年男女。农田那边有农民的茅舍。在一阵令人伤心的沉默之后,随着一声长叹,我听见从一个肺痨病人的嘴里说出了这样的话幸福和光明的源泉。我一直在这些思想的舞台上徘徊。突然我发现两个身影从我面前经过,坐在不远的草地上。这是一对从农田那边走过来的青年男女。农田那边有农民的茅舍。在一阵令人伤心的沉默之后,随着一声长叹,我听见从一个肺痨病人的嘴里说出了这样的话幸福和光明的源泉。我一直在这些思想的舞台上徘徊。突然我发现两个身影从我面前经过,坐在不远的草地上。这是一对从农田那边走过来的青年男女。农田那边有农民的茅舍。在一阵令人伤心的沉默之后,随着一声长叹,我听见从一个肺痨病人的嘴里说出了这样的话幸福和光明的源泉。我一直在这些思想的舞台上徘徊。突然我发现两个身影从我面前经过,坐在不远的草地上。这是一对从农田那边走过来的青年男女。农田那边有农民的茅舍。在一阵令人伤心的沉默之后,随着一声长叹,我听见从一个肺痨病人的嘴里说出了这样的话幸福和光明的源泉。我一直在这些思想的舞台上徘徊。突然我发现两个身影从我面前经过,坐在不远的草地上。这是一对从农田那边走过来的青年男女。农田那边有农民的茅舍。在一阵令人伤心的沉默之后,随着一声长叹,我听见从一个肺痨病人的嘴里说出了这样的话幸福和光明的源泉。我一直在这些思想的舞台上徘徊。突然我发现两个身影从我面前经过,坐在不远的草地上。这是一对从农田那边走过来的青年男女。农田那边有农民的茅舍。在一阵令人伤心的沉默之后,随着一声长叹,我听见从一个肺痨病人的嘴里说出了这样的话幸福和光明的源泉。我一直在这些思想的舞台上徘徊。突然我发现两个身影从我面前经过,坐在不远的草地上。这是一对从农田那边走过来的青年男女。农田那边有农民的茅舍。在一阵令人伤心的沉默之后,随着一声长叹,我听见从一个肺痨病人的嘴里说出了这样的话幸福和光明的源泉。我一直在这些思想的舞台上徘徊。突然我发现两个身影从我面前经过,坐在不远的草地上。这是一对从农田那边走过来的青年男女。农田那边有农民的茅舍。在一阵令人伤心的沉默之后,随着一声长叹,我听见从一个肺痨病人的嘴里说出了这样的话“亲爱的!擦干你的眼泪,至高无上的爱情已经打开了我们的眼界,使我们成了它的崇拜者。是它, 妈妈常教导我,让我养成良好习惯。这样长大才能成为一个有用的人。良好的习惯是尊敬师长这样长大才能成为一个有用的人。良好的习惯是尊敬师长,爱护同学,对人有礼貌;是不粗心,做事情不拖拉;还是爱护公物,不浪费粮食。为什么呢?因为拥有良好习惯,做一个品德高尚的人,懂得尊重别人,才会得到别人的尊重。我要努力地做到这些。我有一些坏习惯,有时候学习很粗心,把一些会做的题做错。在生活上,也很粗心,有一次早上起床居然穿反了衣服。我吃饭很慢,有的时候还剩饭。我还起床磨蹭,本来应该迅速地穿好衣服,但是,我总是磨磨蹭蹭地,速度很慢。“我打算在这学期里,改掉这些坏习惯。早上起来,迅速地穿好衣服,不拖拉。学习不粗心,仔细完成每一道题。吃饭的时候,要很快的把饭吃完,不剩饭。我要从一点一滴做起,逐渐养成良好习惯。我相信自己一定能成为一名品学兼优的好学生!我打算在这学期里,改掉这些坏习惯。早上起来,迅速地穿好衣服,不拖拉。学习不粗心,仔细完成每一道题。吃饭的时候,要很快的把饭吃完,不剩饭。我要从一点一滴做起,逐渐养成良好习惯。我相信自己一定能成为一名品学兼优的好学生!” 在上幼儿园以前,我什么也不会干,就连穿衣服也是妈妈给我穿好,就要上幼儿园了,这样可不行,妈妈锻炼我要学会自己穿衣服。 有一天,妈妈把衣服摆在我面前,开始让我自己穿。一开始。我又哭又叫就是不穿,还把衣服扔的满地都是,然后坐在地上开始大哭,等了好长时间,妈妈还是不理我,我只好自己乖乖的把衣服穿好, 一出了房间门,妈妈就笑了起来,再看看我的衣服,毛衣和裤子都穿反了,我赶紧回房间又重新穿了一遍,这次穿好了,拿起外套,可是外套的扣子又扣不上了,扣子可调皮了,好像故意和我作对,我把扣子往扣眼——人类邪恶的根源;爱情——幸福和光明的源泉。我一直在这些思想的舞台上徘徊。突然我发现两个身影从我面前经过,坐在不远的草地上。这是一对从农田那边走过来的青年男女。农田那边有农民的茅舍。在一阵令人伤心的沉默之后,随着一声长叹,我听见从一个肺痨病人的嘴里说出了这样的话:“亲爱的!擦干你的眼泪,至高无上的爱情已经打开了我们的眼界,使我们成了它的崇拜者。是它, 每一个碌碌无为的中年人都改明白的一个道理是,职场所谓的新人老人,取决于你的成就,而不是入行时间。 入行十余年还不如别人入行三五年来的专业,所谓老人不过是虚谈。 只要一天还出成绩,对待工作就当保持一个新人该有的拼劲和争上游的心态,抛开顾虑,努力向前便是! -END- 声明:本文属于老板思维与智库(ID:laobanzhiku88),图片来源于网络 看完本文有收获?请转发分享给更多人 欢迎关注“互联网架构师”,我们分享最有价值的互联网技术干货文章,助力您成为有思想的全栈架构师,我们只聊互联网、只聊架构,不聊其他!打造最有价值的架构师圈子和社区。 本公众号覆盖中国主要首席架构师、高级架构师、CTO、技术总监、技术负责人等人 群。分享最有价值的架构思想和内容。打造中国互联网圈最有价值的架构师圈子。 长按下方的二维码可以快速关注我们 如想加群讨论学习,请点击右下角的“加群学习”菜单入群 本篇文章为转载内容。原文链接:https://blog.csdn.net/emprere/article/details/98859913。 该文由互联网用户投稿提供,文中观点代表作者本人意见,并不代表本站的立场。 作为信息平台,本站仅提供文章转载服务,并不拥有其所有权,也不对文章内容的真实性、准确性和合法性承担责任。 如发现本文存在侵权、违法、违规或事实不符的情况,请及时联系我们,我们将第一时间进行核实并删除相应内容。
2023-06-29 14:16:29
119
转载
转载文章
...表本站的立场。 作为信息平台,本站仅提供文章转载服务,并不拥有其所有权,也不对文章内容的真实性、准确性和合法性承担责任。 如发现本文存在侵权、违法、违规或事实不符的情况,请及时联系我们,我们将第一时间进行核实并删除相应内容。 1、引言 IM等社交应用的开发工作中,乱码问题也很常见,比如: 1)IM聊天消息中的Emoji表情为什么发给后端后MySQL数据库里会乱码; 2)文件名中带有中文的大文件聊天消息发送后,对方看到的文名是乱码; 3)Http rest接口调用时,后端读取到APP端传过来的参数有中文乱码问题; ... ... 那么,对于乱码这个看似不起眼,但并不是一两话能讲清楚的问题,是很有必要从根源了解字符集和编码原理,知其然知其所以然显然是一个优秀码农的基本素养,所以,便有了本文,希望能帮助到你。 推荐阅读:关于字符编码知识的详细讲解请见《字符编码那点事:快速理解ASCII、Unicode、GBK和UTF-8》。 学习交流: - 即时通讯/推送技术开发交流5群:215477170 [推荐] - 移动端IM开发入门文章:《新手入门一篇就够:从零开发移动端IM》 (本文同步发布于:http://www.52im.net/thread-2868-1-1.html) 2、关于作者 卢钧轶:爱捣腾Linux的DBA。曾任职于大众点评网DBA团队,主要关注MySQL、Memcache、MMM等产品的高性能和高可用架构。 个人微博:米雪儿侬好的cenalulu Github地址:https://github.com/cenalulu 3、系列文章 本文是IM开发干货系列文章中的第21篇,总目录如下: 《IM消息送达保证机制实现(一):保证在线实时消息的可靠投递》 《IM消息送达保证机制实现(二):保证离线消息的可靠投递》 《如何保证IM实时消息的“时序性”与“一致性”?》 《IM单聊和群聊中的在线状态同步应该用“推”还是“拉”?》 《IM群聊消息如此复杂,如何保证不丢不重?》 《一种Android端IM智能心跳算法的设计与实现探讨(含样例代码)》 《移动端IM登录时拉取数据如何作到省流量?》 《通俗易懂:基于集群的移动端IM接入层负载均衡方案分享》 《浅谈移动端IM的多点登陆和消息漫游原理》 《IM开发基础知识补课(一):正确理解前置HTTP SSO单点登陆接口的原理》 《IM开发基础知识补课(二):如何设计大量图片文件的服务端存储架构?》 《IM开发基础知识补课(三):快速理解服务端数据库读写分离原理及实践建议》 《IM开发基础知识补课(四):正确理解HTTP短连接中的Cookie、Session和Token》 《IM群聊消息的已读回执功能该怎么实现?》 《IM群聊消息究竟是存1份(即扩散读)还是存多份(即扩散写)?》 《IM开发基础知识补课(五):通俗易懂,正确理解并用好MQ消息队列》 《一个低成本确保IM消息时序的方法探讨》 《IM开发基础知识补课(六):数据库用NoSQL还是SQL?读这篇就够了!》 《IM里“附近的人”功能实现原理是什么?如何高效率地实现它?》 《IM开发基础知识补课(七):主流移动端账号登录方式的原理及设计思路》 《IM开发基础知识补课(八):史上最通俗,彻底搞懂字符乱码问题的本质》(本文) 4、正文概述 字符集和编码无疑是IT菜鸟甚至是各种大神的头痛问题。当遇到纷繁复杂的字符集,各种火星文和乱码时,问题的定位往往变得非常困难。 本文内容就将会从原理方面对字符集和编码做个简单的科普介绍,同时也会介绍一些通用的乱码故障定位的方法以方便读者以后能够更从容的定位相关问题。 在正式介绍之前,先做个小申明:如果你希望非常精确的理解各个名词的解释,那么可以详细阅读这篇《字符编码那点事:快速理解ASCII、Unicode、GBK和UTF-8》。 本文是博主通过自己理解消化后并转化成易懂浅显的表述后的介绍,会尽量以简单明了的文字来从要源讲解字符集、字符编码的概念,以及在遭遇乱码时的一些常用诊断技巧,希望能助你对于“乱码”问题有更深地理解。 5、什么是字符集 在介绍字符集之前,我们先了解下为什么要有字符集。 我们在计算机屏幕上看到的是实体化的文字,而在计算机存储介质中存放的实际是二进制的比特流。那么在这两者之间的转换规则就需要一个统一的标准,否则把我们的U盘插到老板的电脑上,文档就乱码了;小伙伴QQ上传过来的文件,在我们本地打开又乱码了。 于是为了实现转换标准,各种字符集标准就出现了。 简单的说:字符集就规定了某个文字对应的二进制数字存放方式(编码)和某串二进制数值代表了哪个文字(解码)的转换关系。 那么为什么会有那么多字符集标准呢? 这个问题实际非常容易回答。问问自己为什么我们的插头拿到英国就不能用了呢?为什么显示器同时有DVI、VGA、HDMI、DP这么多接口呢?很多规范和标准在最初制定时并不会意识到这将会是以后全球普适的准则,或者处于组织本身利益就想从本质上区别于现有标准。于是,就产生了那么多具有相同效果但又不相互兼容的标准了。 说了那么多我们来看一个实际例子,下面就是“屌”这个字在各种编码下的十六进制和二进制编码结果,怎么样有没有一种很屌的感觉? 6、什么是字符编码 字符集只是一个规则集合的名字,对应到真实生活中,字符集就是对某种语言的称呼。例如:英语,汉语,日语。 对于一个字符集来说要正确编码转码一个字符需要三个关键元素: 1)字库表(character repertoire):是一个相当于所有可读或者可显示字符的数据库,字库表决定了整个字符集能够展现表示的所有字符的范围; 2)编码字符集(coded character set):即用一个编码值code point来表示一个字符在字库中的位置; 3)字符编码(character encoding form):将编码字符集和实际存储数值之间的转换关系。 一般来说都会直接将code point的值作为编码后的值直接存储。例如在ASCII中“A”在表中排第65位,而编码后A的数值是 0100 0001 也即十进制的65的二进制转换结果。 看到这里,可能很多读者都会有和我当初一样的疑问:字库表和编码字符集看来是必不可少的,那既然字库表中的每一个字符都有一个自己的序号,直接把序号作为存储内容就好了。为什么还要多此一举通过字符编码把序号转换成另外一种存储格式呢? 其实原因也比较容易理解:统一字库表的目的是为了能够涵盖世界上所有的字符,但实际使用过程中会发现真正用的上的字符相对整个字库表来说比例非常低。例如中文地区的程序几乎不会需要日语字符,而一些英语国家甚至简单的ASCII字库表就能满足基本需求。而如果把每个字符都用字库表中的序号来存储的话,每个字符就需要3个字节(这里以Unicode字库为例),这样对于原本用仅占一个字符的ASCII编码的英语地区国家显然是一个额外成本(存储体积是原来的三倍)。算的直接一些,同样一块硬盘,用ASCII可以存1500篇文章,而用3字节Unicode序号存储只能存500篇。于是就出现了UTF-8这样的变长编码。在UTF-8编码中原本只需要一个字节的ASCII字符,仍然只占一个字节。而像中文及日语这样的复杂字符就需要2个到3个字节来存储。 关于字符编码知识的详细讲解请见:《字符编码那点事:快速理解ASCII、Unicode、GBK和UTF-8》。 7、UTF-8和Unicode的关系 看完上面两个概念解释,那么解释UTF-8和Unicode的关系就比较简单了。 Unicode就是上文中提到的编码字符集,而UTF-8就是字符编码,即Unicode规则字库的一种实现形式。 随着互联网的发展,对同一字库集的要求越来越迫切,Unicode标准也就自然而然的出现。它几乎涵盖了各个国家语言可能出现的符号和文字,并将为他们编号。详见:Unicode百科介绍。 Unicode的编号从 0000 开始一直到10FFFF 共分为17个Plane,每个Plane中有65536个字符。而UTF-8则只实现了第一个Plane,可见UTF-8虽然是一个当今接受度最广的字符集编码,但是它并没有涵盖整个Unicode的字库,这也造成了它在某些场景下对于特殊字符的处理困难(下文会有提到)。 8、UTF-8编码简介 为了更好的理解后面的实际应用,我们这里简单的介绍下UTF-8的编码实现方法。即UTF-8的物理存储和Unicode序号的转换关系。 UTF-8编码为变长编码,最小编码单位(code unit)为一个字节。一个字节的前1-3个bit为描述性部分,后面为实际序号部分: 1)如果一个字节的第一位为0,那么代表当前字符为单字节字符,占用一个字节的空间。0之后的所有部分(7个bit)代表在Unicode中的序号; 2)如果一个字节以110开头,那么代表当前字符为双字节字符,占用2个字节的空间。110之后的所有部分(5个bit)加上后一个字节的除10外的部分(6个bit)代表在Unicode中的序号。且第二个字节以10开头; 3)如果一个字节以1110开头,那么代表当前字符为三字节字符,占用3个字节的空间。110之后的所有部分(5个bit)加上后两个字节的除10外的部分(12个bit)代表在Unicode中的序号。且第二、第三个字节以10开头; 4)如果一个字节以10开头,那么代表当前字节为多字节字符的第二个字节。10之后的所有部分(6个bit)和之前的部分一同组成在Unicode中的序号。 具体每个字节的特征可见下表,其中“x”代表序号部分,把各个字节中的所有x部分拼接在一起就组成了在Unicode字库中的序号。如下图所示。 我们分别看三个从一个字节到三个字节的UTF-8编码例子: 细心的读者不难从以上的简单介绍中得出以下规律: 1)3个字节的UTF-8十六进制编码一定是以E开头的; 2)2个字节的UTF-8十六进制编码一定是以C或D开头的; 3)1个字节的UTF-8十六进制编码一定是以比8小的数字开头的。 9、为什么会出现乱码 乱码也就是英文常说的mojibake(由日语的文字化け音译)。 简单的说乱码的出现是因为:编码和解码时用了不同或者不兼容的字符集。 对应到真实生活中:就好比是一个英国人为了表示祝福在纸上写了bless(编码过程)。而一个法国人拿到了这张纸,由于在法语中bless表示受伤的意思,所以认为他想表达的是受伤(解码过程)。这个就是一个现实生活中的乱码情况。 在计算机科学中一样:一个用UTF-8编码后的字符,用GBK去解码。由于两个字符集的字库表不一样,同一个汉字在两个字符表的位置也不同,最终就会出现乱码。 我们来看一个例子,假设我们用UTF-8编码存储“很屌”两个字,会有如下转换: 于是我们得到了E5BE88E5B18C这么一串数值,而显示时我们用GBK解码进行展示,通过查表我们获得以下信息: 解码后我们就得到了“寰堝睂”这么一个错误的结果,更要命的是连字符个数都变了。 10、如何识别乱码的本来想要表达的文字 要从乱码字符中反解出原来的正确文字需要对各个字符集编码规则有较为深刻的掌握。但是原理很简单,这里用以MySQL数据库中的数据操纵中最常见的UTF-8被错误用GBK展示时的乱码为例,来说明具体反解和识别过程。 10.1 第1步:编码 假设我们在页面上看到“寰堝睂”这样的乱码,而又得知我们的浏览器当前使用GBK编码。那么第一步我们就能先通过GBK把乱码编码成二进制表达式。 当然查表编码效率很低,我们也可以用以下SQL语句直接通过MySQL客户端来做编码工作: mysql [localhost] {msandbox} > selecthex(convert('寰堝睂'using gbk)); +-------------------------------------+ | hex(convert('寰堝睂'using gbk)) | +-------------------------------------+ | E5BE88E5B18C | +-------------------------------------+ 1 row inset(0.01 sec) 10.2 第2步:识别 现在我们得到了解码后的二进制字符串E5BE88E5B18C。然后我们将它按字节拆开。 然后套用之前UTF-8编码介绍章节中总结出的规律,就不难发现这6个字节的数据符合UTF-8编码规则。如果整个数据流都符合这个规则的话,我们就能大胆假设乱码之前的编码字符集是UTF-8。 10.3 第3步:解码 然后我们就能拿着 E5BE88E5B18C 用UTF-8解码,查看乱码前的文字了。 当然我们可以不查表直接通过SQL获得结果: mysql [localhost] {msandbox} ((none)) > selectconvert(0xE5BE88E5B18C using utf8); +------------------------------------+ | convert(0xE5BE88E5B18C using utf8) | +------------------------------------+ | 很屌 | +------------------------------------+ 1 row inset(0.00 sec) 11、常见的IM乱码问题处理之MySQL中的Emoji字符 所谓Emoji就是一种在Unicode位于 \u1F601-\u1F64F 区段的字符。这个显然超过了目前常用的UTF-8字符集的编码范围 \u0000-\uFFFF。Emoji表情随着IOS的普及和微信的支持越来越常见。 下面就是几个常见的Emoji(IM聊天软件中经常会被用到): 那么Emoji字符表情会对我们平时的开发运维带来什么影响呢? 最常见的问题就在于将他存入MySQL数据库的时候。一般来说MySQL数据库的默认字符集都会配置成UTF-8(三字节),而utf8mb4在5.5以后才被支持,也很少会有DBA主动将系统默认字符集改成utf8mb4。 那么问题就来了,当我们把一个需要4字节UTF-8编码才能表示的字符存入数据库的时候就会报错:ERROR 1366: Incorrect string value: '\xF0\x9D\x8C\x86' for column 。 如果认真阅读了上面的解释,那么这个报错也就不难看懂了:我们试图将一串Bytes插入到一列中,而这串Bytes的第一个字节是 \xF0 意味着这是一个四字节的UTF-8编码。但是当MySQL表和列字符集配置为UTF-8的时候是无法存储这样的字符的,所以报了错。 那么遇到这种情况我们如何解决呢? 有两种方式: 1)升级MySQL到5.6或更高版本,并且将表字符集切换至utf8mb4; 2)在把内容存入到数据库之前做一次过滤,将Emoji字符替换成一段特殊的文字编码,然后再存入数据库中。之后从数据库获取或者前端展示时再将这段特殊文字编码转换成Emoji显示。 第二种方法我们假设用 --1F601-- 来替代4字节的Emoji,那么具体实现python代码可以参见Stackoverflow上的回答。 12、参考文献 [1] 如何配置Python默认字符集 [2] 字符编码那点事:快速理解ASCII、Unicode、GBK和UTF-8 [3] Unicode中文编码表 [4] Emoji Unicode Table [5] Every Developer Should Know About The Encoding 附录:更多IM开发方面的文章 [1] IM开发综合文章: 《新手入门一篇就够:从零开发移动端IM》 《移动端IM开发者必读(一):通俗易懂,理解移动网络的“弱”和“慢”》 《移动端IM开发者必读(二):史上最全移动弱网络优化方法总结》 《从客户端的角度来谈谈移动端IM的消息可靠性和送达机制》 《现代移动端网络短连接的优化手段总结:请求速度、弱网适应、安全保障》 《腾讯技术分享:社交网络图片的带宽压缩技术演进之路》 《小白必读:闲话HTTP短连接中的Session和Token》 《IM开发基础知识补课:正确理解前置HTTP SSO单点登陆接口的原理》 《移动端IM开发需要面对的技术问题》 《开发IM是自己设计协议用字节流好还是字符流好?》 《请问有人知道语音留言聊天的主流实现方式吗?》 《一个低成本确保IM消息时序的方法探讨》 《完全自已开发的IM该如何设计“失败重试”机制?》 《通俗易懂:基于集群的移动端IM接入层负载均衡方案分享》 《微信对网络影响的技术试验及分析(论文全文)》 《即时通讯系统的原理、技术和应用(技术论文)》 《开源IM工程“蘑菇街TeamTalk”的现状:一场有始无终的开源秀》 《QQ音乐团队分享:Android中的图片压缩技术详解(上篇)》 《QQ音乐团队分享:Android中的图片压缩技术详解(下篇)》 《腾讯原创分享(一):如何大幅提升移动网络下手机QQ的图片传输速度和成功率》 《腾讯原创分享(二):如何大幅压缩移动网络下APP的流量消耗(上篇)》 《腾讯原创分享(三):如何大幅压缩移动网络下APP的流量消耗(下篇)》 《如约而至:微信自用的移动端IM网络层跨平台组件库Mars已正式开源》 《基于社交网络的Yelp是如何实现海量用户图片的无损压缩的?》 《腾讯技术分享:腾讯是如何大幅降低带宽和网络流量的(图片压缩篇)》 《腾讯技术分享:腾讯是如何大幅降低带宽和网络流量的(音视频技术篇)》 《字符编码那点事:快速理解ASCII、Unicode、GBK和UTF-8》 《全面掌握移动端主流图片格式的特点、性能、调优等》 《子弹短信光鲜的背后:网易云信首席架构师分享亿级IM平台的技术实践》 《微信技术分享:微信的海量IM聊天消息序列号生成实践(算法原理篇)》 《自已开发IM有那么难吗?手把手教你自撸一个Andriod版简易IM (有源码)》 《融云技术分享:解密融云IM产品的聊天消息ID生成策略》 《适合新手:从零开发一个IM服务端(基于Netty,有完整源码)》 《拿起键盘就是干:跟我一起徒手开发一套分布式IM系统》 >> 更多同类文章 …… [2] 有关IM架构设计的文章: 《浅谈IM系统的架构设计》 《简述移动端IM开发的那些坑:架构设计、通信协议和客户端》 《一套海量在线用户的移动端IM架构设计实践分享(含详细图文)》 《一套原创分布式即时通讯(IM)系统理论架构方案》 《从零到卓越:京东客服即时通讯系统的技术架构演进历程》 《蘑菇街即时通讯/IM服务器开发之架构选择》 《腾讯QQ1.4亿在线用户的技术挑战和架构演进之路PPT》 《微信后台基于时间序的海量数据冷热分级架构设计实践》 《微信技术总监谈架构:微信之道——大道至简(演讲全文)》 《如何解读《微信技术总监谈架构:微信之道——大道至简》》 《快速裂变:见证微信强大后台架构从0到1的演进历程(一)》 《17年的实践:腾讯海量产品的技术方法论》 《移动端IM中大规模群消息的推送如何保证效率、实时性?》 《现代IM系统中聊天消息的同步和存储方案探讨》 《IM开发基础知识补课(二):如何设计大量图片文件的服务端存储架构?》 《IM开发基础知识补课(三):快速理解服务端数据库读写分离原理及实践建议》 《IM开发基础知识补课(四):正确理解HTTP短连接中的Cookie、Session和Token》 《WhatsApp技术实践分享:32人工程团队创造的技术神话》 《微信朋友圈千亿访问量背后的技术挑战和实践总结》 《王者荣耀2亿用户量的背后:产品定位、技术架构、网络方案等》 《IM系统的MQ消息中间件选型:Kafka还是RabbitMQ?》 《腾讯资深架构师干货总结:一文读懂大型分布式系统设计的方方面面》 《以微博类应用场景为例,总结海量社交系统的架构设计步骤》 《快速理解高性能HTTP服务端的负载均衡技术原理》 《子弹短信光鲜的背后:网易云信首席架构师分享亿级IM平台的技术实践》 《知乎技术分享:从单机到2000万QPS并发的Redis高性能缓存实践之路》 《IM开发基础知识补课(五):通俗易懂,正确理解并用好MQ消息队列》 《微信技术分享:微信的海量IM聊天消息序列号生成实践(算法原理篇)》 《微信技术分享:微信的海量IM聊天消息序列号生成实践(容灾方案篇)》 《新手入门:零基础理解大型分布式架构的演进历史、技术原理、最佳实践》 《一套高可用、易伸缩、高并发的IM群聊、单聊架构方案设计实践》 《阿里技术分享:深度揭秘阿里数据库技术方案的10年变迁史》 《阿里技术分享:阿里自研金融级数据库OceanBase的艰辛成长之路》 《社交软件红包技术解密(一):全面解密QQ红包技术方案——架构、技术实现等》 《社交软件红包技术解密(二):解密微信摇一摇红包从0到1的技术演进》 《社交软件红包技术解密(三):微信摇一摇红包雨背后的技术细节》 《社交软件红包技术解密(四):微信红包系统是如何应对高并发的》 《社交软件红包技术解密(五):微信红包系统是如何实现高可用性的》 《社交软件红包技术解密(六):微信红包系统的存储层架构演进实践》 《社交软件红包技术解密(七):支付宝红包的海量高并发技术实践》 《社交软件红包技术解密(八):全面解密微博红包技术方案》 《社交软件红包技术解密(九):谈谈手Q红包的功能逻辑、容灾、运维、架构等》 《即时通讯新手入门:一文读懂什么是Nginx?它能否实现IM的负载均衡?》 《即时通讯新手入门:快速理解RPC技术——基本概念、原理和用途》 《多维度对比5款主流分布式MQ消息队列,妈妈再也不担心我的技术选型了》 《从游击队到正规军(一):马蜂窝旅游网的IM系统架构演进之路》 《从游击队到正规军(二):马蜂窝旅游网的IM客户端架构演进和实践总结》 《IM开发基础知识补课(六):数据库用NoSQL还是SQL?读这篇就够了!》 《瓜子IM智能客服系统的数据架构设计(整理自现场演讲,有配套PPT)》 《阿里钉钉技术分享:企业级IM王者——钉钉在后端架构上的过人之处》 >> 更多同类文章 …… (本文同步发布于:http://www.52im.net/thread-2868-1-1.html) 本篇文章为转载内容。原文链接:https://blog.csdn.net/hellojackjiang2011/article/details/103586305。 该文由互联网用户投稿提供,文中观点代表作者本人意见,并不代表本站的立场。 作为信息平台,本站仅提供文章转载服务,并不拥有其所有权,也不对文章内容的真实性、准确性和合法性承担责任。 如发现本文存在侵权、违法、违规或事实不符的情况,请及时联系我们,我们将第一时间进行核实并删除相应内容。
2024-04-29 12:29:21
522
转载
转载文章
...表本站的立场。 作为信息平台,本站仅提供文章转载服务,并不拥有其所有权,也不对文章内容的真实性、准确性和合法性承担责任。 如发现本文存在侵权、违法、违规或事实不符的情况,请及时联系我们,我们将第一时间进行核实并删除相应内容。 本文为课程《激光原理》课程调研综述论文成果,要求为调研激光相关的某个领域,并写5000字小综述一篇。论文完成时间:2021-11。 版权声明:除特殊标注外,本文全部图片及文字版权归作者所有,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 本文链接:https://blog.csdn.net/yyyyang666/article/details/129210164 激光诱导击穿光谱联合激光诱导荧光技术(LIBS-LIF)在环境监测上的元素分析应用 摘 要: 环境监测的重要性在当今环境问题日渐突出的背景下愈发显著。在环境问题中,土壤问题和水质问题是十分重要的课题之一,对于土壤监测和水质监测往往使用元素分析的方法。传统的实验室检测方式虽然精度高、准确性好,但是耗时长、流程复杂,无法实现原位检测或远程快速检测。使用激光诱导击穿光谱(LIBS)可以有效改善上述问题,但是其准确率低,存在相邻特征谱线干扰。激光诱导击穿光谱联合激光诱导荧光技术(LIBS-LIF)则是对LIBS技术的进一步强化升级,满足了检测需求。文章首先介绍了LIBS技术以及LIBS-LIF技术的基本原理;接着简要介绍LIBS-LIF技术在土壤监测的应用情况,介绍了技术的应用起源和研究进展;然后介绍LIBS技术和LIBS-LIF技术在水质监测方面的应用,由于液体检测中对于预处理的方式最为重要,因此此处简要归纳了液体检测样品预处理的方法,最后对LIBS-LIF技术在环境方面的应用做出总结和展望。LIBS-LIF技术具有着传统实验室检测无法比拟的优势,也正处于热门研究方向,未来潜力无限。 关键词: 激光诱导击穿光谱(LIBS);激光诱导击穿光谱联合激光诱导荧光技术(LIBS-LIF);环境监测;土壤监测;水质监测 Elemental Analysis Application of Laser Induced Breakdown Spectroscopy assisted with Laser Induced fluorescence(LIBS-LIF) Technology in Environmental Monitoring Abstract: The importance of environmental monitoring is becoming more and more significant under the background of increasingly prominent environmental problems. Among the environmental problems, soil problem and water quality problem is one of the very important topics. Element analysis is often used for soil monitoring and water quality monitoring. Although the traditional laboratory detection method has high accuracy and good accuracy, it takes a long time and the process is complex, so it is impossible to realize in-situ detection or remote rapid detection. Laser induced breakdown spectroscopy (LIBS) can effectively improve the above problems, but its accuracy is low and there is interference between adjacent characteristic lines. Laser-induced breakdown spectroscopy assisted with laser-induced fluorescence (LIBS-LIF) is a further enhancement and upgrade of LIBS technology to meet the detection needs. This paper first introduces the basic principles of LIBS technology and LIBS-LIF technology, then briefly introduces the application of LIBS-LIF technology in soil monitoring, and introduces the application origin and research progress of LIBS-LIF technology. Then it introduces the application of LIBS technology and LIBS-LIF technology in water quality monitoring. Because the way of pretreatment is the most important in liquid detection, the pretreatment methods of liquid testing samples are briefly summarized here. Finally, the application of LIBS-LIF technology in the environment is summarized and prospected. LIBS-LIF technology has incomparable advantages over traditional laboratory testing, and it is also in a hot research direction, with unlimited potential in the future. Keywords: Laser induced breakdown spectroscopy(LIBS); Laser induced breakdown spectroscopy assisted with Laser Induced fluorescence(LIBS-LIF); Environmental monitoring; Soil monitoring; Water quality monitoring Completion time: 2021-11 目录 0. 引言 1. 技术简介 1.1 LIBS技术简介 1.1.1 LIBS技术的基本原理 1.1.2 LIBS技术的定量分析 1.1.3 LIBS技术的优缺点 1.2 LIBS-LIF技术 1.2.1 LIF技术的基本原理 1.2.2 Co原子的LIBS-LIF增强原理 2. LIBS-LIF技术用于土壤监测 2.1 早期研究 2.2 近期研究现状 3. LIBS及LIBS-LIF技术用于水质监测 3.1液体直接检测 3.2液固转换检测 3.2.1吸附法 3.2.2成膜法 3.2.3微萃取法 3.2.4冷冻法 3.2.5电沉积法 3.3液气转换检测 4. 总结与展望 参考文献 0. 引言 随着经济的发展,人们物质生活水平提高的同时,环境的问题也愈发突出,其中,土壤问题和水体问题十分突出。 土壤是包括人类在内的一切生物体生存的载体,土壤的质量与农作物的生长息息相关,而农作物的收成则是人类发展的基石。在工业化发展的影响下,土壤重金属污染和积累成为了一个世界性的问题,尤其在中国特别是长三角地区尤为严重[1]。 水是生命之源,水体问题直接关系到所有生物体的生存。环境中的水体问题,主要集中在工业废水的治理与监测上。工业废水中含有大量重金属元素,其难以生物降解,重金属元素会随着水体流动而扩散。 物质元素分析在土壤分析和水质分析上是常用的方式。传统的分析方法是基于实验室的元素光谱分析法,其具有高精度、高稳定的特点,如:原子吸收光谱法(Atomic absorption spectrometry, AAS)、电感耦合等离子体质谱法(Inductively coupled plasma mass spectrometry, ICP-MS)、电感耦合等离子体原子发射光谱法(Inductively coupled plasma atomic emission spectrometry, ICP-AES)等,但是此类光谱的检测样品预处理复杂、检测操作难度高、需要庞大复杂的实验设备,且对样品造成损坏,有所不便[2,3]。 激光诱导击穿光谱(Laser induced breakdown spectroscopy,LIBS)是一种基于原子光谱分析技术,与传统的光谱分析技术相比,其实验装置简单便携、操作简便、应用广泛、可远程测量,同时有在简单预处理样品或根本不预处理的情况下进行现场测量的潜力。因此,其满足在环境监测中,特别是土壤监测和水质监测此类希望可以在现场检测、快速便捷检测,同时精度较高的需求。LIBS技术很容易与其他技术如激光诱导荧光技术(Laser induced fluorescence, LIF)、拉曼光谱(Raman)等技术联用,进一步提高了 LIBS技术的检测准确度和竞争力[4]。 1. 技术简介 1.1 LIBS技术简介 LIBS技术最早可以追溯到20世纪60年代Brech, F.和Cross, L.所做的激光诱导火花散射实验,其中的一项实验使用红宝石激光器产生的激光照射材料后产生等离子体羽流。经过了几十年的发展,LIBS技术得到了显著发展,其在环境检测、文物保护鉴定、岩石检测、宇宙探索等领域中被广泛应用。 1.1.1 LIBS技术的基本原理 LIBS技术的装置主要由脉冲激光器、光谱仪、样品装载平台和计算机组成,光谱仪和计算机之间常常由光电倍增管或CCD等光电转换器件连接,如图 1所示[3]。 图 1 LIBS实验装置图[3] 首先,通过脉冲激光器产生强脉冲激光后由透镜聚焦到样品上,被聚焦区域的样品吸收,产生初始自由电子,并在持续的激光脉冲作用下加速。初始自由电子获取到足够高的能量之后,会轰击原子电离产生新的自由电子。随着激光脉冲作用的持续,自由电子和原子的作用如此往复碰撞,在短时间内形成等离子体,形成烧蚀坑。接着,激光脉冲结束,等离子体温度逐渐降低,产生连续背景辐射并产生原子或离子的发射光谱。通过光谱仪采集信号,在计算机上分析特征谱线的波长和强度信息就可以对样本中的元素进行定性和定量分析[2]。 1.1.2 LIBS技术的定量分析 由文献[2]可知,LIBS技术的定量分析方法通常有外标法、内标法和自由校准法(CF)。其中,最简单方便的是外标法。 外标法由光谱分析基本定量公式Lomakin-Scheibe公式 I=aCb(1)I=aC^b \tag{1} I=aCb(1) 式中III为光谱强度,aaa为比例系数,CCC为元素浓度,bbb为自吸收系数。自吸收系数bbb会随着元素浓度CCC的减小而增大,当元素浓度CCC很小时,b=1b=1b=1。使用同组仪器测量时aaa和bbb的值为定值。 将式(1)左右两边取对数,得 lgI=blgC+lga(2)lgI=blgC+lga \tag{2} lgI=blgC+lga(2) 由式(2)可知,当b=1时,光谱强度和元素浓度呈线性关系。因此,可以通过检验一组标准样品的元素浓度和对应的光谱强度,绘制出对应的标准曲线,从而根据曲线的得到未知样品的浓度值。 如图 2 (a)(b)所示,通过使用LIBS技术多次测定一系列含有Co元素的标准样品的光谱强度后取平均可以绘制出图 2 (b)所示的校正曲线[5]。同时可以计算出曲线的相关系数R^2、交叉验证均方差(RMSECV)和样品中Co元素的检出限(LOD)。 图 2 用LIBS和LIBS-LIF技术测定有效钴元素的光谱和校准曲线[5] (a) (b)使用LIBS技术测定,(c) (d)使用LIBS-LIF技术测定 1.1.3 LIBS技术的优缺点 随着LIBS技术的提高和广泛应用,其自身独特的优势也显示出来,其主要优点主要如下[6]: (1)样品不需要进行预处理或只需要稍微预处理。 (2)样品检测时间短,相较于传统的AAS、ICP-AES等技术检测需要几分钟到几小时的时间相比,LIBS技术检测只需要3-60秒。 (3)样品的检出限LOD高,对于低浓度样品检测更加灵敏精确。 (4)实验装置结构简单,便携性高。 (5)可用于远程遥感监测 (6)对于检测样品的损伤基本没有,十分适合对于文物遗迹等方面进行应用 LIBS技术也有着自身的缺陷,其中问题最大的就是相较于传统的AAS、ICP-AES等技术来说,LIBS的检测准确性低,只有5-20%。 但LIBS还有一个优点在于很容易与其他技术如激光诱导荧光技术(Laser induced fluorescence, LIF)、拉曼光谱(Raman)等技术联用,可以弥补LIBS技术的检测准确率低的缺陷,同时结合其他技术的优势提高竞争力[7]。 1.2 LIBS-LIF技术 LIBS技术常常与LIF技术联合使用,即LIBS-LIF技术。通过LIF技术对特征曲线信号的选择性加强作用,有效的提高了检测的准确率,改善了单独使用LIBS检测准确率低的缺陷。 LIBS-LIF技术在1979年由Measures, R. M.和Kwong, H. S.首次使用,用于各种样品中微量铬元素的选择性激发。 1.2.1 LIF技术的基本原理 LIF技术,是通过激光辐射激发原子或者分子,之后被照射的原子或分子自发发射出的荧光。 首先,调节入射激光的波长,从而改变入射激光的能量。之后,当入射激光的能量与检测区域中的气态分子或原子的能级差相同时,分子或原子将被激光共振激发跃迁至激发态,但是这种激发态并不稳定,会通过自发辐射释放出另一个光子能量并向下跃迁,同时发射出分子或原子荧光,这便是激光诱导荧光。 其中,分子或原子发射荧光的跃迁过程主要有共振荧光、直越线荧光、阶跃线荧光和多光子荧光四种,如图3所示[2]。元素被激发的直跃线荧光往往强度大,散射光干扰弱,故被常用。 图 3 分子或原子发射荧光的跃迁过程[2] 1.2.2 Co原子的LIBS-LIF增强原理 下面将以Co元素为例,说明LIBS-LIF技术的原理。 Co元素直跃线荧光的产生原理图如图 4所示[5]。波长为304.40nm的激光能量刚好等于Co原子基态到高能态(4.07eV)的能级差,Co原子被304.40nm的激发照射后跃迁至该能级。随后,该能级上的Co原子通过自发辐射释放能量跃迁至低能态(0.43eV),同时发出波长为304.51nm的荧光。因此,采用LIF的激发波长为304.40nm,光谱仪对应的检测波长为304.51nm。 图 4 Co元素直跃线荧光产生原理图[5] LIBS-LIF技术的装置如图 5所示[5],与LIBS装置不同的是其增加了一台可调激光器,如染料激光器、OPO激光器等。其用于激发特定元素的被之前LIBS激发出的等离子体。该激光平行于样品表面照射,不会对样品产生损伤。 图 5 LIBS-LIF实验装置图[5] 在本次Co元素的检测中,OPO激光器的波长为304.40nm。样品首先通过脉冲激光器垂直照射后产生等离子体,原理和LIBS技术一致。之后使用OPO激光器产生的304.40nm的激光照射等离子体,激发荧光信号,增强特征谱线的强度。最后通过光谱仪采集信号,在计算机上分析特征谱线。 LIBS-LIF技术对Co原子测定的光谱和校正曲线如图 2 (c)(d)所示。通过与(a)(b)图对可得到,使用LIBS-LIF技术明显增强了Co原子的特征谱线强度,同时定量分析得到的校正曲线的相关系数R^2、交叉验证均方差(RMSECV)和样品中Co元素的检出限(LOD)数值都有很好的改善。 2. LIBS-LIF技术用于土壤监测 土壤监测是LIBS-LIF技术的最传统应用方向之一。土壤成分复杂,蕴含多种微量元素,这些元素必须维持在合理的范围内。若如铬等相关微量元素过低,则会对作物的生长产生影响;而若铅等重金属元素过高,则表明土地受到了污染,种植出的作物可能存在重金属残留的问题。 2.1 早期研究 LIBS-LIF技术用于大气压下的土壤元素检测可以最早追溯到1997年Gornushkin等人使用LIBS技术联合大气紫外线测定石墨、土壤和钢中钴元素的可行性[8],其紫外线即起到作为LIF光源的作用。 之后,为了评估该技术在现场快速检测分析中的可行性,其使用了可以同时检测分析22种元素的Paschen-Runge光谱仪以发挥LIBS技术可以快速检测多种元素的优势。同时使用染料激光器作为LIF光源,使用LIBS-LIF技术对Cd和TI元素进行了信号选择性增强测量,排除了邻近元素谱线的干扰。但是对于Pb元素还无法检测[9]。 2.2 近期研究现状 华中科技大学GAO等人在2018年对土壤中难以检测的Sb元素使用LIBS-LIF技术进行检验,排除了检验Sb元素时邻近Si元素的干扰,并探讨了使用常规LIBS时在287nm-289nm的波长下不同的ICCD延时长度对信号强度的影响,以及使用LIBS-LIF技术时作为LIF光源的OPO激光器激光能量对Sb元素特征谱线信号强度与信噪比的影响、激光光源脉冲间延时长度对Sb元素特征谱线信号强度与信噪比的影响,由相关结果得到了最优实验条件[10],如图 6至图 8所示。 图 6 不同ICCD延迟时间下样品在287.0-289.0 nm波段的光谱 图 7 LIBS-LIF和常规LIBS得到的光谱比较 图 8 Sb特征谱线的强度和信噪比曲线 (A)Sb特征谱线的强度和信噪比随OPO激光能量的变化关系;(B)Sb特征谱线的强度和信噪比随两个激光器之间脉冲延迟的变化关系 近期,该实验室研究了利用LIBS-LIF测定土壤中的有效钴含量。该实验着重于研究检测土壤中能被植物吸收的元素,即有效元素,强化研究的实际意义;利用DPTA提取样品,增大检测浓度;使用LIBS-LIF测定有效钴含量,排除了相邻元素的干扰。 3. LIBS及LIBS-LIF技术用于水质监测 LIBS及LIBS-LIF技术用于水质检测的原理和流程土壤检测基本一致,但是面临着更多的挑战。在水样的元素定量测定中,水的溅射会干扰到光的传播和收集,从而降低采集的灵敏度;由于水中羟基(OH)的猝灭作用会使得激发的等离子体寿命较短,因此等离子体的辐射强度低,进而影响分析灵敏度[2]。同时,由于部分实验方式造成使用LIBS-LIF技术不太方便,只能使用传统LIBS技术。 因此,在使用LIBS技术进行检验时还需要做相关改进。最常见的就是进行样品的预处理,在样品制备上进行改进。 由文献[11]整理可知,样品的预处理主要可以分为液体直接检测、液固转换检测、液气转换检测三种。 3.1液体直接检测 液体直接检测主要有两种方式:将光聚焦在静态液体测量和将光聚焦在流动的液体测量两种。 最早期使用LIBS技术进行检验的就是直接将光聚焦在静态液体表面测量。但其精确度和灵敏度往往比将光聚焦在流动的液体测量低。Barreda等人比较了在静态、液体喷射态和液体流动态下硅油中的铂元素使用LIBS进行检测,最后液体喷射态和液体流动态下的LOD比静态下降低了7倍[12]。 但上述实验是在有气体保护下进行的结果。总体上看,液体直接检测并不是一个很好的选择。 图 9 液体分析的三种不同实验装置图[12] a液体喷射分析,b静态液体分析,c通道流动液体分析 3.2液固转换检测 液固转换法是检测中最常用的方法,其主要可以分为以下几类: 3.2.1吸附法 吸附法是最常用的预处理方式,利用可吸附材料吸收液体中的微量元素。常用的材料有碳平板、离子交换聚合物膜,或者滤纸、竹片等将液体转换为固体,从而进行分析。 2008年,华南理工大学Chen等人以木片作为基底吸附水溶液的方式测定了Cr、Mn、Cu、Cd、Pb五种金属元素在微量浓度下的校正曲线,其检出限比激光聚焦在页面上直接分析高出2-3个数量级[13]。之后2017年,同实验室的Kang等人以木片作为基底吸附水溶液的方式,使用LIBS-LIF技术对水中的痕量铅进行了高灵敏度测量,最后得到的铅元素的LOD为~0.32ppb,超过了传统实验室检测技术ICP-AES的检测方式,为国际领先水平[14]。 3.2.2成膜法 与吸附法相反,成膜法是将水样滴在非吸水性衬底上,如Si+SiO2衬底和多空电纺超细纤维等,然后干燥成膜,从而转化为固体进行分析。 3.2.3微萃取法 微萃取法是利用萃取剂和溶液中的微量元素化学反应来实现富集。其中,分散液液体微萃取(Dispersion liquid-liquid microextraction, DLLME)是一种简单、经济、富集倍数高、萃取效率高的方法,被广泛使用。 3.2.4冷冻法 将液体冷冻成为冰是液固转化的一种直接预处理方式,冰的消融可以防止液体飞溅和摇晃,从而改善液体分析性能。 3.2.5电沉积法 电沉积法是利用电化学反应,将液体中的样品转化为固体样品并进行预浓缩,之后用于检测。该方法可以使得灵敏度大大提高,但是实验设备也变得复杂,预处理工作量也有变大。 3.3液气转换检测 将液体转化为气溶胶可以使得样品更加稳定,从而产生更稳定的检测信号。可以使用超声波雾化器和膜干燥器等产生气溶胶,再进行常规的LIBS-LIF检测。 Aras等人使用超声波雾化器和薄膜干燥器单元产生亚微米级的气溶胶,实现了液气体转换,并在实际水样上测试了该超声雾化-LIBS系统的适用性,相关实验装置如图 10、图 11所示[15]。 图 10 用于金属气溶胶分析的LIBS实验装置图[15] M:532 nm反射镜,L:聚焦准直透镜,W:石英,P:泵浦,BD:光束转储 图 11 样品导入部分结构图[15] (A)与薄膜干燥器相连的USN颗粒发生器去溶装置(加热器和冷凝器);(B)与5个武装聚四氟乙烯等离子电池相连的薄膜干燥器。G:进气口,DU:脱溶装置,W:废料,MD:薄膜干燥机,L:激光束方向,C:样品池,M:反射镜,F.L.:聚焦透镜 4. 总结与展望 本文简要介绍了LIBS和LIBS-LIF的原理,并对LIBS-LIF在环境监测中的土壤监测和水质检测做了简要的介绍和分类。 LIBS-LIF在土壤监测的技术已经逐渐成熟,基本实现了土壤的快速检测,同时也有相关便携式设备的研究正在进行。对于水质监测方面,使用LIBS-LIF检测往往集中在液固转换法的使用上,对于气体和液体直接检测,由于部分实验装置的限制,联用LIF技术往往比较困难,只能使用传统的LIBS技术。 LIBS-LIF技术快速检测、不需要样品预处理或只需要简单处理、可以实现就地检测等优势与传统实验室检测相比有着独到的优势,虽然目前由于技术限制精度还不够高,但是在当前该领域的火热研究趋势下,相信未来该技术必定可以大放异彩,为绿色中国奉献光学领域的智慧。 参考文献 [1] Hu B, Jia X, Hu J, et al.Assessment of Heavy Metal Pollution and Health Risks in the Soil-Plant-Human System in the Yangtze River Delta, China[J].International Journal of Environmental Research and Public Health,2017, 14 (9): 1042. [2] 康娟. 基于激光剥离的物质元素高分辨高灵敏分析的新技术研究[D]. 华南理工大学,2020. [3] 马菲, 周健民, 杜昌文.激光诱导击穿原子光谱在土壤分析中的应用[J].土壤学报: 1-11. [4] Gaudiuso R, Dell'aglio M, De Pascale O, et al.Laser Induced Breakdown Spectroscopy for Elemental Analysis in Environmental, Cultural Heritage and Space Applications: A Review of Methods and Results[J].Sensors,2010, 10 (8): 7434-7468. [5] Zhou R, Liu K, Tang Z, et al.High-sensitivity determination of available cobalt in soil using laser-induced breakdown spectroscopy assisted with laser-induced fluorescence[J].Applied Optics,2021, 60 (29): 9062-9066. [6] Hussain Shah S K, Iqbal J, Ahmad P, et al.Laser induced breakdown spectroscopy methods and applications: A comprehensive review[J].Radiation Physics and Chemistry,2020, 170. [7] V S D, George S D, Kartha V B, et al.Hybrid LIBS-Raman-LIF systems for multi-modal spectroscopic applications: a topical review[J].Applied Spectroscopy Reviews,2020, 56 (6): 1-29. [8] Gornushkin I B, Kim J E, Smith B W, et al.Determination of Cobalt in Soil, Steel, and Graphite Using Excited-State Laser Fluorescence Induced in a Laser Spark[J].Applied Spectroscopy,1997, 51 (7): 1055-1059. [9] Hilbk-Kortenbruck F, Noll R, Wintjens P, et al.Analysis of heavy metals in soils using laser-induced breakdown spectrometry combined with laser-induced fluorescence[J].Spectrochimica Acta Part B-Atomic Spectroscopy,2001, 56 (6): 933-945. [10] Gao P, Yang P, Zhou R, et al.Determination of antimony in soil using laser-induced breakdown spectroscopy assisted with laser-induced fluorescence[J].Appl Opt,2018, 57 (30): 8942-8946. [11] Zhang Y, Zhang T, Li H.Application of laser-induced breakdown spectroscopy (LIBS) in environmental monitoring[J].Spectrochimica Acta Part B: Atomic Spectroscopy,2021, 181: 106218. [12] Barreda F A, Trichard F, Barbier S, et al.Fast quantitative determination of platinum in liquid samples by laser-induced breakdown spectroscopy[J].Anal Bioanal Chem,2012, 403 (9): 2601-10. [13] Chen Z, Li H, Liu M, et al.Fast and sensitive trace metal analysis in aqueous solutions by laser-induced breakdown spectroscopy using wood slice substrates[J].Spectrochimica Acta Part B: Atomic Spectroscopy,2008, 63 (1): 64-68. [14] Kang J, Li R, Wang Y, et al.Ultrasensitive detection of trace amounts of lead in water by LIBS-LIF using a wood-slice substrate as a water absorber[J].Journal of Analytical Atomic Spectrometry,2017, 32 (11): 2292-2299. [15] Aras N, Yeşiller S Ü, Ateş D A, et al.Ultrasonic nebulization-sample introduction system for quantitative analysis of liquid samples by laser-induced breakdown spectroscopy[J].Spectrochimica Acta Part B: Atomic Spectroscopy,2012, 74-75: 87-94. 本篇文章为转载内容。原文链接:https://blog.csdn.net/yyyyang666/article/details/129210164。 该文由互联网用户投稿提供,文中观点代表作者本人意见,并不代表本站的立场。 作为信息平台,本站仅提供文章转载服务,并不拥有其所有权,也不对文章内容的真实性、准确性和合法性承担责任。 如发现本文存在侵权、违法、违规或事实不符的情况,请及时联系我们,我们将第一时间进行核实并删除相应内容。
2023-08-13 12:41:47
360
转载
站内搜索
用于搜索本网站内部文章,支持栏目切换。
知识学习
实践的时候请根据实际情况谨慎操作。
随机学习一条linux命令:
env | sort
- 列出并排序所有环境变量及其值。
推荐内容
推荐本栏目内的其它文章,看看还有哪些文章让你感兴趣。
2023-04-28
2023-08-09
2023-06-18
2023-04-14
2023-02-18
2023-04-17
2024-01-11
2023-10-03
2023-09-09
2023-06-13
2023-08-07
2023-03-11
历史内容
快速导航到对应月份的历史文章列表。
随便看看
拉到页底了吧,随便看看还有哪些文章你可能感兴趣。
时光飞逝
"流光容易把人抛,红了樱桃,绿了芭蕉。"