HTML5上下左右轮盘菜单导航代码

下载地址 HTML5上下左右轮盘菜单导航代码是一款炫酷的css轮盘菜单导航,该轮盘菜单默认位置是网页的左上,但也可以选择分布在网页的其他三个不同位置。 dd:

【数据结构】时间复杂度的计算方法

时间复杂度的计算方法 我们通常把程序执行的次数叫做频度。 频度函数 f(n) 计算程序的频度之和 时间复杂度: T(n) = O( f(n)) 大O表示法的几种常见情况: 复杂度为常数,如23,9999,等等 都表示为O(1)复杂度包含n时,省略系数与常数项,只取n的最高阶项 如:2n+45 为 O(n) ; 4n3+6n2+n 为O(n^3)复杂度为对数时:如log5(n)、log2(n) 等等 都表示为 O(logn)省略低阶,只取高阶 (即取最大的),类似与高数极限的抓大头 如:logn+nlogn 表示为O(nlogn) 复杂度大小: O(1) < O(logn) < O(n) < O(nlogn) < O(n^2) < O(n^3) < O(2^n) < O(n!) < O(n^n) 实例 例一: void method1(){ printf("祝你"); //执行1次 printf("诸事顺利"); //执行1次 printf("万事如意"); //执行1次 } // f(n) = 1+1+1 = 3 结果: f(n)= 1 + 1 + 1 = 3

idea 导入的类变成红色,pom文件显示删除线

idea 导入的类变成红色 启动 idea 打开项目发现导入的类都变红了,包名还是能找到,就是类找不到。 点击 idae 的 File > Invalideate Caches / Restart 清除缓存并重启 接下来等待 idea 重启完成就发现红名的类可以识别了 如果是新增的文件显示为红色,临时处理办法为 鼠标右键 -》 add to vcs。 还可以设置新增时自动添加到vcs:file→setting→version control→confirmation→when files are created 选择add silently idea中的maven项目中pom.xml文件显示删除线 解决方案 Ctrl+Alt+S 打开设置搜索Ignored 如下图将排除的文件前的勾去掉即可

vue项目打包优化,防止项目代码泄漏

在开发VUE项目的时候,可能有些情况下,我们的VUE项目打包后发布到服务器上访问,但是在chrome开发调试里的Sources—> Page—> webpack 可以查看到项目的webpack 包。 为了代码安全性,还是禁止掉比较好,因为我们不能让别人看到打包后的项目的vue源码,所以要做下配置: vue cli2: 打开config/index.js,将build对象下面的productionSourceMap设置成false vue cli3: 在根目录打开vue.config.js,如果没有就自己创建一个,然后在配置文件里设置productionSourceMap为false module.exports = { productionSourceMap: false, // 生产环境的 source map 设置上线后是否加载webpack文件 } 注意:vueCli3中productionSourceMap设置为false,有可能出现不生效的情况,这时候就还要同时设置 configureWebpack.devtool module.exports = { configureWebpack: config => { config.devtool = false; ... }, productionSourceMap: false, }

Matlab导入Excel数据进行三维轨迹制图

单独选中想要画图的内容 step.2 打开Matlab 并导入数据 step.3 选中要导入的数据 并选择以数值矩阵输出 step.4 点击确认后 对工作区的数据进行重命名 step.5 如代码所示 x = A(:,1);%x列参数命名 y = A(:,2);%y列参数命名 z = A(:,3);%z列参数命名 plot3(x,y,z)%三维图形 box on%设置边框 axis([-2,10,-40,10,-10,50]);%X/Y/Z坐标轴区间 ax = gca;%当前图标 ax.ZGrid = 'on';%X网格化开启 ax.XGrid = 'on';%y网格化开启 ax.YGrid = 'on';%z网格化开启 %坐标轴命名 xlabel('X方向'); ylabel('Y方向'); zlabel('Z方向'); 即可运行

git 进阶系列教程-------git使用流程

GIT使用流程 前言 初衷 git是一门很容易入门的项目管理工具,但是它是一门很难精通的技术。 git pull/git add ./git commit -m "message"/git push/...... 知道以上几个命令,或许再多一点,也许就能说:‘我会git’了。但是在实际工作中,我们需要的git命令不止这些。市面上的大多教程,特别是视频教程,都止步于命令,最多讲一些工作简单流程。 作为一个曾经的小白,我很清楚的知道,即使知道这些命令,在日常使用的时候依旧有一种无从着力的感觉。看着像查询手册一样的技术文档时,我觉得是有什么把我阻挡在了这面技术更深层的外面。明明绝大多数的命令我都用过,知道它们大概能实现什么效果,但是遇到一个实际情形的时候,我依旧需要查阅大量的文档才能知道下一步要如何操作。 我认为这种情况是知识没有成体系所造成的结果,当我查阅了大量文档,知道了这个体系是如何运作的后,我想写一篇这样的文档: 从项目技术leader建立git项目,到项目开发的全部流程。尽可能详细的从应用的角度,讲解git的使用。从场景出发,让后来者相对轻松的入门。 适用人群 对git命令有基础了解的同学、想要体系化重新学习git的同学、想要做项目leader需要对自己的技能有个完善和补充的同学。 开始 阶段一:项目分组(组织:organization) 注意:以下是分组的原因以及必要性,可以跳过不看。 众所周知,git是项目版本管理的工具。而一家公司大概率不止一个项目,而是很多个项目。比如腾讯这家小公司,有游戏相关的项目、有云服务相关的项目、有支付相关的项目。单单游戏相关,肯定又有端游、手游。端游又有蛮多具体的游戏…;扯远了,总之,一家公司根据业务,划分出很多项目组,而项目组又会根据项目划分出不同的项目以及项目团队。 比如:公司做决策时,为了有一些可依赖的、直观的数据而搭建起一套系统(通常就是我们说的大数据)。公司会在团队中找出一些人员,成立一个项目组负责这个事情。而这个项目组很可能拆分出这么一些团队(team):前端团队、后端团队、运维团队。其中前端团队很可能开发两个具体的项目: 项目A—给公司运维人员、分析人员提供的前端页面,主要功能是根据自身权限能查看到一些内部数据,比如日活量、销售额等,页面中规中矩。项目B—给公司领导层提供的前端页面,主要功能是给公司人员分配权限,页面简单。后端团队可能也开发两个具体项目: 项目A----鉴权系统,类似一种中间件或者看门狗,主要功能是拦截没有鉴权的请求,给主服务器减缓压力。项目B—给前端两个项目做支撑的接口服务。 ps: 以上项目分配仅仅是举个例子,有的公司可能会更简单一些,有的会更复杂,有的分配原则和我说的不一样,不过不重要。重要的你要明白即使在一个项目组,很可能依然会分出几个项目团队,每个项目团队依然有可能有多个具体的项目开发任务。 ps: 在项目的托管上,有的公司选择github,有的使用国内的coding,有的使用gitee(呵呵),还有的公司自建gitlab,这里我们采用github来进行托管,流程上都差不多,一通百通。 所以,综上所述,为了应对这种项目组织情况,我们需要创造一个项目组,来组织多个项目和多个团队 接下来就是你身为项目的技术leader应该要做的事情了----创造组织(organization) ps: 建立自己的账号,创造公钥私钥这种事我就不从这篇文章中介绍了,网上优秀的文档有一堆。 1. 创建一个项目组 点击添加,点击New noganization按钮。你看,这并不难 如果不出意外你会看到这样的页面,这个你大概看一下就懂,掏钱的有更好的托管服务,不掏钱版本在使用上有一些限制,具体用什么版本看你公司,当然这是细枝末节,不重要,这里点击免费的版本。 然后呢,你就填写你要创建的组织的相关信息,也不多,主要就三条,组织名、组织邮箱、组织所属公司。然后验证一下,证明你是真人,点击next即可。 然后你就会跳转至这个页面。主要是让你添加一下你要让谁进入你的组织,一同开发,邀请谁就把谁的邮箱放上去即可。暂时我们谁都不邀请。点击compele setup按钮即可 然后进入到这个页面,这个不是我预期的,可能是因为我登录github时间有点久,所以要求我重新输入密码。很可能你不会出现这个页面哈。出现也不怕,输入一下你的github的密码即可。 然后就到了这里,我绷不住了,怎么搞定和我是刚注册的一样呢。这里但凡你英语不是工地学的,应该都能看懂。主要就是说你的项目组的建立是为了做什么,和你新建github账号时的偏好设置差不多,看情况填填就行了,完全不会影响你的正常使用的。 最终,如果你看到了这个页面,说明你的项目已经建立成功了。 2. 创建一个team 创建组织之后,你可以在组织下创建n个项目,你也可以创建多个team。这个没啥先后顺序可言,看你心情。目的是为了让组织中的多个项目和多个team匹配协同嘛。这里我们先创建一个team吧。 填写团队信息 然后你就进入到了下面这个页面,也标示着你的team已经成功创建一个了。 看右上角,这个team目前只有你一个人。你可以点击add a member按钮来添加新的成员进入这个组织,并直接进入这个team。ps: 如果你是这个项目的普通成员之一,你很有可能是这么进入这个项目的。 然后你可以输入成员的一些关键信息(比如他的邮箱),选择添加即可。这里我新创建了一个小号为了给你们演示一下多人开发的场景。然后github就会给该账号绑定的邮箱发送一个邀请邮件。 下面就是邮箱收到的邮件 进入邮件,点击接受邀请 然后你会跳转到github这个网站上,上面是join xxx。确定加入到这个团队。 如果你点击了jion,那你就进入到这个组织的这个team了。 3. 创建一个仓库 在组织中可以有多个仓库,其性质和你的个人仓库差不多,区别在于,这个仓库是方便多个人,多个team一同开发。那我们首先创造一个仓库。 然后就是填写一些仓库信息,我填写了一点信息,仓库名、仓库描述、仓库是共有的,只是没在截图里面。ps:里面有错别字,共有->公有;生命->声明。 然后你就到这么个页面了。这就是仓库的初始化的样子,和你的个人仓库初始化特别像,你会看起来很熟悉,无非是些提示信息。只是在上面多了一个按钮:add teams and collaborators ,意思是给这个仓库增加teams和协作者。也就是说,让组织中的谁来给你开发项目来。 点击之后,其实你会跳转到项目的设置中来。无非就是添加人,添加团队。接下来我给大家说一个概念:有关组织中的人和team。你在组织中可以是独立的人存在着,也可以是team中的一个成员存在着。我是实在没有账号了,就不演示了。相信我你上手就会,这都无关技术,明白概念之后你大胆操作就行了。tips:添加人的时候,可以不是组织下现有的成员。人和team是多对多的关系,所以也有人加入team、退出team,也会有人员的增加、删除,team的增加、删除,我就不一一截图告诉你们了,意义不大,你们自己看看就会的。

【通信原理】六、数字基带传输系统

文章目录 一、数字基带系统与基带信号波形数字基带信号波形及其特点数字基带信号的数学模型 二、数字基带信号的功率谱密度功率谱性质归纳 三、基带传输的基本码型四、数字基带信号传输与码间串扰无码间干扰条件 五、无码间干扰基带传输系统的抗噪声性能双极性信号单极性信号 一、数字基带系统与基带信号波形 对于数字基带信号,我们可以表示为: s ( t ) = ∑ n = − ∞ ∞ a n g ( t − n T B ) s(t)=\sum_{n=-\infty}^{\infty}a_ng(t-nT_B) s(t)=n=−∞∑∞​an​g(t−nTB​) 数字基带信号波形及其特点 单极性不归零波形:极性单一,含有直流分量,长连0/1时无法同步信息 双极性不归零波形:0、1等概率时无直流分量,长连0/1时无法同步信息 单极性归零波形:极性单一,含有直流分量,高电平小于一个码元持续时间,长连0/1时无法同步信息 双极性归零波形:有利于同步信息 差分波形:当为传号差分时,传0不变,传1反转;如果 { a n } \{a_n\} {an​}为绝对码, { b n } \{b_n\} {bn​}为相对码,则编码规则为: b n = a n ⨁ b n − 1 b_n=a_n\bigoplus b_{n-1} bn​=an​⨁bn−1​ 译码规则为: a n = b n ⨁ b n − 1 a_n=b_n\bigoplus b_{n-1} an​=bn​⨁bn−1​

前端开发有哪几个发展方向

前端开发有以下几个发展方向: 移动端开发:主要指开发移动设备(如手机、平板电脑)上使用的应用程序或网站。 响应式设计:主要指设计出能够自适应不同屏幕尺寸的网站。 前端框架:主要指使用已有的前端代码库来更快速、高效地开发网站或应用程序。常用的前端框架有 React、Vue.js 和 Angular。 前端工程化:主要指使用各种工具和方法来提升前端开发的效率和质量。 设计系统:主要指使用统一的设计元素和规范来构建网站或应用程序的用户界面。 进阶 JavaScript:主要指深入学习 JavaScript 语言的高级特性,如异步编程、函数式编程等。

Java优雅的记录日志:log4j实战篇

写在前面 项目开发中,记录错误日志有以下好处: 方便调试 便于发现系统运行过程中的错误 存储业务数据,便于后期分析 在java中,记录日志有很多种方式: 自己实现:自己写类,将日志数据,以io操作方式,写数据到文本文件、数据库中。 使用log4j:log4j可以将日志输出到console窗口、文本文件、数据库等,功能强大! 使用slfj:slfj也是一个很强大的功能,slfj旨在一统天下,提供了logging.jar 和 log4j的接口,可以通过slfj来调用log4j,也可以调用jdk的logging。 使用jdk自带的logging.jar中的方法 log4j需要导入的包 一般使用log4j需要与logging配合使用: commons-logging-1.0.4.jar log4j-1.2.15.jar 添加配置文件 在src下,把log4j的配置文件添加进去log4j.properties。 建立类文件+主函数 修改配置文件,将日志输出到console log4J配置文件为: ### 设置级别和目的地(这里多个目的地) ### log4j.rootLogger = DEBUG,CONSOLE ### 这里的me是包,也就是在这个包记录日志时,是只记录debug及以上级别的日志 log4j.logger.me=DEBUG ### 输出到控制台 ### log4j.appender.CONSOLE = org.apache.log4j.ConsoleAppender log4j.appender.CONSOLE.Target = System.out log4j.appender.CONSOLE.layout = org.apache.log4j.PatternLayout log4j.appender.CONSOLE.layout.ConversionPattern = %d{ABSOLUTE} %5p %c{1}:%L - %m%n main主函数调用: import org.apache.log4j.Logger; public class Log4jTest { public static Logger logger1 = Logger.getLogger(Log4jTest.class); public static void main(String[] args) { //logger1 logger1.

虚拟机安装python环境

Index of /ftp/python/3.8.15/ 先下载虚拟机的python安装包 当然也可以使用wget命令直接虚拟机下载 1.先在虚拟机中创建一个用于放置python安装包的目录 将该安装包上传到该目录下 2.在开始安装python3之前,先要解决环境依赖问题,通过yum安装工具包,自动处理依赖关系,每个软件包通过空格分割提前安装好这些软件包,日后就不会出现很多坑 yum -y install zlib-devel bzip2-devel libffi-devel openssl-devel ncurses-devel sqlite-devel readline-devel tk-devel gcc make 安装完成后会提示complete! 3.解压python安装包 tar -xzvf Python-3.8.15.tgz 4.进入解压目录 cd Python-3.8.15 依次执行以下命令 --prefix 后面的参数是你指定python的安装目录,自己定义 ./configure --prefix=/.../Python-3.8.15 make make install 执行完成后就可以配置环境变量了 vi /etc/profile 然后source /etc/profile即可 此时输入python调用的还是Linux自带的2.7.5版本,python3才是调用的刚刚安装的版本 此外如果要在虚拟机中部署scrapy,还要安装Twisted

【 字符衔接】

题目描述 已知两个字符串,把第一个字符串的头3个字符和第二个字符串的末尾3个字符合并成一个新字符串 输入 第一行输入T表示有T个测试实例 第二行输入第1个字符串,设定字符串只包含字母或数字,长度大于3 第三行输入第2个字符串,设定字符串只包含字母或数字,长度大于3 以此类推输入下个实例 输出 每行输出合并后新的字符串 输入样例1 2 china1949 szu1983 2012year day14 输出样例1 chi983 201y14 #include<stdio.h> #include<string.h> int main() { int T,i,len2,len3,len1,k,l; scanf("%d",&T); for(int i=0;i<T;i++) { char s1[100],s2[100],s11[100],s22[100]; len2=0; len3=0; len1=0; k=0; l=0; scanf("%s",s1); scanf("%s",s2); len1=strlen(s1); len2=strlen(s2); len3=len2-3; for(k=0;k<3;k++) { s11[k]=s1[k]; } s11[k]='\0'; for(l=len3;l<len2;l++) { s22[l-len3]=s2[l]; } s22[l-len3]='\0'; strcat(s11,s22); puts(s11); } return 0; }

QT QStackedWidget 控件 使用详解

本文详细的介绍了QStackedWidget控件的各种操作,例如:新建界面、页面切换、添加页面、addWidget、count、currentIndex 、currentWidget、indexOf、insertWidget、removeWidget、widget、setCurrentIndex 槽函数、setCurrentWidget 槽函数、currentChanged 信号、widgetRemoved 信号、 样式表等操作。 本系列QT全面详解文章目前共有十八篇,本系列文章较为详细的讲述了QT控件的基础操作和使用,也谢谢大家的关注、点赞、收藏。 本文作者原创,转载请附上文章出处与本文链接。 QT QStackedWidget 控件 使用详解目录 1 新建界面 2 页面切换 2.1 插入第三页 2.2 代码实现 3 添加页面 3.1 新建界面 3.2 代码实现 4 所有函数 4.1 addWidget 4.2 count 4.3 currentIndex 4.4 currentWidget 4.5 indexOf 4.6 insertWidget 4.7 removeWidget 4.8 widget 5 槽函数 5.1 setCurrentIndex 5.2 setCurrentWidget 6 信号槽 6.1 currentChanged 6.2 widgetRemoved 7 .h 8 .cpp 9 样式表 10 其它文章 : 1 新建界面 2 页面切换 2.

安卓逆向so篇(一):so文件调用

一.前言 安卓逆向分析时偶尔会遇到签名算法在native层的,想要调用该签名算法,可以采用以下三种方法: (1)hook相关函数:hook是逆向中最常用的了,不过在电脑端还要整个虚拟机,装对应的app,内存占用较大,有时app还会崩溃,手机端的话也是得装app,需要hook几个不同软件的话内存也是吃力的。 (2)逆向so文件:使用IDA逆向so文件,需要定位到加密函数,还要看得懂汇编和C代码,工作量挺大。 (3)调用so文件:通过反编译技术定位到签名函数,找到定义native方法的类,确定使用的so文件,将so文件移植到自己的项目中,可以随时调用,而且可以整合多个so文件,占内存小,稳定性高。 二.正文 本教程介绍调用so文件的方法,有两种途径: 1.Android App 通过反编译工具jadx搜索定位到签名函数,继续深入找到定义native方法的类,确定使用的so文件,将so文件移植到自己的App中,可以随时调用。 (1) 解压目标App,在lib文件夹中找到目标so文件,将该so文件复制到自己App项目的libs目录下 (2) 在自己App项目中建立签名类(具体的native方法定义通过反编译技术获取),要注意的是包名和类名要和原App一致,否则调用不了。例如某个调用了libNativeHelper.so的类定义如下: package com.xxxxx.helpers; public class AppNativeHelper { public static native int applyPatch(String str, String str2, String str3); public static final native String desCbcDecrypt(String str); public static final native String desCbcEncrypt(String str); public static final native String getDailySignApi(String str); public static final native String getFileMd5(String str); public static final native String getMd5(String str); public static final native String getServerApi(String str); public static native int makePatch(String str, String str2, String str3); public static final native String tokenDecrypt(String str); public static final native String tokenEncrypt(String str); public static native void uninstall(String str, int i, String str2, boolean z); static { try { System.

RocketMQ(六)producer发送单向、同步、异步消息源码

针对RocketMQ三种发送消息的具体源码进行了梳理。 之前已经根据(20条消息) RocketMQ(五)producer发送消息的总体流程_代码---小白的博客-CSDN博客 梳理了Producer发送消息的总体流程,现在来梳理一下内部具体的一个发送消息的源码。 当一切准备就绪,最终单向、同步、异步发送模式都会调用MQClientAPIImpl#sendMessage方法发送消息,该方法是真正的发起请求的方法。 这个方法的逻辑就相对比较简单: 1. 首先构建发送消息命令对象RemotingCommand,此时会判断是否需要更换轻量级消息头,如果sendSmartMsg属性为true(默认为true)或者是批量消息,则使用轻量级消息头。SendMessageRequestHeaderV2相比于requestHeader,其field 全为 a,b,c,d 等短变量名,可以加快FastJson反序列化过程。 2. 根据发送模式执行不同的发送逻辑。单向发送模式调用RemotingClient#invokeOneway方法;异步发送模式调用MQClientAPIImpl#sendMessageAsync方法;同步发送模式调用MQClientAPIImpl#sendMessageSync方法。在异步和同步模式发送方法的调用前还会再检查是否超时,如果超时则不再调用。 /** * MQClientInstance的方法 * 单向、同步、异步消息的最终发送消息的方法 * @param addr broker地址 * @param brokerName brokerName * @param msg msg * @param requestHeader requestHeader * @param timeoutMillis 剩余超发时间 * @param communicationMode 发送模式 * @param sendCallback 发送回调函数 * @param topicPublishInfo topic信息 * @param instance MQClientInstance * @param retryTimesWhenSendFailed 异步发送失败时的重试次数,默认2次 * @param context 发送消息上下文 * @param producer DefaultMQProducerImpl * @return * @throws RemotingException * @throws MQBrokerException * @throws InterruptedException */ public SendResult sendMessage( final String addr, final String brokerName, final Message msg, final SendMessageRequestHeader requestHeader, final long timeoutMillis, final CommunicationMode communicationMode, final SendCallback sendCallback, final TopicPublishInfo topicPublishInfo, final MQClientInstance instance, final int retryTimesWhenSendFailed, final SendMessageContext context, final DefaultMQProducerImpl producer ) throws RemotingException, MQBrokerException, InterruptedException { long beginStartTime = System.

MapReduce 案例倒排索引

文章目录 MapReduce 案例倒排索引一、案例分析1、倒排索引介绍2、案例需求及分析 二、MapReduce倒排索引编程实现1、准备数据文件(1) 在虚拟机上创建文本文件(2) 上传到HDFS指定文件 2、map阶段实现(1) 创建倒排索引映射器类 3、Combine阶段实现4、Reduce阶段实现5、Driver主类实现6、运行倒排索引驱动器类,查看结果 MapReduce 案例倒排索引 一、案例分析 1、倒排索引介绍 倒排索引是文档检索系统中最常用的数据结构,被广泛应用于全文搜索引擎。倒排索引主要用来存储某个单词(或词组)在一组文档中的存储位置的映射,提供了可以根据内容来查找文档的方式,而不是根据文档来确定内容,因此称为倒排索引(Inverted Index)。带有倒排索引的文件我们称为倒排索引文件,简称倒排文件(Inverted File)。 2、案例需求及分析 现假设有三个源文件file1.txt、file2.txt和file3.txt,需要使用倒排索引的方式对这三个源文件内容实现倒排索引,并将最后的倒排索引文件输出。 首先,使用默认的TextInputFormat类对每个输入文件进行处理,得到文本中每行的偏移量及其内容。Map过程首先分析输入的<key,value>键值对,经过处理可以得到倒排索引中需要的三个信息:单词、文档名称和词频。 经过Map阶段数据转换后,同一个文档中相同的单词会出现多个的情况,而单纯依靠后续Reduce阶段无法同时完成词频统计和生成文档列表,所以必须增加一个Combine阶段,先完成每一个文档的词频统计。 经过上述两个阶段的处理后,Reduce阶段只需将所有文件中相同key值的value值进行统计,并组合成倒排索引文件所需的格式即可。 二、MapReduce倒排索引编程实现 1、准备数据文件 启动hadoop服务,输入命令:start-all.sh (1) 在虚拟机上创建文本文件 创建InvertedIndex目录,在里面创建三个文本文件 file1.txt、file2.txt、file3.txt (2) 上传到HDFS指定文件 创建/InvertedIndex/input目录,执行命令:hdfs dfs -mkdir -p /InvertedIndex/input 2、map阶段实现 首先,使用IntelliJ开发工具创建Maven项目InvertedIndex,并且新创建hsl.aex.mr包,在该路径下编写自定义Mapper类InvertedIndexMapper,主要用于将文本中的单词按照空格进行切割,并以冒号拼接,“单词:文档名称”作为key,单词次数作为value,都以文本方式输出至Combine阶段。 (1) 创建倒排索引映射器类 创建hsl.aex.mr包,在包里创建InvertedIndexMapper类 package hsl.aex.mr; import org.apache.commons.lang3.StringUtils; import org.apache.hadoop.io.LongWritable; import org.apache.hadoop.io.Text; import org.apache.hadoop.mapreduce.Mapper; import org.apache.hadoop.mapreduce.lib.input.FileSplit; import java.io.IOException; public class InvertedIndexMapper extends Mapper<LongWritable,Text,Text,Text>{ private static Text keyInfo = new Text(); // 存储单词和URL组合 private static final Text valueInfo = new Text("

MapReduce 工作原理

文章目录 MapReduce 工作原理一、MapReduce工作过程二、MapTask工作原理三、Reduce Task工作原理四、Shuffle工作原理五、MapReduce编程组件1、inputFormat组件2、Mapper组件3、Reducer组件4、Partitioner组件5、Combiner组件6、OutputFormat组件 六、MapReduce运行模式1、本地运行模式2、集群运行模式 七、MapReduce性能优化策略1、数据输入2、Map阶段3、Reduce阶段4、Shuffle阶段5、其它调优属性 MapReduce 工作原理 一、MapReduce工作过程 分片、格式化数据源⟹ Longrightarrow⟹执行MapTask⟹ Longrightarrow⟹执行Shuffle过程⟹ Longrightarrow⟹执行ReduceTask过程⟹Longrightarrow⟹写入文件 二、MapTask工作原理 MapTask作为MapReduce工作流程前半部分,它主要经历5个阶段,分别是Read阶段、Map阶段、Collect阶段、Spill阶段和Combiner阶段。 三、Reduce Task工作原理 ReduceTask的工作过程主要经历了5个阶段,分别是Copy阶段、Merge阶段、Sort阶段、Reduce阶段和Write阶段。 四、Shuffle工作原理 Shuffle是MapReduce的核心,它用来确保每个reducer的输入都是按键排序的。它的性能高低直接决定了整个MapReduce程序的性能高低,map和reduce阶段都涉及到了shuffle机制。 五、MapReduce编程组件 1、inputFormat组件 主要用于描述输入数据的格式,它提供两个功能,分别是数据切分和为Mapper提供输入数据。定义如何读取和分割输入数据。InputFormat是一个类,定义了InputSplit用于把输入数据拆分到任务,并提供RecordReader对象工厂用于读取文件。InputFormat由作业的驱动器直接调用,基于InputSplit来确定map任务执行的数量和位置。 2、Mapper组件 Hadoop提供的Mapper类是实现Map任务的一个抽象基类,该基类提供了一个map()方法。mapper执行MapReduce程序第一阶段的用户自定义工作。从实现角度来看,mapper实现以一系列键值对(k1,v1)的形式接收输入数据,这些数据会用于单个map执行。map通常将输入对转换成输出对(k2,v2),后者会被用作洗牌和排序的输入。对于构成总的作业输入的每个map任务而言,mapper的新实例均运行在独立的JVM实例中。这是特意设计,即不为单独的mapper提供以任何方式与其它mapper进行通信的机制。这使得每个map任务的可靠性仅取决于本地机器的可靠性。 3、Reducer组件 Map过程输出的键值对,将由Reducer组件进行合并处理,最终的某种形式的结果输出。reducer负责执行第二阶段作业特定工作的用户提供代码。对于分配给特定reducer的每一个键,reducer的reduce()方法仅被调用一次。该方法接收一个键,以及一个与键关联的所有值的迭代器。迭代器以未定义的顺序返回与键相关的值。典型地,reducer将输入的键值对转换成输出对(k3,v3)。 4、Partitioner组件 Partitioner组件可以让Map对Key进行分区,从而可以根据不同的key分发到不同的Reduce中去处理,其目的就是将key均匀分布在ReduceTask上。由每个单独mapper产生的中间键空间(k2,v2)的子集会被分配给每个reducer。这些子集(或分区)是reduce任务的输入。每个map任务可能会向任何分区派发键值对。相同键的所有值总要在一起进行reduce,无论它们来自哪个mapper。其结果是,所有map节点必须达成一致,确定由哪个reducer来处理不同的中间数据片段。Partitioner类确定了一个给定的键值对要去向哪一个reducer。默认的Partitioner为每个键计算散列值,并基于这个结果来分配分区 默认的分区是HashPartitioner 5、Combiner组件 Combiner组件的作用就是对Map阶段的输出的重复数据先做一次合并计算,然后把新的(key,value)作为Reduce阶段的输入。一个可选的处理步骤,用于优化MapReduce作业执行。如果存在的话,组合器在mapper之后、reducer之前运行。一个Combiner类的实例在每个map任务和部分reduce任务中运行。组合器接收mapper实例派发的所有数据作为输入,并尝试着组合有着相同键的值,从而缩小键空间,同时减少了需要排序的键(不必要的数据)的数量。接下来,组合器的输出会被排序并发送到reducer。 6、OutputFormat组件 OutputFormat是一个用于描述MapReduce程序输出格式和规范的抽象类。OutputFormat管理作业输出(作业输出由reducer生成,如果reducer不存在,则由mapper生成)的写方式。OutputFormat的职责是定义输出数据的位置以及用于保存结果数据的RecordWriter 六、MapReduce运行模式 1、本地运行模式 在当前的开发环境模拟MapReduce执行环境,处理的数据及输出结果在本地操作系统 2、集群运行模式 把MapReduce程序打成一个Jar包,提交至Yarn集群上去运行任务。由于Yarn集群负责资源管理和任务调度,程序会被框架分发到集群中的节点上并发的执行,因此处理的数据和输出结果都在HDFS文件系统中。 七、MapReduce性能优化策略 使用Hadoop进行大数据运算,当数据量极其大时,那么对MapReduce性能的调优重要性不言而喻,尤其是Shuffle过程中的参数配置对作业的总执行时间影响特别大,我们可以从五个方面对MapReduce程序进行性能调优,分别是数据输入、Map阶段、Reduce阶段、Shuffle阶段和其他调优属性方面。 1、数据输入 在执行MapReduce任务前,将小文件进行合并,大量小文件会产生大量的map任务,增大map任务装载次数,而任务装载较耗时,从而导致MapReduce运行速度较慢。因此采用CombineTextInputFormat来作为输入,解决输入端大量的小文件场景。 2、Map阶段 减少溢写(spill)次数 减少合并(merge)次数 在map之后,不影响业务逻辑前提下,先进行combine处理,减少 I/O 3、Reduce阶段 合理设置map和reduce数 设置map、reduce共存 规避使用reduce 合理设置reduce端的buffer 4、Shuffle阶段 Shuffle阶段的调优就是给Shuffle过程尽量多地提供内存空间,以防止出现内存溢出现象,可以由参数mapred.child.java.opts来设置,任务节点上的内存大小应尽量大。 5、其它调优属性 MapReduce还有一些基本的资源属性的配置,这些配置的相关参数都位于mapred-default.xml文件中,我们可以合理配置这些属性提高MapReduce性能,例如合理设置MapTask、ReduceTask等参数。

RocketMQ(五)producer发送消息的总体流程

之前已经对producer的启动流程进行了大致的梳理,现在梳理一下producer发送消息的一个过程。包括生产者重试机制、生产者故障转移机制、VIP通道等内容都会进行梳理。 Producer通过调用send方法发送消息,实际上RocketMQ的producer发送消息的模式可以氛围三种: 1. 单向发送:把消息发向Broker服务器,而不用管消息是否成功发送到Broker服务器,只管发送,不管结果。 2. 同步发送:把消息发送给Broker服务器,如果消息发送成功给Broker服务器,能得到Broker服务器的响应结果。因为是同步发送,等待的过程会被阻塞。 3. 异步发送:把消息发送给Broker服务器,如果消息成功发送给Broker服务器,能得到Broker服务器的响应结果。因为是异步发送,发送完消息后,不用等待,等到服务器的响应调用回调。 1 Producer发送消息的源码入口 send函数 DefaultMQProducer#send方法作为源码分析的入口方法,该方法被使用者直接调用。其内部调用defaultMQProducerImpl#send方法发送消息。 1.1 同步消息 /** * 消息发送的入口,该方法被使用者直接调用,其内部调用defaultMQProducerImpl#send方法发送消息。 * @param msg * @return * @throws MQClientException * @throws RemotingException * @throws MQBrokerException * @throws InterruptedException */ @Override public SendResult send( Message msg) throws MQClientException, RemotingException, MQBrokerException, InterruptedException { //根据namespace设置topic msg.setTopic(withNamespace(msg.getTopic())); //调用defaultMQProducerImpl#send发送消息 return this.defaultMQProducerImpl.send(msg); } 该方法内部调用defaultMQProducerImpl#send发送消息。 /** * DEFAULT SYNC ------------------------------------------------------- */ public SendResult send( Message msg) throws MQClientException, RemotingException, MQBrokerException, InterruptedException { //调用另一个send方法,设置超时时间参数,默认3000ms return send(msg, this.

利用2阶分数阶微分掩模的边缘检测(Matlab代码实现)

👨‍🎓个人主页:研学社的博客 💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭:行百里者,半于九十。 📋📋📋本文目录如下:🎁🎁🎁 目录 💥1 概述 📚2 运行结果 🌈3 Matlab代码实现 🎉4 参考文献 💥1 概述 边缘检测是图像处理的一个重要环节,也是进行信息提取与模式识别的一个基本手段。传统的边缘检测算子多为微分算子,主要包括一阶与二阶微分算子。 常用的一阶微分算子主要有 Rebort 算子、 Sobel 算子、Prewitt算子和 Canny 算子等,而常用的二阶微分算子则有 Laplician 算子和 LOG 算子等。 近年来,随着分数阶微积分理论在图像处理领域中的成功应用[2-5] ,利用分数阶微分进行边缘检测逐渐成为一个研究热点。Mathieu 等人 [6] 提出了分数阶鲁棒轮廓边缘检测器,适当选择分数阶微分的阶数时,该检测器不仅能选择性地检测出边缘;杨柱中等人[7] 构造了一种基于 0~1 阶分数阶微分的 Tiansi 掩模模板,相对于传统的微分算子,该模板在有效提取图像边缘的同时具有较 高的信噪比;王卫星等人 [8] 根据 Tiansi 掩模模板的特点,提出了一种改进的 Tiansi 算子,该算子在进行边缘检测时可大幅增强图像的纹理细节边缘信息值;Pu 等人 [9] 和 Gao 等人 [10] 分别利用分数阶微分替换传统一阶微分,构造了两种不同的分数阶边缘检测算子;汪成亮等人[11] 针 对 Tiansi 模板的最佳分数阶阶数需要人为指定这一缺陷,提出了一种基于图像纹理复杂度的自适应分数阶微分算法;何春等人[12] 首先利用分数阶微分和分数阶积分组成复合导数,然后在此基础上提出了一种基于复合导数的边缘检测算子;蒋伟等人[13] 基于 0~1 阶分数阶微分理论和传统的 Sobel 算子,提出了一种分数阶 Sobel 算子的边缘检测模型。 📚2 运行结果 部分代码:b=filter2(op,a); %设置过零检测的门限 %寻找滤波后的过零点,+-和-+表示水平方向从左到右和从右到左过零

[附源码]计算机毕业设计的校园报修平台Springboot程序

项目运行 环境配置: Jdk1.8 + Tomcat7.0 + Mysql + HBuilderX(Webstorm也行)+ Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。 项目技术: Springboot + mybatis + Maven+Vue等等组成,B/S模式 + Maven管理等等。 环境需要 1.运行环境:最好是java jdk 1.8,我们在这个平台上运行的。其他版本理论上也可以。 2.IDE环境:IDEA,Eclipse,Myeclipse都可以。推荐IDEA; 3.tomcat环境:Tomcat 7.x,8.x,9.x版本均可 4.硬件环境:windows 7/8/10 1G内存以上;或者 Mac OS; 5.是否Maven项目: 否;查看源码目录中是否包含pom.xml;若包含,则为maven项目,否则为非maven项目 6.数据库:MySql 5.7/8.0等版本均可; 毕设帮助,指导,本源码分享,调试部署(见文末) 3.3系统功能分析 考虑到实际生活中在校园报修方面的需要以及对该系统认真的分析,将系统权限按管理员,维修员和用户这三类涉及用户划分。 (a) 管理员;管理员使用本系统涉到的功能主要有:首页、个人中心、用户管理、维修员管理、楼栋管理、房间管理、公告信息管理、报修信息管理、处理结果管理、我要反馈管理等功能。管理员用例图如图3-1所示。 图3-1管理员用例图 (b)维修员;维修员使用本系统涉到的功能主要有:首页、个人中心、楼栋管理、房间管理、公告信息管理、报修信息管理、处理结果管理等功能。维修员用例图如图3-2所示。 图3-2维修员用例图 (c)用户主要包括首页、个人中心、楼栋管理、房间管理、公告信息管理、报修信息管理、处理结果管理、我要反馈管理等功能。用户用例图如图3-3所示。 图3-3用户用例图 3.4系统流程的分析 由于不同的系统实际使用用户角色的不同,他们的业务分析也会变得有所不一样,为了论述方便接下来都将以用户功能权限下的系统业务流程来分析,如下图所展示: 3.4.1 用户管理的流程 图3-4用户管理流程 3.4.2个人中心管理流程 图3-5个人中心管理流程 3.4.3登录流程 图3-6登录流程 4.1软件功能模块设计 系统整体功能如下图所示: 图4-1系统总体功能模块图 4.2 数据库设计 4.2.1 概念模型设计 概念模型是对现实中的问题出现的事物的进行描述,ER图是由实体及其关系构成的图,通过E-R图可以清楚地描述系统涉及到的实体之间的相互关系。 楼栋管理实体图如图4-2所示: 图4-2楼栋管理实体图 房间管理实体图如图4-3所示: 图4-3房间管理实体图 报修信息管理实体图如图4-4所示: 图4-4报修信息管理实体图 系统登录,用户进入系统前在登录页面根据要求填写用户名和密码,选择角色等信息,点击登录进行登录操作,如图5-1所示。

QPSK调制解调仿真matlab

QPSK是MPSK的一种,对于理解MPSK有着很大的帮助。 在理解MPSK中,有以下几个难点: 什么是串并转换如何把QPSK转换成两路2PSK信号解调时如何判决 下面给出我结合全网与自己的理解的QPSK调制解调的代码 此代码仿真了QPSK的调制解调过程 clear; clc; N = 20; %比特数 T = 1; %比特周期 fc = 2; %载波频率 Fs = 100; %抽样频率 bitstream = randi([0,1], 1, N); %随机产生的比特数0、1 bitstream = 2*bitstream-1; %单极性变为双极性(0到-1;1到1) I=[]; Q=[]; for i=1:N if mod(i, 2)~=0 I = [I, bitstream(i)]; else Q = [Q, bitstream(i)]; end end %% 绘图比较I、Q比特流 bit_data=[]; for i=1:N bit_data = [bit_data, bitstream(i)*ones(1, T*Fs)]; end I_data=[]; Q_data=[]; for i=1:N/2 I_data = [I_data, I(i)*ones(1, T*Fs*2)]; Q_data = [Q_data, Q(i)*ones(1, T*Fs*2)]; end figure(); t = 0:(1/Fs):(N*T-1/Fs); subplot(3, 1, 1) plot(t, bit_data); legend('Bitstream比特信息') %比特信息 subplot(3, 1, 2) plot(t,I_data); legend('I BitstreamI路信息') %I路信息 subplot(3, 1, 3) plot(t, Q_data); legend('Q BitstreamQ路信息') %Q路信息 %% 载波信号 bit_t = 0:(1/Fs):(2*T-1/Fs); %载波周期为2倍比特周期,定义时间轴 I_carrier = []; Q_carrier = []; for i = 1:N/2 I_carrier = [I_carrier, I(i)*cos(2*pi*fc*bit_t)]; %I路载波信号 Q_carrier = [Q_carrier, Q(i)*cos(2*pi*fc*bit_t+pi/2)]; %Q路载波信号 end QPSK_signal = I_carrier + Q_carrier; figure(); subplot(3, 1, 1) plot(t, I_carrier); legend('I signal') %I路信号 subplot(3, 1, 2) plot(t, Q_carrier); legend('Q signal') %Q路信号 subplot(3, 1, 3) plot(t, QPSK_signal); legend('QPSK signal') %I路、Q路和的信号 %% 通过信道传输 snr = 1; QPSK_receive = awgn(QPSK_signal, snr); %% 解调 I_recover = zeros(1, N/2); Q_recover = zeros(1, N/2); for i = 1:N/2 idx = (i-1)*length(bit_t) + 1:i*length(bit_t); %I路 I_output = QPSK_receive(1, idx).