0x00
这一节比较简单,主要分析全局变量,全局静态变量,静态局部变量的实现。
0x01
我们直接看代码。
#include "com_example_ndkreverse2_Lesson2.h" #include <android/log.h> #define LOG_TAG "lesson2" #define ALOGD(...) ((void)__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)) static int a = 15; JNIEXPORT void JNICALL Java_com_example_ndkreverse2_Lesson2_main (JNIEnv * env, jobject jobject) { static int b = 16; a = 2; b = 1; ALOGD("a=%d\n, b=%d\n", a, b); } 这个函数的汇编实现,我们打开ida打开对应的so查看:
.text:00000D2C EXPORT Java_com_example_ndkreverse2_Lesson2_main .text:00000D2C Java_com_example_ndkreverse2_Lesson2_main .text:00000D2C .text:00000D2C var_10 = -0x10 .text:00000D2C .text:00000D2C PUSH {R0-R2,LR} .text:00000D2E MOVS R3, #2 .text:00000D30 MOVS R1, #1 .
1.顺序查找:
从表的一端开始,顺序扫描线性表,依次将扫描到的节点关键字和给定值k相比较。
等概率条件下...平均查找长度:ASL = (n+....+2+1)/n= (n+1)/2。
2.二分法查找:
前提是线性表是有序表。假设数据是按升序排序的,对于给定值x,从序列的中间位置开始比较,如果当前位置值等于x,则查找成功;若x小于当前位置值,则在数列的前半段中查找;若x大于当前位置值则在数列的后半段中继续查找,直到找到为止。
在等概率条件下...平均查找长度:ASL =(1/n)* ( j * 2^(j-1) )(j是从1到h),ASL = log2(n+1)-1。
原因:用二叉树来描述,树的高度d与节点树的关系为:n=(1+2+4+...... 2^(d-1))=2^d - 1;所以d = log2(n+1),每一层只需要比较一次,所以最多需要比较log2(n+1)次。
3.分块查找:
又称索引顺序查找,由分块有序(每一块中的关键字不一定有序,但是前一块中的最大关键字必须小于后一块中的最小关键字,即分块有序。)的索引表和线性表组成。例如把r【1....n】分为 b 块,则前 b-1 块节点数为 s = 【n/b】,最后一块允许小于或等于s。索引表是一个递增有序表。
平均查找长度分为两部分,索引表的查找+块内的查找。(索引表能够用二分法和顺序查找,块内无序,所以只能用顺序查找)
如果以二分查找来确定块,则 ASL = log2(b+1)-1 + (s+1)/2。
如果以顺序查找来确定块,则 ASL = (b+1)/2 + (s+1)/2。
如果以哈希查找来确定块,则ASL=1 + (s+1)/2。
一.GC如何判断一个对象为”垃圾”的 java堆内存中存放着几乎所有的对象实例,垃圾收集器在对堆进行回收前,第一件事情就是要确定这些对象之中哪些还“存活”着,哪些已经“死去”。那么GC具体通过什么手段来判断一个对象已经”死去”的?
1.引用计数算法(已被淘汰的算法) 给对象中添加一个引用计数器,每当有一个地方引用它时,计数器值就加1;当引用失效时,计数器值就减1;任何时刻计数器为0的对象就是不可能再被使用的。
目前主流的java虚拟机都摒弃掉了这种算法,最主要的原因是它很难解决对象 之间相互循环引用的问题。尽管该算法执行效率很高。
2.可达性分析算法 目前主流的编程语言(java,C#等)的主流实现中,都是称通过可达性分析(Reachability Analysis)来判定对象是否存活的。这个算法的基本思路就是通过一系列的称为“GC Roots”的对象作为起始点,从这些节点开始向下搜索,搜索所走过的路径称为引用链(Reference Chain),当一个对象到GC Roots没有任何引用链相连(用图论的话来说,就是从GC Roots到这个对象不可达)时,则证明此对象是不可用的。如下图所示,对象object 5、object 6、object 7虽然互相有关联,但是它们到GC Roots是不可达的,所以它们将会被判定为是可回收的对象。
在Java语言中,可作为GC Roots的对象包括下面几种:
虚拟机栈(栈帧中的本地变量表)中引用的对象。方法区中类静态属性引用的对象。方法区中常量引用的对象。本地方法栈中JNI(即一般说的Native方法)引用的对象。 二.被GC判断为”垃圾”的对象一定会回收吗 即使在可达性分析算法中不可达的对象,也并非是“非死不可”的,这时候它们暂时处于“缓刑”阶段,要真正宣告一个对象死亡,至少要经历两次标记过程:如果对象在进行可达性分析后发现没有与GC Roots相连接的引用链,那它将会被第一次标记并且进行一次筛选,筛选的条件是此对象是否有必要执行finalize()方法。当对象没有覆盖finalize()方法,或者finalize()方法已经被虚拟机调用过,虚拟机将这两种情况都视为“没有必要执行”。(即意味着直接回收)
如果这个对象被判定为有必要执行finalize()方法,那么这个对象将会放置在一个叫做F-Queue的队列之中,并在稍后由一个由虚拟机自动建立的、低优先级的Finalizer线程去执行它。这里所谓的“执行”是指虚拟机会触发这个方法,但并不承诺会等待它运行结束,这样做的原因是,如果一个对象在finalize()方法中执行缓慢,或者发生了死循环(更极端的情况),将很可能会导致F-Queue队列中其他对象永久处于等待,甚至导致整个内存回收系统崩溃。
finalize()方法是对象逃脱死亡命运的最后一次机会,稍后GC将对F-Queue中的对象进行第二次小规模的标记,如果对象要在finalize()中成功拯救自己——只要重新与引用链上的任何一个对象建立关联即可,譬如把自己(this关键字)赋值给某个类变量或者对象的成员变量,那在第二次标记时它将被移除出“即将回收”的集合;如果对象这时候还没有逃脱,那基本上它就真的被回收了。
代码示例:
public class FinalizeEscapeGC { public static FinalizeEscapeGC SAVE_HOOK = null; public void isAlive() { System.out.println("yes,i am still alive:)"); } @Override protected void finalize() throws Throwable { super.finalize(); System.out.println("finalize mehtod executed!"); FinalizeEscapeGC.SAVE_HOOK = this; } public static void main(String[] args) throws Throwable { SAVE_HOOK = new FinalizeEscapeGC(); // 对象第一次成功拯救自己 SAVE_HOOK = null; System.
包
包用于在逻辑上组合过程和函数,它由包规范和包体两部分组成。
1.我们可以使用create package命令来创建包:
实例:
create package sun_package is
procedure update_sal(name varchar2,newsal number);
function annual_income(name varchar2) return number;
end;
包的规范只包含了过程和函数的说明,但是没有过程和函数的实现代码。包体用于实现包规范中的过程和函数。
2.建立包体可以使用create package body命令
SQL> create or replace package body sun_package is
2 procedure update_sal(name varchar2,newsal number)
3 is
4 begin
5 update kkkk set sal=newsal where ename=name;
6 end;
7 function annual_income(name varchar2)
8 return number is
9 annual_salary number;
10 begin
11 select sal*12+nvl(comm,0) into annual_salary from emp where ename=name;
联系:用例图与类图都是一种半形式化的语言,相较于自然语言,它们更加严谨、易懂,便于沟通。
区别:用例图主要是面向用户描述系统功能,并指出各功能的操作者。主要用于需求分析时详细了解用户的需求,获得更全面、精准的用户需求;类图则是主要面向程序设计者的,用于项目的细分,便于程序员之间的交流,也能够有效地进行工作分配。
转载于:https://www.cnblogs.com/I-S-Y/p/5308895.html
今天编码发现了一个很奇怪的问题:每次请求都会产生一个新的sessionid,即每次请求都会产生新的session。
调试了半天也没找到什么原因,终于,终于,发现了问题:
原来请求的时候url多了个斜杠,即http://172.31.60.117:8088//mslogin/view/login.jsp;
注意这里的双斜杠 //,如果请求的url中多了斜杠,则每次请求会产生新的session,这样保存在session中的数据就无法拿到了。
去掉斜杠后终于正常了。
首先,确保自己的开发环境正确
1.JDK 1.7+Spring3.x+Tomcat
2.JDK 1.8+Spring4.x+Tomcat
不能用JDK 1.8去编译Spring 3.x的版本开发,不然你会发现WEB-INF下的classes是空的。没有编译后的字节码文件
不能用JDK 1.8去编译Spring 3.x的版本开发,不然你会发现WEB-INF下的classes是空的。没有编译后的字节码文件
不能用JDK 1.8去编译Spring 3.x的版本开发,不然你会发现WEB-INF下的classes是空的。没有编译后的字节码文件
Spring 框架下载地址
http://repo.spring.io/release/org/springframework/spring/
我写这篇博文的时候选择的是4.2.4版本
接下来说非注解的具体配置
一。首先是web.xml应用总入口的配置
web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5"> <display-name>TxHelperServer</display-name> <welcome-file-list> <welcome-file>index.html</welcome-file> <welcome-file>index.htm</welcome-file> <welcome-file>index.jsp</welcome-file> </welcome-file-list> <servlet> <servlet-name>springMVC</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:springmvc.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>springMVC</servlet-name> <url-pattern>*.action</url-pattern> </servlet-mapping> </web-app> Servlet是Java Web的核心,Spring MVC也不例外,Spring MVC里的前端控制器DispatcherServlet就是一个Servlet。 配置DispatcherServlet servlet-name可以自定义。我这里叫做springMVC
init-param的param-name可以通过查看源码的方式看到contextConfigLocation
param-value是Spring MVC配置文件的路径
我这里是在工程名下和src同级的新建了一个文件夹config,在config里新建了一个xml文件springmvc.xml
Spring MVC的主要配置会在springmvc.xml里
<load-on-startup>1</load-on-startup>
这个表示启动级别为1,当Tomcat启动时,应用也随之启动.
2.配置servlet-mapping
*.action表示所有以action结尾的URL请求都交给DispatcherServlet,虽然方便,但不利于实现RESTful
/ 表示全部请求都交由DispatcherServlet,此种配置可以实现RESTful,但会拦截静态资源文件,css/js/img。
三个简单实用的用于 DOM 操作的 jQuery 方法:
text() - 设置或返回所选元素的文本内容html() - 设置或返回所选元素的内容(包括 HTML 标记)val() - 设置或返回表单字段的值 单选按钮的选择跟获值:
<div class="input-input"> <label> <input name="identity" value="1" checked="checked" type="radio"> 个人投资者 </label> <label> <input name="identity" value="2" type="radio"> 机构投资者 </label> </div> var type = $("input[name='identity']:checked").val(); 这里的选值主要是value里面的值,例如1或则2
还有一些过后用到会加上去的
要玩大数据,没有数据怎么玩?这里推荐一些33款开源爬虫软件给大家。
爬虫,即网络爬虫,是一种自动获取网页内容的程序。是搜索引擎的重要组成部分,因此搜索引擎优化很大程度上就是针对爬虫而做出的优化。
网络爬虫是一个自动提取网页的程序,它为搜索引擎从万维网上下载网页,是搜索引擎的重要组成。传统爬虫从一个或若干初始网页的URL开始,获得初始网页上的URL,在抓取网页的过程中,不断从当前页面上抽取新的URL放入队列,直到满足系统的一定停止条件。聚焦爬虫的工作流程较为复杂,需要根据一定的网页分析算法过滤与主题无关的链接,保留有用的链接并将其放入等待抓取的URL队列。然后,它将根据一定的搜索策略从队列中选择下一步要抓取的网页URL,并重复上述过程,直到达到系统的某一条件时停止。另外,所有被爬虫抓取的网页将会被系统存贮,进行一定的分析、过滤,并建立索引,以便之后的查询和检索;对于聚焦爬虫来说,这一过程所得到的分析结果还可能对以后的抓取过程给出反馈和指导。
世界上已经成型的爬虫软件多达上百种,本文对较为知名及常见的开源爬虫软件进行梳理,按开发语言进行汇总。虽然搜索引擎也有爬虫,但本次我汇总的只是爬虫软件,而非大型、复杂的搜索引擎,因为很多兄弟只是想爬取数据,而非运营一个搜索引擎。
Java爬虫 1. Arachnid Arachnid是一个基于Java的web spider框架.它包含一个简单的HTML剖析器能够分析包含HTML内容的输入流.通过实现Arachnid的子类就能够开发一个简单的Web spiders并能够在Web站上的每个页面被解析之后增加几行代码调用。 Arachnid的下载包中包含两个spider应用程序例子用于演示如何使用该框架。
特点:微型爬虫框架,含有一个小型HTML解析器
许可证:GPL
2、crawlzilla crawlzilla 是一个帮你轻松建立搜索引擎的自由软件,有了它,你就不用依靠商业公司的搜索引擎,也不用再烦恼公司內部网站资料索引的问题。
由 nutch 专案为核心,并整合更多相关套件,并卡发设计安装与管理UI,让使用者更方便上手。
crawlzilla 除了爬取基本的 html 外,还能分析网页上的文件,如( doc、pdf、ppt、ooo、rss )等多种文件格式,让你的搜索引擎不只是网页搜索引擎,而是网站的完整资料索引库。
拥有中文分词能力,让你的搜索更精准。
crawlzilla的特色与目标,最主要就是提供使用者一个方便好用易安裝的搜索平台。
授权协议: Apache License 2
开发语言: Java JavaScript SHELL
操作系统: Linux
项目主页: https://github.com/shunfa/crawlzilla 下载地址: http://sourceforge.net/projects/crawlzilla/ 特点:安装简易,拥有中文分词功能
3、Ex-Crawler Ex-Crawler 是一个网页爬虫,采用 Java 开发,该项目分成两部分,一个是守护进程,另外一个是灵活可配置的 Web 爬虫。使用数据库存储网页信息。
授权协议: GPLv3 开发语言: Java 操作系统: 跨平台 特点:由守护进程执行,使用数据库存储网页信息
4、Heritrix Heritrix 是一个由 java 开发的、开源的网络爬虫,用户可以使用它来从网上抓取想要的资源。其最出色之处在于它良好的可扩展性,方便用户实现自己的抓取逻辑。
Heritrix采用的是模块化的设计,各个模块由一个控制器类(CrawlController类)来协调,控制器是整体的核心。
代码托管:https://github.com/internetarchive/heritrix3
授权协议: Apache 开发语言: Java 操作系统: 跨平台 特点:严格遵照robots文件的排除指示和META robots标签
众所周知,当用户登录网站后较长一段时间没有与服务器进行交互,将会导致服务器上的用户会话数据(即session)被销毁。此时,当用户再次操作网页时,如果服务器进行了session校验,那么浏览器将会提醒用户session超时,导致这个问题的关键词有两个:一个是「长时间」,一个是「未操作」。 防止session超时,我们一般采用的方式有两种:1、延迟session超时时间 2、(在规定的session超时时间内)隔一定时间与服务器交互。
一、 延长服务器的session超时时间。ps:在Tomcat服务器的WEB.xml有如下节点内容: <session-config><session-timeout>30</session-timeout></session-config>; 这里的30表示session的超时时间,单位为分钟,如果用户登录后在30分钟内没有与服务器交互,
那么当前用户的session将失效。我们可以配置一个更大的数值(比如60),
就可以延长session的超时时间,如果将该值改为0或负数的话,则表示session永不失效。
不过在实际的工作应用中,一味地上调session的超时时间设置并不怎么常见,
大多数需要实现该功能的网站都将解决问题的焦点集中在另一种思路上。
例如:一些在线网站均采用定时刷新页面的方法来防止session超时。
二、定时刷新页面。最常见的有两种实现方式:一种是通过JavaScript+HTMLDOM,另一种则是通过meta标签来实现。
1)JavaScript+HTMLDOM,示例代码如下:
function refresh(seconds) { setTimeout("self.location.reload()",seconds*1000); } refresh(600);//调用方法启动定时刷新,数值单位:秒。 2)通过meta标签来实现(在页面中添加meta标签refresh也可以指定每隔指定时间就刷新当前页面),示例代码如下: <metahttp-equiv="refresh"content="600"/> 上述meta标签可以实现每过600秒就刷新一次当前页面。
在上述两种方案中,较好的为第二种,因为如果当前页面是在IE浏览器的模式窗口中打开的,默认情况下,
self.location.reload()方法将会失效,而refreshmeta标签在IE模式窗口下仍然有效。
上述两种方式都实现了刷新当前页面,并且使用起来非常简单,不过很遗憾的是,它们存在一种几乎致命的缺陷。试想一下,如果在论坛发帖等需要用户输入内容的页面,用户花费较长的时间输 入了许多文本内容,可是突然遇到了一个定时页面刷新,结果用户输入的所有内容都没了,估计这个时候用户连掐死你的心都有了……
因此我们需要在当前页面本身不刷新、不影响用户的任何操作的情况下实现定时刷新。最常见的解决方法仍然有两种。
1、在当前页面添加一个隐藏的iframe,然后在该iframe里面实现定时刷新。
2、使用JavaScript Image对象来实现定时刷新,(服务器的响应可以是文字等非图片内容,非图片内容只会造成图像加载失败,而我们的图像标签本身就是隐藏的,不管是加载成功还是失败都不 会显示,毕竟我们的主要目的是发送请求给服务器,让服务器保持session处于活动状态。)
3、使用Ajax来实现定时刷新。
使用说明:
使用iframe标签实现定时刷新: 优点是:不需要编写JavaScript代码,可以在浏览器禁用JavaScript的情况下实现定时刷新; 缺点是:在某些不支持iframe标签的老式浏览器中没有效果,此外,iframe标签在浏览器中新增加了一个独立的页面,即使没有显示出来,不过其内部解析的window、document等对象仍然 存在,占用的浏览器内存相对较多。 使用Image对象: 优点是:与iframe相比,占用的内存相对较少,支持Image的浏览器也相对较多(现代浏览器均支持); 缺点是:在浏览器禁用JavaScript的情况下就毫无用武之地了(这个现在几乎不存在,现在很少出现禁用js的情况)。 Ajax来实现定时刷新: 缺点是:因为有些老式浏览器的JavaScript无法实现Ajax,但是却可以使用Image对象。 此外,使用Ajax需要编写更多的代码来处理XMLHttpRequest等对象的活动。 转载于:https://www.cnblogs.com/blog7206/p/5073104.html
推荐一个博客:https://github.com/pbypby,主页上有: Popular repositories kcf_tracker2 c demo for kernelized correalation filtersstc_tracker2 c++ demo for Fast Tracking via Spatio-Temporal Context LearningBRISQUE1 c++ demo for Blind/Referenceless Image Spatial Quality Evaluatorwmil_tracker1 c++ demo for weighted multiple instances learningct_tracker0 c++ demo for compressive tracking =========================================分割线=========================================== ==================== 以下转自: http://blog.csdn.net/huixingshao/article/details/43667485=================== 0,Online Object Tracking: A Benchmark cvpr2013 综述 http://visual-tracking.net/#
http://cvlab.hanyang.ac.kr/tracker_benchmark_v10.html
1, VTD: Visual Tracking Decomposition cvpr2010 源码+测试视频
http://cv.snu.ac.kr/research/~vtd/ 2, CT: Real-time Compressive Tracking eccv2012 源码+测试视频
http://www4.comp.polyu.edu.hk/~cslzhang/CT/CT.htm 3, PROST - Parallel Robust Online Simple Tracking 测试视频
R语言使用 read.table 报错
Error:appears to contain embedded nulls
解决方法:
1)使用readLines
速度极慢
2)给read.table添加参数skipNul
test <- read.table("D:/part-r-00000") # Error in read.table("D:/part-r-00000") : 空白的文件开头 # In addition: Warning messages: # 1: In read.table("D:/part-r-00000") : # line 1 appears to contain embedded nulls # 2: In read.table("D:/part-r-00000") : # line 2 appears to contain embedded nulls # 3: In read.table("D:/part-r-00000") : # line 3 appears to contain embedded nulls # 4: In read.table("D:/part-r-00000") : # line 4 appears to contain embedded nulls # 5: In read.
本想分析一下触摸事件的分发响应机制,但是发现分发事件的方法在Activity、View以及ViewGroup中各自存在 ,如图1表所示
图一
这样的话又牵扯到了三者之间的关系,那索性先理清楚Activity与另外两者的关系 ,在去分析触摸事件比较好。
什么是Activity 、View 、 Window? Activity:是Android 四大组件之一, 是存放View对象的容器,也是我们界面的载体,可以用来展示一个界面。它有一个SetContentView()方法 ,可以将我们定义的布局设置到界面上。
View:就是一个个视图的对象,实现了KeyEvent.Callback和Drawable.Callback。
Window:是一个抽象类,是一个顶层的窗口,它的唯一实例是PhoneWindow它提供标准的用户界面策略,如背景、标题、区域,默认按键处理等。
分析下三者之间的关系吧 View包含很多,TextView 、Imageview 、Listview 、 Button..就是一个一个展示不同图形的对象。我们可以把view通过xml布局,或者通过new View(),然后通过addview方法或动态或静态添加到Activity的布局上。我们都知道我们定义了layout布局,通过SetContentView就可以设置到Activity上,而Activity中的SetContentView()方法,又调用了Window的SetContentView方法,也就是View通过Activity最终添加到了Window上面。
那我们今天就看一下这个方法到底如何把layout布局加载进去,到底加载到哪里去了?
/** * Set the activity content from a layout resource. The resource will be * inflated, adding all top-level views to the activity. * * @param layoutResID Resource ID to be inflated. * * @see #setContentView(android.view.View) * @see #setContentView(android.view.View, android.view.ViewGroup.LayoutParams) */ public void setContentView(@LayoutRes int layoutResID) { getWindow().
http://www.52rd.com/S_TXT/2015_10/TXT73145.HTM
摘要:第五代移动通信系统实现超高数据传输目标的核心技术是采用毫米波频段和高达500MHz-4GHz的超宽带信号调制,远远超过目前最新的4G和WLAN技术所使用的频率范围和调制带宽,给目前的5G研究和产品开发提出了很大的挑战,需要研发全新的器件、模块、基带、和射频微波系统,但是目前针对无线通信技术的标准以及验证和测试方法都是在6GHz以下的RF频段以及160MHz以内的调制带宽,缺乏成熟有效同时具备一流性能指标的毫米波和超宽带信号产生和信号分析手段。本文介绍专门为5G先进技术研究开发而设计的验证测试平台,基于是德科技SystemVue系统设计仿真软件,M8190A超宽带任意波发生器,E8267D微博矢量信号发生器,N9040B UXA宽带矢量信号分析仪或63G实时示波器,可以直接产生和分析高达4GHz带宽的5G物理层信号,如FBMC等。该系统提供一种渐变快速的超宽带硬件线性失真校正方法,使测量系统实现了目前业界最佳的矢量误差特性。该系统可用于协助5G物理层算法开发和验证、毫米波和超宽带器件和模块的设计和调试,5G信道建模和验证,初期的发射机和接收机测试也验证,也可用过国防和航空航天、电子战、雷达等超宽带信号产生与分析,具备良好的灵活性和可扩展性。
1、引言: 目前5G面临的技术研究和测试验证的挑战
无线通信的演进已经经历了4代,最早出现的是模拟通信,只能传输语音业务,2G以GSM为主,主要传输语音和低速的数据业务,3G包括WCDMA和TD-S等,初步实现了移动互联网操作,推动了智能手机的普及,4G LTE实现了高速无线接入和丰富的多媒体应用,而5G将给无线通信带来革命性的飞跃,5G的核心目标就是要实现超高速的数据传输,传输速率达到几个G甚至10G比特率,从而彻底解决现在移动通信的速率瓶颈。为了实现超高速数据传输的目标,5G需要采用全新的无线传输技术,由于频率资源和带宽问题,需要使用更高的频段,例如毫米波,调制带宽会从现在的几十M跨越到 500 M到3GHz,而且还会使用新的物理层技术包括调制编码和多址接入,所以针对5G关键技术的研究和验证是目前的主要任务。
目前针对5G的研究和测试验证主要面临3大挑战,首先是软件方面如何简便快捷地产生和分析5G格式信号,第2是硬件能否实现在毫米波频段, 500 M到3GHz超宽带信号的发射和接收,第3是需要全面的验证和测试能力,比如系统级验证和软件硬件甚至模块的验证和测试。
2、5G毫米波和超宽带信号验证测试平台
为了应对5G带来的挑战,帮助客户快速进入5G先进技术研究开发,是德科技已经构建了一套5G验证测试平台,基于是德科技SystemVue系统设计软件,M8190A超宽带任意波形发生器,E8267D微波矢量信号发生器,N9040B UXA超宽带信号分析仪以及90000系列高带宽示波器,可以直接产生和分析毫米波频段超过500M带宽的5G物理层信号,如FBMC等,进行系统级和软硬件模块的验证和测试。该平台提供一种简便快速的超宽带硬件线性失真校正方法,使测试系统实现了目前业界最佳5G发射信号质量。该平台可以用于协助5G物理层算法开发和验证,毫米波和超宽带器件和模块的设计和调试,5G信道建模和验证,初期的发射机和接收机测试和验证,应用非常广泛,具备良好的灵活性和可扩展性。
2.1 基于SystemVue的5G FBMC参考库
基于SystemVue的W1906BEL 5G 基带程序库能够为 5G 技术研究提供可立即使用的参考信号处理用户专利设计,借助这个基带程序库,基带物理层设计人员可以大幅节省时间提升工作效率,系统架构师、算法开发人员和基带硬件设计人员可以充分利用集成仿真环境,应用动态链路级场景研究、实现和验证通信物理层信号处理设计,也可以非常方便地重新设计参考发射机和接收机,以获得最佳性能,并于其他候选技术设计进行比较。W1906BEL 5G 基带程序库包括源代码、模型、子系统、仿真实例和基础组件,可以提供用于 5G 候选波形技术FBMC的数字信号处理模块,端到端物理层发射和接收仿真模型,频率和时间同步,信道估计和修正,生成参考波形以验证射频电路设计,系统级性能验证和 BER/FER 测试,以及连接是德科技硬件仪表构建实物仿真和测试平台的能力。
图1所示为FBMC与OFDM在实现上的区别。FBMC主要包括符号映射,子载波映射,OQAM处理,IFFT,滤波器组处理,并串行转换等过程,与OFDM比较主要区别就在于OQAM和滤波器组处理。
处理将QAM信号转换为Offset QAM,主要包含2个步骤,首先是将QAM符号从复数转为实部和虚部两个实数,并且采样率变成2倍,然后与序列相乘,m代表Sub-channel,n代表离散时间变量,OQAM处理是将QAM符号的实部或虚部做1/2符号周期的时间偏移,对于连续的Sub-channel,假定为m(偶数序号)和m+1(奇数序号),对Sub-channel m,QAM符号的实部做1/2符号周期的时间偏移,对Sub-channel m+1,QAM符号的虚部做1/2符号周期的时间偏移。OQAM处理的主要好处是可以降低信号的峰均比PAR。
上式为滤波器组输出S[m]表达式,其中也包含了OQAM处理的部分。
滤波器组的含义是指第1个滤波器为原型滤波器,其它滤波器是通过对原型滤波器进行频移得到的。原型滤波器的特性由混叠系数K决定,混叠系数K可以表述为滤波器的冲激响应时间与子载波符号周期T的比值,也是子载波符号在时域上混叠的数目,从图2中可以看到,K值越大,滤波器滚降越陡峭,但是混叠子载波旁瓣数量也越大,所以FBMC子载波之间存在干扰,不是正交的,而OFDM可以看作是K=1的情况
在FBMC的发射机模型中还插入了Preamble和Pilot信号,在接收机模型中基于Preamble和Pilot提供了时间和频率同步,信道估计和均衡修正,Pilot相位跟踪修正等功能,这样就可以实现与硬件仪表连接构建实际的发射机和接收机
2.2验证测试平台的结构和组成仪表介绍
图3所示的5G验证测试平台是将5G FBMC软件处理与毫米波和超宽带的硬件发射和接收能力结合在一起,从而为业界提供完整地验证5G系统级性能的能力,同时也可以将正在研发的5G软件或硬件与平台结合,或替代平台中的模块,进行验证和测试
SystemVue和前面介绍的W1906BEL程序库组成了软件处理的部分,硬件平台分成信号产生(发射机)和信号接收分析(接收机)。
发射机硬件由M8190A宽带任意波形发生器和E8267D PSG微波矢量信号源构成。M8190A是基于AXIe架构的模块化仪表,每个M8190A可以提供两个通道差分信号输出,每个通道具备8GHz采样率14bit量化或12GHz采样率12bit量化,5GHz模拟带宽,采样率可以灵活调整,并内置数字上变频DUC功能。为了实现毫米波频段信号产生,采用两通道IQ输出模式。M8190A输出的两路IQ差分信号送到E8267D PSG,调制到微波/毫米波的载波频率。E8267D PSG具备从250KHz到最高44GHz的频率范围,不仅具备内置的基带信号发生器,同时可以包含宽带IQ信号调制器,标称宽带IQ调制带宽为2GHz,实际测试表明E8267D PSG输出的IQ调制带宽实际超出2GHz,因此M8190A与E8267D PSG的组合是目前业界唯一能完全满足5G关键技术要求的5G毫米波和超宽带信号发射平台。
接收机硬件可以选择N9040B UXA或90000系列高带宽示波器两种类型仪表,N9040B UXA是最新型信号分析仪,覆盖3Hz到26.5GHz频率范围,IQ解调分析带宽和实时频谱测量带宽都达到业界最高的510MHz,具备全带宽内14bit量化,IQ带宽内无失真动态范围超过75dBc,相噪指标也达到了业界最高的-136dBm/Hz(1GHz载波,20KHz偏移),是兼顾5G宽带信号接收测量和射频微波测量精度动态范围的最佳选择,90000系列高带宽示波器可以提供最高达63GHz的接收和分析带宽,可以满足更高带宽的需要。
3、5G平台实现的验证和测试
3.1 毫米波超宽带信号产生和线性失真校正
目前在这个5G毫米波和超宽带验证测试平台上已经构建了覆盖5G主要带宽要求的发射信号模型,包括基于FBMC调制的500MHz带宽,1GHz带宽,2GHz带宽,3GHz带宽和4GHz带宽信号,子载波调制方式包括QPSK,16QAM和64QAM,载波频率最高可达44GHz,如果使用外混频方式,还可以支持更高的毫米波频段,例如E Band。图4所示的例子是该验证测试平台产生的载波频率为20GHz,调制带宽为4GHz,调制方式为16QAM的FBMC信号,使用信号分析仪测量OBW占用带宽,测量得到的信号99%累积功率占用带宽约为3.9GHz。
但是也可以看到图4所示的4GHz调制带宽信号明显存在带内不平坦现象,主要是宽带IQ调制器存在的线性失真,会明显影响发射信号的矢量误差。为提高超宽带发射机的调制质量,该平台采用了一种简便直接的矢量校正方法,首先产生一个可以覆盖工作带宽的宽带调制信号,调制方式可以选择QPSK或16QAM,其中16QAM效果较好,然后采用矢量信号分析仪解调测量EVM,并通过均衡器计算并提取频率响应曲线的矢量值,然后再对基带信号进行预失真处理。典型的宽带16QAM信号解调和均衡器计算频率响应的曲线如下图5所示
经过宽带校正最终产生出来的信号如图6所示,可以看到除了子载波数字调制引起的峰均比外,整个带宽内信号分布比较平坦。
3.2 5G收发信机系统级吞吐率验证
验证测试平台的核心是通过软件和硬件构建了完整5G发射机和接收机,因此可以完成比较全面的5G验证和测试,既可以做系统级性能验证,算法验证,也可以测试发射机和接收机指标,还可以验证和调试5G元器件。系统级验证主要是通过误码率BER或吞吐率等指标来反映5G系统在各种参数条件和传播条件下的性能,下面是两种典型调制带宽和调制格式参数系统在AWGN信道条件下的验证结果,其中使用的指标是吞吐率,系统物理层理论的峰值吞吐率计算方法如下:
考虑误码率BER后的实际数据吞吐率计算方法如下:
第1个实例是在20GHz载波频率和500MHz调制带宽验证了系统级吞吐率,信号载波频率为20GHz,调制带宽为500MHz,调制方式为FBMC 64QAM,AWGN信道,信噪比从0-20dB变化,图7所示为系统级吞吐率Throughput与信噪比SNR的关系曲线,可以看到吞吐率Throughput约为1.06Gbps到1.63Gbps
第2个实例是在20GHz载波频率和4GHz调制带宽验证了系统级吞吐率,信号载波频率为20GHz,调制带宽为4GHz,调制方式为FBMC 16QAM,AWGN信道,信噪比从10-35dB变化,图8所示为系统级吞吐率Throughput与信噪比SNR的关系曲线,可以看到吞吐率Throughput约为7.4Gbps到9.3Gbps
结束语
我们已经通过5G验证测试平台实现了基于5G FBMC调制技术,使用毫米波频率,超过500M甚至高达4GHz的超宽带信号的发射和接收,实现了接近10G比特率的数据吞吐率。这套5G测试验证平台可以完全满足5G毫米波和超宽带技术要求。
是德科技是目前行业唯一提供5G全面解决方案,能够帮助客户应对5G测试和系统验证的挑战。是德科技在软件方面推出了业界第1个5G仿真库,支持FBMC和Massive MIMO,在硬件方面已经全面支持毫米波频段, 510 M以上的超宽带的信号发射和接收,同时提供系统级验证和测试能力,包括误码率,EVM和吞吐率等。
pom.xml解析 1.根元素 project 2.modelVersion 固定版本4.0.0 指定了当前pom的版本 3.坐标 <groupId>,<artifactId>,<version>,<packageing> groupId 反写的公司网址+项目名 artifactId 项目名+模块名 version 版本号 第一个0表示大版本号,第二个0表示大版本号,第三个0表示大版本号。如:0.0.1snapshot快照。 (snapshot 快照/alpha 内部测试/beta 公测/Release稳定/GA正式发布) packaging 打包方式 默认是jar 4. name :项目描述名 url:项目的地址 description:项目描述 developers:开发人员列表 licenses:许可证 organization:组织信息 5.dependency的 <optional>:设置依赖是否可选 <exclusions>:排除依赖传递列表(A->B->C,可排除C) 6.dependencyManagement管理,仅仅启到定义的作用,用于定义parent,子模块继承。 7.build-plugins 插件列表 8.parent 、 modules
续第三章:Learning Spark 第三章 RDD编程 已翻译整理完毕,PDF可下载
PS:今天去换药,一上午就没了,坑爹啊~~ 加油加油,第四章!!
第四章 处理键值对(Key/Value Pairs) 本章介绍如何处理键值对,这是Spark中常见的一种数据类型。键值对RDD通常用于聚合操作,也经常会将一些初始ETL(提取,转换,加载)获取的数据保存为键值对的格式。键值对的RDD也暴露了一些新的操作(比如每个产品的评价计数,按相同的键对数据进行分组,对两个不同的RDD分组)。
我们也会讨论一个键值对RDD的高级特征:分区(partitioning),使用户可以跨节点控制RDD的布局。通过可控的分区,应用程序有时可确保数据在同一个机器上,可以集中访问,就可以大量的减少通信的开销,以此获得显著的提速。我们会用一个PageRand算法的例子来阐述分区。选择正确的分区对于分布式系统来说就和本地程序选择正确的数据结构类似,这两者都说明数据的布局对性能的影响非常大。
动机
Spark为包含键值对的RDD提供了一些特殊的操作。这种RDD被称之为pair RDD。Pair RDD在许多程序中都是很有用的组件,因为它们对外的操作可以让你并行的处理每个键,或者跨网络重组数据。例如,Pair RDD有一个reduceByKey()的方法,它可以对每个键的数据分别进行聚合;join()方法可以通过对两个RDD中相同的元素进行分组合并。从RDD中抽取字段(例如事件的事件,客户ID或者其他标识)并用这些字段作为pair RDD的键进行处理是很常见的。
创建Pair RDD
Spark中有多种方式能得到pair RDD。在第五章中我们要探索的很多格式加载时都可以直接的返回其键值数据为pair RDD。另外,我们有一个普通RDD想要转换为pair RDD,可以通过map()操作来返回键值对。通过代码来看个例子,从一个包含文本行的RDD开始,用每一行的第一个单词作为key。
这种方式构造键值RDD会根据编程语言有些不同。在Python中,为了处理有key的数据,我们需要返回tuple组成的RDD(见示例4-1)。
示例4-1 Python中使用第一个单词做key来创建pair RDD
pairs = lines.map(lambda x: (x.split(" ")[0], x))
在Scala中,为了处理有key的数据,我们同样需要返回tuple(见示例4-2)。tuple类型的RDD存在隐式转换,可以提供附加的键值函数。
示例4-2 Scala中使用第一个单词做key来创建pair RDD
val pairs = lines.map(x => (x.split(" ")(0), x))
Java没有内置的tuple类型,所以Spark的Java API有一个用户创建的scala.Tuple2类。该类很简单:Java用户可以编写new Tuple2(elem1, elem2)来创建一个新tuple,然后用._1()和._2()方法来访问tuple中的元素。
Java用户在创建pair RDD时同样需要调用特殊版本的Spark函数。比如用mapToPair()替换基本函数map(),在43页的“JAVA”部分有更多讨论。不过可以看一个简单的示例4-3。
示例4-3 Java中使用第一个单词做key来创建pair RDD
PairFunction<String, String, String> keyData =
new PairFunction<String, String, String>() {
public Tuple2<String, String> call(String x) {
下载地址:Learning Spark - 第三章 RDD编程 第三章整理完成了,排版也还Ok,下面是截图,PDF的,加了书签。翻译的内容基本和原作的页码一致,方便对照。
更新,第三章完整版PDF可下载:Learning Spark 第三章 RDD编程 已翻译整理完毕,PDF可下载
续啊续,再续上一篇:Learning Spark - LIGHTNING-FAST DATA ANALYSIS 第三章 - (2)
常见的变换和动作
在本章中,我们巡视一遍Spark中最常见的变换和动作。对包含某种类型数据的RDD还有些另外的操作可用,比如RDD的数量的统计函数,对RDD的key/value对按照key进行聚合的key/value操作。在后面的章节中我们会讲到RDD类型之间的转换和其他操作。
基本RDD
我们先从对于不管是什么数据的RDD都适用的变换和动作说起。
元素级的变换
两个最常见的你可能用到的变换是map()和filter()(见图3-2)。map()变换传入一个函数,并将该函数应用到RDD中的每一个元素。函数的返回结果就是变换后的每个元素构成的新RDD。filter()变换也是传入一个函数,返回的是该RDD中仅能通过该函数的元素构成的新RDD。
图 3-2 从输入RDD中map和filter后的RDD
我们可以用map()做任何的事情,从我们的集合中取出网站关联的每个url到计算平方数。map()的返回类型不必和输入类型相同,这很有用。如果我们有一个String类型的RDD,通过map()将字符串解析后返回double,那么我们的输入类型就是RDD[String],而结果类型就是RDD[Double]。
让我们看一个map()的简单例子,计算RDD中所有数的平方(示例3-36到3-28)。
示例3-26:Python计算RDD中的平方值
nums = sc.parallelize([1, 2, 3, 4])
squared = nums.map(lambda x: x * x).collect()
for num in squared:
print "%i " % (num)
示例3-27:Scala计算RDD中的平方值
val input = sc.parallelize(List(1, 2, 3, 4))
val result = input.map(x => x * x)
println(result.collect().mkString(","))
示例3-28:Java计算RDD中的平方值
JavaRDD<Integer> rdd = sc.
在project中右击-------Team--------------synchronous with repository会弹出项目模块,看到的是红色的和蓝色的,红色的是项目有冲突,不要轻易修改,与出图人有探讨情况,发现是自己的问题可以进行选择进行 点击+选择红色的右击 override and update覆盖更新操作,其他的蓝色则依次进行覆盖更新操作, 为提交操作
maven检出项目步骤
1. eclipse中
先检出项目perference --show View --svn Repositories
进行删除 --file -import -maven-导入项目,此时会下载jar包,如果产生问题,可以找到problem一项进行删除