首页 文章 精选 留言 我的

精选列表

搜索[学习],共10000篇文章
优秀的个人博客,低调大师

IOS自动化测试之UIAutomation学习

一、软件安装 首先通过appstore下载安装Xcode开发工具,当前编写文档时最新版本为4.5.1 二、通过Xcode工具编写运行测试脚本 说明:如果是在IOS模拟器上运行测试用例,需要有被测试应用的源代码才有权限把应用安装到模拟器中,当前示例中使用了自己编写的一个简单Iphone应用,大家也可以直接在网上搜索一个开源的应用即可。 1、当你有了一个应用的源代码之后,在Xcode工具中,首先选中被测应用,然后点击菜单栏中的“Product-Profile”,则会弹出Instruments工具,在弹出的工具中选择IOS Simulator-》Automation,然后点击Profile 2、在弹出的Automation工具中选择需要测试的项目,同时在Add-》Create 添加测试脚本,点击Create后,在中间区域会出现编写测试脚本的区域,在中间添加以下脚本 //获取当前window对象 var target = UIATarget.localTarget(); var app = target.frontMostApp(); var window = app.mainWindow(); //打印除当前界面的控件数信息 target.logElementTree(); 具体的API参考官方文档:http://developer.apple.com/library/ios/#documentation/DeveloperTools/Reference/UIAutomationRef/_index.html 3、点击左上角的Record按钮则开始运行测试用例,运行完成后在工具的中间位置,原来编写代码的地方会出现运行结果的log日志,我们在刚才的代码中编写了target.logElementTree(),这句API会打印出当前页面的控件信息,可以在日志中看到树形结构的控件,点击可以查看控件的一些属性,这个API在编写代码的过程中也会比较有用。 另外如果想切换到编写代码的页面,可以点击图中红框处的进行切换。 注意:通过点击Record来运行测试用例时,代码执行完成后不会自动停止,所以需要手工的点击一下左上角的Stop按钮来停止运行。 4、录制回放功能 如果你是第一次编写自动测试脚本,可能很多API都不知道,这时候你可以先使用一下UIAutomation的录制回访功能,参考一下大概是怎么来编写测试用例的,当然你也会发现通过录制回访会有很多重复的代码,当你熟悉之后就可以不用录制回访来编写脚本了。 首先你切换到编写脚本的界面,这时候会看到中间的下方会有一个红色按钮,你点击一下就开始录制了,这时候会自动帮你在模拟器中启动起来被测应用,然后你在模拟器上继续点击操作的步骤都会被记录下来。 中间红色区域就是自动生成的代码,你可以点击代码中的箭头能看到不同的API,因为查找到一个元素可以使用不同的路径,对你属性了解API会有些帮助。 录制完成后点击红色按钮旁边的方块形停止按钮,录制就停止了,想要运行的话还是点击左上角的Record按钮就再次运行录制结果了。 三、编写测试用例进阶篇 通过上面你应该了解了大概怎么来使用UIAutomation工具以及编写简单的测试脚本,当时编写的也不算是一个测试用例,最起码的断言操作都没有,那么这一篇我们来将一下如何来编写一个真正的测试用例。 1、元素识别 如果要编写测试用例,我们首先想到要操作的控件元素应该如何去识别找到它呢,第二节我们简单说了一下通过脚本输出控件Log是一种方式可以识别到控件,还有另外一种方式是使用设备自带的Accessibility Inspector功能 在模拟器上,你还可以激活Accessibility 的检测器。启动模拟器,找到“Settings > General > Accessibility > Accessibility Inspector”,然后将它设为“打开”状态。 此时在模拟器上会出现一个覆层,你进入需要测试的应用,鼠标点击相应的控件,如下图所示会看到一些信息,Label就是这个控件的id属性,Traits就是这个控件的类型,Frame就是这个控件的位置以及大小{{36,295},{43,21}},其中第一个位置{36,295}是该控件的左上角的坐标,{43,21}则是这个控件的宽度和高度,通过这两个参数可以算出控件的具体坐标位置。 2、编写测试用例 var testName = "FirstTest"; UIALogger.logStart(testName); var target = UIATarget.localTarget(); var app = target.frontMostApp(); var window = app.mainWindow(); app.logElementTree(); window.tableViews()[0].cells()[0].tap(); target.delay(3); var date = window.elements()["date"]; UIALogger.logMessage( date ); if (date){ UIALogger.logPass( testName ); } else{ UIALogger.logFail( testName ); } 上面是使用了UIAutomation自带的一些API完成了一个自动测试用例的编写,包括了元素查找以及断言操作,但是如果你编写多个测试用例的话会发现一些问题,比如一些代码会有重复,用例组织不是很好,断言操作不方便。 3、tuneup介绍 下面为大家介绍一个开源的基于UIAutomation扩展的JS库tuneup,这个js扩展库是方便大家来编写测试用例。 Tuneup开源地址:https://github.com/alexvollmer/tuneup_js 如何来使用,首先你可以在电脑上新建一个测试用例目录,比如文件夹名称就叫Demo,下面可以新建一个lib子文件夹,存放需要用到的一个扩展库,你下载的tuneup目录内容可以都放到lib目录下,在demo文件夹下新建一个测试用例的js文件,测试代码中只需要把tuneup使用import引用进来就可以使用了,通过tuneup编写的测试用例如下。 #import "lib/tuneup/tuneup.js" var target = UIATarget.localTarget(); var app = target.frontMostApp(); /* Second是测试用例的注释,可以填写用例的用途,以及编写人等信息 */ test("Second", function(target, app) { var window = app.mainWindow(); app.logElementTree(); window.tableViews()[0].cells()[0].tap(); var date = window.elements()["date"]; assertNotNull(date,"进入日期详情页面,date属性没找到!"); }); 四、通过命令行运行测试用例 为了能够实现自动定时运行测试脚本,编写完成的测试用例我们希望是能够通过命令行的方式来启动运行的,那么下面我们介绍一下如何通过命令行来启动运行我们编写好的测试用例。 instruments -t /Applications/Xcode.app/Contents/Applications/Instruments.app/Contents/PlugIns/ AutomationInstrument.bundle/Contents/Resources/Automation.tracetemplate "/Users/ios/Library /Application Support/iPhone Simulator/6.0/Applications/D02EF837-94F7-457A-989A-A654FC034803 / DemoSBTableViewTest.app" -e UIASCRIPT /AutoTest/workspace/IosDemo/test.js -e UIARESULTSPATH /AutoTest/workspace/IosDemo/lib/ 上面是通过命令行来运行测试用例的脚本, -t 后面的参数为Automation.tracetemplate的路径,不用修改,Xcode4.5以后的版本路径都是这个,如果是Xcode4.5以前的路径会不一样 “/User***.app” 这个参数为被测程序的绝对路径,模拟器中安装的应用都可以在本地硬盘中找到 -e UIASCRIPT 指定执行的js脚本 -e UIARESULTSPATH 指定输出结果存放的路径 五、后续基于UIAutomation扩展需要的改进点 1、输出的用例运行结果存在给定的xml文件中, 后续需要解析xml文件,解析成testng的格式,方便后续和Jenkins等持续集成平台整合 2、查找定位元素,只能按照控件层级,一级一级往下找,使用起来有些不方便,需要再次封装一下 3、需要加入外围的一些控制,使整个自动化测试运行完全自动化,另外还需要加入一些失败重跑机制,UI的自动化一般都会存在一些不稳定的因素。 最新内容请见作者的GitHub页:http://qaseven.github.io/

优秀的个人博客,低调大师

阿里云对象存储服务OSS 学习笔记

阿里云对象存储服务(Object Storage Service,简称 OSS),是阿里云提供的海量、安全、低成本、高可靠的云存储服务 OSS服务先使用后付费 可以使用阿里云提供的API/SDK接口或者OSS迁移工具轻松地将海量数据移入或移出阿里云OSS。阿里云OSS服务的三种类型:1.标准类型(Standard):移动应用、大型网站、图片分享或热点音视频的主要存储方式2.低频访问类型(Infrequent Access):成本更低、存储期限更长3.归档类型(Archive):不经常访问数据的备份和归档 OSS具备的其他各项优势:方便、快捷的使用方式强大、灵活的安全机制丰富、强大的增值服务 OSS主要应用于以下场景1.图片和音视频等应用的海量存储OSS可用于图片、音视频、日志等海量文件的存储。各种终端设备、Web网站程序、移动应用可以直接向OSS写入或读取数据。OSS支持流式写入和文件写入两种方式,如下图所示:2.网页或者移动应用的静态和动态资源分离利用BGP带宽,OSS可以实现超低延时的数据直接下载。也可以配合阿里云CDN加速服务,为图片、音视频、移动应用的更新分发提供最佳体验3.云端数据处理上传文件到OSS后,可以配合媒体转码服务(MTS)和图片处理服务(IMG)进行云端的数据处理

优秀的个人博客,低调大师

Android网络连接处理学习笔记

在Android中,可以有多种方式来实现网络编程: 创建URL,并使用URLConnection/HttpURLConnection 使用HttpClient 使用WebView 创建URL,并使用URLConnection/HttpURLConnection java.net.*下面提供了访问 HTTP 服务的基本功能。使用这部分接口的基本操作主要包括: 创建 URL 以及 URLConnection / HttpURLConnection 对象 设置连接参数 连接到服务器 向服务器写数据 从服务器读取数据 源码: try { // 创建URL对象 URL url = new URL("http://t.sina.cn/fesky"); // 创建URL连接 URLConnection connection = url.openConnection(); // 对于 HTTP 连接可以直接转换成 HttpURLConnection, // 这样就可以使用一些 HTTP 连接特定的方法,如 setRequestMethod() 等 // HttpURLConnection connection // =(HttpURLConnection)url.openConnection(Proxy_yours); // 设置参数 connection.setConnectTimeout(10000); connection.addRequestProperty("User-Agent", "J2me/MIDP2.0"); // 连接服务器 connection.connect(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } 使用HttpClient 对于HttpClient类,可以使用HttpPost和HttpGet类以及HttpResponse来进行网络连接。 使用WebView Android手机中内置了一款高性能webkit内核浏览器,在SDK中封装成了WebView组件。 http://developer.android.com/guide/tutorials/views/hello-webview.html提供了一个简单的例子: 1. webview的XML定义: <WebView android:id="@+id/webview" android:layout_width="fill_parent" android:layout_height="fill_parent" /> 2.Manifest文件中权限的设定: <uses-permission android:name="android.permission.INTERNET" /> 3.如果想要支持JavaScript: webview.getSettings().setJavaScriptEnabled(true); 4.如果需要在WebView中显示网页,而不是在内置浏览器中浏览,则需要mWebView.setWebViewClient,并重写shouldOverrideUrlLoading方法。 5.如果不做任何处理,在显示你的Brower UI时,点击系统“Back”键,整个Browser会作为一个整体“Back"到其他Activity中,而不是希望的在Browser的历史页面中Back。如果希望实现在历史页面中Back,需要在当前Activity中处理Back事件:mWebView.goBack(); WebView webview; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); // 获取WebView对象 webview = (WebView) findViewById(R.id.webview); // 使能JavaScript webview.getSettings().setJavaScriptEnabled(true); // 如果需要在WebView中显示网页,而不是在内置浏览器中浏览, // 则需要mWebView.setWebViewClient,并重写 // shouldOverrideUrlLoading方法。 webview.setWebViewClient(new WebViewClientDemo()); // 加载网页 webview.loadUrl("http://t.sina.cn/fesky"); } @Override public boolean onKeyDown(int keyCode, KeyEvent event) { // 按下BACK键回到历史页面中 if ((keyCode == KeyEvent.KEYCODE_BACK) && webview.canGoBack()) { webview.goBack(); return true; } return super.onKeyDown(keyCode, event); } private class WebViewClientDemo extends WebViewClient { @Override // 在WebView中而不是默认浏览器中显示页面 public boolean shouldOverrideUrlLoading(WebView view, String url) { view.loadUrl(url); return true; } } 以上是采用loadUrl方法实现网页的加载,也可以采用loadData或者loadDataWithBaseURL方法实现网页的加载: webview.loadData(html, “text/html”, "utf-8”); 如果html中包含中文,则需要webview.loadData(URLEncoder.encode(html,encoding), mimeType, encoding); 对于本地图片或网页的显示,可以使用loadUrl,不过Url的地址前缀为file:///,如"file:///android_asset/test.htm”。 本文转自feisky博客园博客,原文链接:http://www.cnblogs.com/feisky/archive/2010/01/13/1646919.html,如需转载请自行联系原作者

优秀的个人博客,低调大师

iOS内存管理学习笔记一

1、引用计数 引用计数就是当前的对象被多少个其他对象所引用。这是我自己的理解。 MRC:手动引用计数,开发者自己来计算每一个对象被引用了多少次,自己进行内存的释放。 ARC:自动引用计数,编译器(xcode)来计算每一个对象的引用次数,对象由编译器来决定什么时候释放。 进一步说,所谓的ARC就是编译器帮我们在代码的合适位置插入了retain和release等MRC需要开发者手动写的关于对象引用计数的代码。 ARC环境: 1>xcode4.2或以上版本 2>LLVM3.0以上的编译器 3>编译器选项中设置ARC为有效 2、理解引用计数 举个简单的例子(可能不是那么贴切): 假如工作室里只有一盏灯,每个上班的员工上班时间都需要开灯,下班时间都需要关灯。假如有很多人上下班,最早上班的人A开了灯,A工作了八个小时下班了,把灯关掉,这样的话,没有下班的其他人都会处在一片黑暗之中。这样显然是不合理的,那么该如何解决呢? 解决这一问题是在办公室至少还有一人的状态下保持开灯,在最后一个人离开办公室的时候关灯。 我们来捋一下这个过程: 1>第一个进来的人需要照明,开灯 2>之后进来的人需要照明 3>下班离开办公室的人不需要照明 4>最后一个离开办公室的人不需要照明(此时已经无人需要照明),关灯 我们可以使用“引用计数”来判断办公室里是否还有人需要照明。过程如下: 1>第一个人进来了,需要照明,引用计数从0变为1,要开灯 2>第二个人进来了,需要照明,引用计数从1变为2 3>第一个人离开了,不需要照明,引用计数从2变为1 4>第二个人离开了,不需要照明,引用计数从1变为0,关灯 总结:只要引用计数=0,就是关灯状态,否则就是开灯状态。 在OC中,“对象”就是照明设备,那些使用该对象的“环境”就相当于需要照明的人。 开灯——生成对象(alloc,new,copy等) 需要照明——持有对象(retain等) 不需要照明——释放对象(release) 关灯——废弃对象(地址被回收,这个对象烟消云散了) 下面是个人理解的对象生命周期: Person是一个类 Person * xiaoming = [[Person alloc]init]; 这个时候再内存中开辟了一块内存空间,并初始化这个对象。引用计数从0变为1,相当于开灯。 image.png Person * xiaohong = xiaoming; 这时候引用计数要增加了。相当于又有人需要照明,引用计数 = 2. image.png 然后xiaohong在使用完这个对象之后就把对象释放了。现在引用计数-1,引用计数=1 [xiaohong release]; image.png xiaoming在使用完这个对象的时候也进行了释放。相当于不需要照明,引用计数-1,引用计数 = 0 . [xiaoming release]; image.png 这个时候,系统发现引用计数已经等于0了,这块空间需要释放回收了,回到最初的状态,于是变成下图的样子。 image.png 在这里简单说说内存泄漏的情形吧。 内存泄漏就是有些地址已经不使用了,但是依然有指针指向它导致这块地址空间不能释放。如下图所示: image.png 这是我自己的理解,如有不妥之处还请各位不吝赐教。如果您看到这篇文章,对您有一点点的帮助,将是我最开心的事!

优秀的个人博客,低调大师

Linux平台Swift语言开发学习环境搭建

1.序言 这两天一直忙,没来得及记录东西,周三12月4日凌晨1点多看到苹果正式开源了Swift,国外各大媒体资讯动作超级快。我也兴奋的起来看了一遍关于Swift开源的最新消息。众所周知,苹果平台的Swift语言已经出来了一年半了,一直在成长,经历了好几个版本。许多人盼望的swift开源是希望可以在除了苹果平台之外的平台可以运用这个新语言。比如有人希望将来可以用swift也可以撸一撸后台开发之类,理论上是没问题的,但是同样也有人会喷这么一个愿景,但是开源一出后,多多少少社区人员会去往这个方面去努力的。苹果官方为swift新搞了个网站swift.org,也放出来了Ubuntu Linux平台的预编译好的swift工具链的打包文件以及Linux下的编译指南。我今天写这么一博客的目的就是为了介绍和推广Swift语言在初学者或者低年级大学生群体中的运用。 2.Swift+Ubuntu环境配置 首先假定我们已经安装好Ubuntu Linux操作系统了,这个系统安装很简单,网上很多的步骤教程,虚拟机的话推荐用VirtualBox。Swift支持Ubuntu 14.04和15.10两个发型版,我这选择15.10版本的包。 第一步:下载 Swift 2.2 工具链压缩包,打开终端,输入命令新建目录并下载 diveinedu@diveinedu-VirtualBox:~$ mkdir swift && cd swift; diveinedu@diveinedu-VirtualBox:~/swift$ wget https://swift.org/builds/ubuntu1510/swift-2.2-SNAPSHOT-2015-12-01-b/swift-2.2-SNAPSHOT-2015-12-01-b-ubuntu15.10.tar.gz 第二步:用tar命令解压 Swift 2.2 工具链压缩包到当前目录,并配置环境变量 先解压,再进入目录,目录下会有usr/bin和usr/lib等等子目录: diveinedu@diveinedu-VirtualBox:~/swift$ tar xvf swift-2.2-SNAPSHOT-2015-12-01-b-ubuntu15.10.tar.gz diveinedu@diveinedu-VirtualBox:~/swift$ cd swift-2.2-SNAPSHOT-2015-12-01-b-ubuntu15.10/ 然后配置用户级别的环境变量,编辑$HOME/.bashrc配置文件 diveinedu@diveinedu-VirtualBox:~/swift/swift-2.2-SNAPSHOT-2015-12-01-b-ubuntu15.10$ gedit $HOME/.bashrc 上面命令会调出图形界面文本编辑器GEdit来编辑这个配置文件,在文件的最后输入如下配置行并保存退出编辑器 export SWIFT_HOME=$HOME/swift/swift-2.2-SNAPSHOT-2015-12-01-b-ubuntu15.10 export PATH=$SWIFT_HOME/usr/bin:$PATH export LD_LIBRARY_PATH=$SWIFT_HOME/usr/lib:$LD_LIBRARY_PATH export LIBRARY_PATH=$SWIFT_HOME/usr/lib:$LIBRARY_PATH 这样环境变量就配置OK啦。这个时候我们只需要关闭我们的Shell终端重新打开终端就生效了。 3.Swift+Ubuntu初次体验 搞过iOS开发的都知道,2014年6月Swift刚出世时就随Xcode带了Playground功能,可以边写边看运行结果,辣么在Ubuntu Linux下有没有类似的呢,也有,只是没那么强大的IDE支持,我们一样可以运行类似Pyhton脚本解析器一样的Swift解析器,同步输入Swift代码来“解析”运行。这个命令就是swift,在上面的环境变量设置完后重开终端就可以直接使用了,如下所示。 diveinedu@diveinedu-VirtualBox:~$ swift Welcome to Swift version 2.2-dev (LLVM 46be9ff861, Clang 4deb154edc, Swift 778f82939c). Type :help for assistance. 1> let hello = "hello"; hello: String = "hello" 2> let world = "diveinedu" world: String = "diveinedu" 3> let space = " " space: String = " " 4> print(hello+space+world); hello diveinedu 5>hello. Available completions: append(c: Character) -> Void append(x: UnicodeScalar) -> Void appendContentsOf(newElements: S) -> Void appendContentsOf(other: String) -> Void characters: String.CharacterView debugDescription: String endIndex: Index hashValue: Int insert(newElement: Character, atIndex: Index) -> Void insertContentsOf(newElements: S, at: Index) -> Void isEmpty: Bool lowercaseString: String nulTerminatedUTF8: ContiguousArray<CodeUnit> removeAll() -> Void removeAll(keepCapacity: Bool) -> Void removeAtIndex(i: Index) -> Character removeRange(subRange: Range<Index>) -> Void replaceRange(subRange: Range<Index>, with: C) -> Void replaceRange(subRange: Range<Index>, with: String) -> Void reserveCapacity(n: Int) -> Void startIndex: Index unicodeScalars: String.UnicodeScalarView uppercaseString: String utf16: String.UTF16View utf8: String.UTF8View withCString(f: UnsafePointer<Int8> throws -> ResultUnsafePointer<Int8> throws -> Result) -> Result withMutableCharacters(body: (inout String.CharacterView) -> R(inout String.CharacterView) -> R) -> R write(other: String) -> Void writeTo(&target: Target) -> Void 6> hello.isEmpty $R0: Bool = false 在这个解析执行界面还有自动提示补全功能!简直四国矣.上面第五行是输入hello后再输入一点.然后按tab键,一下就出来这么多关于字符串的方法,妈妈再也不担心我在终端模式下不记得方法名了。 上面这特简单的几行代码还没包含类和对象,下面看看在swift解析器中直接输入类的定义和对象创建和简单使用。 diveinedu@diveinedu-VirtualBox:~$ swift Welcome to Swift version 2.2-dev (LLVM 46be9ff861, Clang 4deb154edc, Swift 778f82939c). Type :help for assistance. 1> struct Resolution { 2. var width = 0 3. var height = 0 4. } 5. class VideoMode { 6. var resolution = Resolution() 7. var interlaced = false 8. var frameRate = 0.0 9. var name: String? 10. func description() 11. { 12. print("name:\(name) frameRate:\(frameRate)") 13. } 14. } 15> let mode = VideoMode() mode: VideoMode = { resolution = { width = 0 height = 0 } interlaced = false frameRate = 0 name = nil } 16> mode.name = "1080p HD" 17> mode.frameRate = 30.0 18> mode.description() name:Optional("1080p HD") frameRate:30.0 19> 这些都只是在swift解析器中临时性的运行一些代码,如果我们需要新建.swift格式文件然后编译成可执行二进制文件形式又要怎样做呢,同样很简单,我们可以用swiftc这个命令来编译。 我们可以新建一个目录来存放swift代码文件,然后编辑一个test.swift: diveinedu@diveinedu-VirtualBox:~$ mkdir -p $HOME/swift/swiftcode diveinedu@diveinedu-VirtualBox:~$ cd $HOME/swift/swiftcode diveinedu@diveinedu-VirtualBox:~/swift/swiftcode$ gedit test.swift 当打开gedit文本编辑器后,输入上面的类和对象创建以及方法调用的代码,列出在下面 struct Resolution { var width = 0 var height = 0 } class VideoMode { var resolution = Resolution() var interlaced = false var frameRate = 0.0 var name: String? func description() { print("name:\(name) frameRate:\(frameRate)") } } let mode = VideoMode() mode.name = "1080p HD" mode.frameRate = 30.0 mode.description() 保存后关闭编辑器,然后执行swiftc test.swift来编译源文件,会出现如下链接错误: diveinedu@diveinedu-VirtualBox:~/swift/swiftcode$ swiftc test.swift <unknown>:0: error: link command failed with exit code 127 (use -v to see invocation) diveinedu@diveinedu-VirtualBox:~/swift/swiftcode$ 解决办法是安装编译依赖clang libicu-dev,输入下面命令回车(会询问当前用户密码) diveinedu@diveinedu-VirtualBox:~/swift/swiftcode$ sudo apt-get install clang libicu-dev 安装完成后再次执行编译命令swiftc test.swift就顺利编译成功,再当前目录下输出test可执行文件。 diveinedu@diveinedu-VirtualBox:~/swift/swiftcode$ swiftc test.swift diveinedu@diveinedu-VirtualBox:~/swift/swiftcode$ ./test name:Optional("1080p HD") frameRate:30.0 而且执行ldd ./test查看此二进制文件依赖的动态库可知,它链接了libswiftCore,这是所有swift程序都会需要的。 diveinedu@diveinedu-VirtualBox:~/swift/swiftcode$ ldd ./test linux-vdso.so.1 => (0x00007ffcef3f5000) libswiftCore.so => /home/diveinedu/swift/swift-2.2-SNAPSHOT-2015-12-01-b-ubuntu15.10/usr/lib/swift/linux/libswiftCore.so (0x00007f1cd2f75000) libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f1cd2bdd000) libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f1cd28d5000) libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f1cd26be000) libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f1cd22f3000) libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f1cd20d5000) libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f1cd1ed1000) libicuuc.so.55 => /usr/lib/x86_64-linux-gnu/libicuuc.so.55 (0x00007f1cd1b3c000) libicui18n.so.55 => /usr/lib/x86_64-linux-gnu/libicui18n.so.55 (0x00007f1cd16d9000) libbsd.so.0 => /lib/x86_64-linux-gnu/libbsd.so.0 (0x00007f1cd14c9000) /lib64/ld-linux-x86-64.so.2 (0x0000556e488b7000) libicudata.so.55 => /usr/lib/x86_64-linux-gnu/libicudata.so.55 (0x00007f1ccfa11000) 细心的读者会发现好像不见main函数或者main相关的函数,程序照样可以运行,不管是脚本还是编译成二进制可执行文件,这个我以后再细说了。 文章转载自 开源中国社区[https://www.oschina.net]

优秀的个人博客,低调大师

hadoop学习笔记:hadoop文件系统浅析

1.什么是分布式文件系统? 管理网络中跨多台计算机存储的文件系统称为分布式文件系统。 2.为什么需要分布式文件系统了? 原因很简单,当数据集的大小超过一台独立物理计算机的存储能力时候,就有必要对它进行分区(partition)并存储到若干台单独计算机上。 3.分布式系统比传统的文件的系统更加复杂 因为分布式文件系统架构在网络之上,因此分布式系统引入了网络编程的复杂性,所以分布式文件系统比普通文件系统更加复杂。 4.Hadoop的文件系统 很多童鞋会把hdfs等价于hadoop的文件系统,其实hadoop是一个综合文件系统抽象,而hdfs是hadoop旗舰级文件系统,hadoop除了hdfs还能集成其他文件系统。Hadoop的这个特点充分体现了hadoop的优良的可扩展性。 在hadoop里,hadoop定义了一个抽象的文件系统的概念,具体就是hadoop里面定义了一个java的抽象类:org.apache.hadoop.fs.FileSystm,这个抽象类用来定义hadoop中的一个文件系统接口,只要某个文件系统实现了这个接口,那么它就可以作为hadoop支持的文件系统。下面是目前实现了hadoop抽象文件类的文件系统,如下表所示: 文件系统 URI方案 Java实现 (org.apache.hadoop) 定义 Local file fs.LocalFileSystem 支持有客户端校验和本地文件系统。带有校验和的本地系统文件在fs.RawLocalFileSystem中实现。 HDFS hdfs hdfs.DistributionFileSystem Hadoop的分布式文件系统。 HFTP hftp hdfs.HftpFileSystem 支持通过HTTP方式以只读的方式访问HDFS,distcp经常用在不同的HDFS集群间复制数据。 HSFTP hsftp hdfs.HsftpFileSystem 支持通过HTTPS方式以只读的方式访问HDFS。 HAR har fs.HarFileSystem 构建在Hadoop文件系统之上,对文件进行归档。Hadoop归档文件主要用来减少NameNode的内存使用。 KFS kfs fs.kfs.KosmosFileSystem Cloudstore(其前身是Kosmos文件系统)文件系统是类似于HDFS和Google的GFS文件系统,使用C++编写。 FTP ftp fs.ftp.FtpFileSystem 由FTP服务器支持的文件系统。 S3(本地) s3n fs.s3native.NativeS3FileSystem 基于Amazon S3的文件系统。 S3(基于块) s3 fs.s3.NativeS3FileSystem 基于Amazon S3的文件系统,以块格式存储解决了S3的5GB文件大小的限制。 最后我要强调一点:在hadoop里有一个文件系统概念,例如上面的FileSystem抽象类,它是位于hadoop的Common项目里,主要是定义一组分布式文件系统和通用的I/O组件和接口,hadoop的文件系统准确的应该称作hadoop I/O。而HDFS是实现该文件接口的hadoop自带的分布式文件项目,hdfs是对hadoop I/O接口的实现。 下面我给大家展示一张表,这样大家对hadoop的FileSystem里的相关API操作就比较清晰了,表如下所示: Hadoop的FileSystem Java操作 Linux操作 描述 URL.openSteam FileSystem.open FileSystem.create FileSystem.append URL.openStream open 打开一个文件 FSDataInputStream.read InputSteam.read read 读取文件中的数据 FSDataOutputStream.write OutputSteam.write write 向文件写入数据 FSDataInputStream.close FSDataOutputStream.close InputSteam.close OutputSteam.close close 关闭一个文件 FSDataInputStream.seek RandomAccessFile.seek lseek 改变文件读写位置 FileSystem.getFileStatus FileSystem.get* File.get* stat 获取文件/目录的属性 FileSystem.set* File.set* Chmod等 改变文件的属性 FileSystem.createNewFile File.createNewFile create 创建一个文件 FileSystem.delete File.delete remove 从文件系统中删除一个文件 FileSystem.rename File.renameTo rename 更改文件/目录名 FileSystem.mkdirs File.mkdir mkdir 在给定目录下创建一个子目录 FileSystem.delete File.delete rmdir 从一个目录中删除一个空的子目录 FileSystem.listStatus File.list readdir 读取一个目录下的项目 FileSystem.getWorkingDirectory getcwd/getwd 返回当前工作目录 FileSystem.setWorkingDirectory chdir 更改当前工作目录 有了这张表,大家对FileSystem的理解应该会清晰多了吧。 大家从对照表里会发现,hadoop的FileSystem里有两个类:FSDataInputStream和FSDataOutputStream类,它们相当于java I/O里的InputStream和Outputsteam,而事实上这两个类是继承java.io.DataInputStream和java.io.DataOutputStream。 至于关于hadoop I/O本文今天不做介绍,以后也许会专门写篇文章讲讲我自己的理解,不过为了给大家一个清晰的印象,我在博客园里找到了两篇文章,有兴趣的童鞋可以好好看看看,连接如下: http://www.cnblogs.com/xuqiang/archive/2011/06/03/2042526.html http://www.cnblogs.com/xia520pi/archive/2012/05/28/2520813.html 5.数据的完整性 数据完整性也就是检测数据是否损坏的技术。Hadoop用户肯定都希望系统在存储和处理数据时候,数据不会有任何的丢失或损坏,尽管磁盘或网络上的每个I/O操作都不太可能将错误引入到自己正在读写的数据里,但是如果系统需要处理的数据量大到hadoop能够处理的极限,数据被损坏的概率就很高了。Hadoop引入了数据完整性校验的功能,下面我将其原理描述如下: 检测数据是否损坏的措施是,在数据第一次引入系统时候计算校验和(checksum),并在数据通过一个不可靠的通道时候进行传输时再次计算校验和,这样就能发现数据是否损坏了,如果两次计算的校验和不匹配,你就认为数据已经损坏了,但是该技术不能修复数据,它只能检测出错误。常用的错误检测码是CRC-32(循环冗余校验),任何大小的数据输入均计算得到一个32位的整数校验和。 6.压缩与输入分片 文件压缩有两大好处:一是可以减少存储文件所需要的磁盘空间,二是可以加速数据在网络和磁盘上的传输。对于处理海量数据的hadoop而言,这两个好处就变得相当重要了,所以理解hadoop的压缩是很有必要的,下表列出了hadoop支持的压缩格式,如下表: 压缩格式 工具 算法 文件扩展名 多文件 可分割性 DEFLATE 无 DEFLATE .deflate 不 不 gzip gzip DEFLATE .gz 不 不 ZIP zip DEFLATE .zip 是 是,在文件范围内 bzip2 bzip2 bzip2 .bz2 不 是 LZO lzop LZO .lzo 不 是 在hadoop对于压缩有两个指标很重要一个是压缩率还有就是压缩速度,下表列出一些压缩格式在此方面表现的性能,如下所示: 压缩算法 原始文件大小 压缩后的文件大小 压缩速度 解压缩速度 gzip 8.3GB 1.8GB 17.5MB/s 58MB/s bzip2 8.3GB 1.1GB 2.4MB/s 9.5MB/s LZO-bset 8.3GB 2GB 4MB/s 60.6MB/s LZO 8.3GB 2.9GB 49.3MB/S 74.6MB/s 在hadoop支持压缩里,是否支持切分(splitting)文件的特性也是相当重要的,下面我将讲述切分的问题,也就是我标题写的输入分片的问题: 压缩格式是否可以切分的特性是针对mapreduce处理数据而言的,比如我们有一个压缩为1GB的文件,如果hdfs块大小设置为(hdfs块我的文章里没有讲解,不理解的童鞋可以先查查百度,以后我在写hdfs时候会重点讲这个的)64mb,那么这个文件将存储在16个块里,如果把这个文件作为mapreduce作业的输入数据,mapreduce会根据这16个数据块,产生16个map操作,每个块都是其中一个map操作的输入,那么mapreduce执行效率会非常的高,但是这个前提就是该压缩格式要支持切分。假如压缩格式不支持切分的话,那么mapreduce也是可以做出正确处理,这时候它会将16个数据块放到一个map任务里面,这时候map任务数少了,作业粒度也变大了,那么执行效率就会大大下降。 由于本人知识还是有限,关于压缩和切入分片的问题我就讲述到这里,下面提供一篇相关的文章,有兴趣的童鞋可以看看,链接如下: http://www.cnblogs.com/ggjucheng/archive/2012/04/22/2465580.html 7.hadoop序列化 我们先看两个定义: 序列化:是指将结构化对象转化为字节流,以便在网络上传输或写到磁盘上进行永久存储。 反序列化:是指将字节流转向结构化对象的逆过程。 序列化在分布式数据处理量大领域经常出现:进程通信和永久存储。 Hadoop中,各个节点的通信是通过远程调用(RPC)实现的,RPC将数据序列化成二进制后发送给远程节点,远程节点收到数据后将二进制字节流反序列化为原始数据。序列化在RPC应用中有着自己的特点,RPC序列化的特点是: 紧凑:紧凑的格式能让我们能充分利用网络带宽,而带宽是数据中心最稀缺的资源; 快速:进程通信形成了分布式系统的骨架,所以需要尽量减少序列化和反序列化的性能开销,这是基本的 可扩展:协议为了满足新的需求变化,所以控制客户端和服务器过程中,需要直接引进相应的协议,这些事新协议,原序列化方式能支持心得协议报文 互操作:能支持不同语言写的客户端和服务端进行交互 在hadoop里面有自己定义的序列化格式:writable,它是hadoop的核心之一。 Writable是一个接口,要实现hadoop的序列化就得实现该接口。因为时间原因,序列化我也不展开了,我下面也推荐一篇文章,里面讲述了hadoop的序列化,虽然讲的简单点,而且不全面,但是看完后对hadoop序列化的具体实现会有个初步的了解,链接如下: http://blog.csdn.net/a15039096218/article/details/7591072 摘自http://www.cnblogs.com/sharpxiajun/archive/2013/06/15/3137765.html 本文转自茄子_2008博客园博客,原文链接:http://www.cnblogs.com/xd502djj/p/4882857.html,如需转载请自行联系原作者。

资源下载

更多资源
优质分享App

优质分享App

近一个月的开发和优化,本站点的第一个app全新上线。该app采用极致压缩,本体才4.36MB。系统里面做了大量数据访问、缓存优化。方便用户在手机上查看文章。后续会推出HarmonyOS的适配版本。

Spring

Spring

Spring框架(Spring Framework)是由Rod Johnson于2002年提出的开源Java企业级应用框架,旨在通过使用JavaBean替代传统EJB实现方式降低企业级编程开发的复杂性。该框架基于简单性、可测试性和松耦合性设计理念,提供核心容器、应用上下文、数据访问集成等模块,支持整合Hibernate、Struts等第三方框架,其适用范围不仅限于服务器端开发,绝大多数Java应用均可从中受益。

Rocky Linux

Rocky Linux

Rocky Linux(中文名:洛基)是由Gregory Kurtzer于2020年12月发起的企业级Linux发行版,作为CentOS稳定版停止维护后与RHEL(Red Hat Enterprise Linux)完全兼容的开源替代方案,由社区拥有并管理,支持x86_64、aarch64等架构。其通过重新编译RHEL源代码提供长期稳定性,采用模块化包装和SELinux安全架构,默认包含GNOME桌面环境及XFS文件系统,支持十年生命周期更新。

Sublime Text

Sublime Text

Sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等。还可自定义键绑定,菜单和工具栏。Sublime Text 的主要功能包括:拼写检查,书签,完整的 Python API , Goto 功能,即时项目切换,多选择,多窗口等等。Sublime Text 是一个跨平台的编辑器,同时支持Windows、Linux、Mac OS X等操作系统。

用户登录
用户注册