首页 文章 精选 留言 我的

精选列表

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

solaris学习3:启动过程

#---------- ADDED BY BOOTADM - DO NOT EDIT ---------- title Oracle Solaris 10 8/11 s10x_u10wos_17b X86 findroot (rootfs0,2,a) kernel /platform/i86pc/multiboot module /platform/i86pc/boot_archive #---------------------END BOOTADM-------------------- #---------- ADDED BY BOOTADM - DO NOT EDIT ---------- title Solaris failsafe findroot (rootfs0,2,a) kernel /boot/multiboot kernel/unix -s module /boot/x86.miniroot-safe #---------------------END BOOTADM-------------------- title Windows rootnoverify (hd0,0) chainloader +1 以上是solaris10的启动,正常启动重root下的/platform下调用文件,而failsafe则从/boot下调用引导文件。两者不一样,还没对solaris的引导机制理解,估测与linux可能有点不一样。等理解后再补充。 现在有点时间来写些solaris的启动过程了,首先说说上面的solaris grub的启动菜单。 1、 menu.lst 活动的grub menu.lst文件才能对OS启作用,其他的menu.lst文件对系统不起任何作用,这里就有个问题了,活动的menu.lst文件在哪里,即OS启动时会调用那个menu.lst?用命令bootadm查看: 至于menu.lst文件中的solaris 启动文件,只有x86架构的solaris才有grub引导,solaris的内核文件在/platform下。而windows的部分,我发现一个有趣的现象:我在我的笔记本安装solaris,没有系统(全部重新分区了),只是将第一个主分区format成ntfs,放入grub、menu.lst等一些引导文件,第二个主分区为fat32,放入solaris的iso文件,然后用硬盘安装方式安装完毕后,呵呵,solaris的menu.lst也有windows的引导部分,看来solaris是检测到某个主分区为dos格式的,就会在menu.lst创建windows的引导部分。 另外failsafe是什么?我的理解是单用户模式的迷你引导boot,不需要root密码(区别单用户模式的关键),将/dev/dsk/c0d0s0 mounted,提供基本的修复命令。 2、 solaris引导过程(以sparc为例,没有grub引导) 引导PROM(简单理解就是加电硬件自检过程): x86架构为BIOS将运行自检诊断,验证硬件和内存,未发现硬件错误则进入自动引导过程。sparc架构类似,主机加电后,prom运行POST自检硬件,如果无错误,并且auto-boot为true,则进入自动引导过程。呵呵,这样说的太简单了,由于x86没什么说的,就以sparc架构说说: POST自检硬件和内存,通过后下一步(此时可以进入OK模式,即命令行模式操作一些启动设置) 显示主机ID等信息:如cpu类型和速度,PROM版本号NVRAM sn号,网卡MAC,主机ID等 读取PROM参数boot-device确定启动设备 读取启动设备的0扇区的disk label(即VTOC) 查找启动程序(grub启动的sector1~15内容) 2. 引导程序过程 bootlk将ufsboot加载到内存 ufsboot加载内核:有两个内核,genunix是独立于平台的通用内核文件,unix是平台特定的内核文件。ufsboot将两个内核加载进内存,两个内核一起形成后来系统运行的内核。内核文件在:x86 /etc/`uname -m`/kernel x64 /etc/`uname -m`/kernel/sparc9 内核其他目录有:/kernel /usr/kernel 内核目录的子目录:drv 设备驱动 exec 可执行的文件 fs 文件系统类型 misc虚拟模块(usb、cdrom等) sched 调度 strmod 流模块(用户和设备间连接) sys 系统接口定义 3. 内核初始化过程 内核读取/etc/system文件(内核参数配置文件) 内核初始化自己加载模块,内核用ufsboot命令加载文件,当挂载跟“/”完成后,内核unmap ufsboot program 内核启动/etc/init进程,/etc/init是 /sbin/init的link。 4. init过程 init读取/etc/inittab,确定运行级别,solaris的级别是串行的,即先runlevel 1 在runlevel 2 ,再到runlevel 3。至于运行级别在下面说明。 5. svc.startd过程 启动各种系统服务 3、 运行级别 各种系统的默认运行级别:redhat 5 solaris 3 mac os x 3 AIX 2等 solaris的运行级别有8种 0 硬件维护模式 控制台访问进入OBP状态 /etc/rc0.d 命令脚本:/sbin/rc0 1 管理状态只有root用户可用 单用户 /etc/rc1.d 命令脚本:/sbin/rc1 2 第一个多用户状态,nfs等网络不可用 多用户 /etc/rc2.d 命令脚本:/sbin/rc2 3 多用户,网络可用 多用户 /etc/rc3.d 命令脚本:/sbin/rc3 4 用户自定义 没有指定 没有目录 5 关闭电源状态 控制台访问 /etc/rc5.d 命令脚本:/sbin/rc5 6 关闭重启 单用户 /etc/rc6.d 命令脚本:/sbin/rc6 S 管理任务或修复系统文件 控制台访问 /etc/rcS.d 命令脚本:/sbin/rcS 每个运行级别在/sbin 目录下都有一个对应的RC脚本,init用这些RC脚本设置变量、测试环境、启动停止其他进程脚本。 对于/etc/rc#.d 目录下的脚本文件,K开头为kill,S开头为start,忽略任何其他开头的文件,K、S一定要大写,并且按后面的数字顺序执行,如S10比S12优先。如果用户想在/etc/rc#.d目录自己建个启动脚本,脚本以 .sh结束则不需要start stop参数,否则需要提交start和stop参数。 查看运行级别:runlevel 或 who -r 切换运行级别:init n (linux的命令就有几个:init telinit initctl等) init Q 或 init q 是init进程立即重新读取并处理inittab文件 另外有个概念要注意:里程碑 个人理解(摘自网络):指定类型的服务,是一个层次依靠关系,即服务运行到一种状态要依靠其它的服务运行才可以用的以类型依靠状态。 从运行级别来看,就是solaris10用来替代运行级别的概念,比如single-user里程碑相当于运行级别S,multi-user里程碑相当于运行级别2,multi-user-server相当于运行级别3. 有7种milestone,上面列了三种,还有:network 、 name-sevices、sysconfig、devices 4、 solaris注销: linux注销在我的blog里说了,那么solaris怎样才能注销呢?开始对其了解不多,不过应该和linux相似,都有桌面运行环境,如gnome、cde、jds等,所以solaris的注销命令为:pkill -9 dtsession ,是CDE桌面环境,我自己使用是没有问题的,希望大家有指正。那么JDS桌面环境如何注销,命令:pkill -9 Xsession 今天详细测试了下,注销solaris的问题新的理解是: 无论CDE、JDS,结束桌面环境都可以用干掉Xsession进程的方法,自己在JDS中用干掉Xorg的方法也可以注销桌面。 今天又有一个发现:solaris里有个命令whodo,可以查看终端的运行进程记录: 这是在CDE桌面,要注销就结束Xsession、dtsession,在JDS桌面还有gnome-session,结束该进程也可以注销。 ============================================================================ outlook历史记录清除方 现象: 如图:在收件人处输入字母:h,则出现三个收件人的地址,有些用户怕出错,不允许 这种情况出现,即输入字母h时,不会出现三个地址 具体方法如下,Outlook 2003应用测试通过 方法一: 工具-》选项-》首选参数-》电子邮件选项-》高级电子邮件选项 去掉“填写收件人、抄送人及密件抄送人字段时提示姓名”的勾选 方法二: C:\Documents and Settings\fuhaixiong\Application Data\Microsoft\Outlook下删除.nk2文件 方法三: 直接按delete删除 建议用第一种方法 本文转自fuhaixiong 51CTO博客,原文链接:http://blog.51cto.com/heliy/170949 ,如需转载请自行联系原作者

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

Android学习笔记--Content Provider 1

MicrosoftInternetExplorer402DocumentNotSpecified7.8Normal0 1.ContentProvider基本概念 A:ContentProvider提供为存储和获取数据提供了统一的接口 B:使用ContentProvider可以在不同的应用程序之间共享数据 C:Android为常见的一些数据提供了ContentProvider(包括音频,视频,图片和通讯录等等) 2.Uri A:每一个ContnetProvider都拥有一个公共的URI,这个URI用于表示这个ContnetProvider所提供的数据 B:Android所提供的ContentProvider都存放在android.provider包当中 3.ContnetProvider实现方法 Query Insert Update Delete getType onCreate 4.实现ContentProvider的过程 A:定义一个Content_URI常量 B:定义一个类,继承ContentProvider C:实现query,insertupdate,deletegetType,和onCreate方法; D:在AnroidManifest.xml当中进行声明; 例: //DatabaseHelper所为一个访问SQLite的助手类,提供两个方面的功能 //第一,getReadableDatabase()和getWritableDatabasr()可以获得SQLiteDatabase对象 //第二,提供onCreate和onUpgrade两个回调函数,允许我们在创建和升级数据库时,进行操作 例:publicclassDatabaseHelperextendsSQLiteOpenHelper{ //数据库版本号 PrivatestaticfinalintVERSION=1; //必须的构造函数 PublicDatabaseHelper(Contextcontext,Stringname,CursorFactoryfactory,intversion){ Super(context,name,factory,version); } PublicDatabaseHelper(Contextcontext,Stringname,intversion){ Super(context,name,null,version); } PublicDatabaseHelper(Contextcontext,Stringname){ Super(context,name,null,VERSION); } PublicvoidonCreate(SQLiteDatabasedb){ System.out.println("createadatabase"); //拼出了建表的语句 db..execSQL("createtable"+ FirstMetaData.USER_TABLE_NAME +"("+FirstMetaData.UserTableMetaData._ID +"INTEGERPRIMARYKEYAUTOINCREMENT," +FirstMetaData.UserTableMetaData.USER_NAME +"varchar(20));"; } PublicvoidonUpgrade(SQLiteDatabasedb){ System.out.println("updateadatabase"); } } ContentProviderActivity例: 1.声明控件对象(略) 2.获得控件对象(略) 3.绑定事件(略) 4.创建监听器对象 //insert PublicvoidonClick(Viewv){ ContentValuesvalues=newContentValues(); Values.put( FirstMetaData.UserTableMetaData.USER_NAME,"zhangsan" ); Uriuri=getContentesolver().insert( FirstMetaData.UserTableMetaData.CONTENT_URI,values ); System.out.println("uri---->"+uri.toString()); } //query PublicvoidonClick(Viewv){ Cursorc=getContentResolver().query( FirstMetaData.UserTableMetaData.CONTENT_URI,null,null,null,null ); While(c.moveToNext()){ System.out.println(c.getString(c.getColumnIndex(UserTableMeatData.USER_NAME))); } } 本文转自My_King1 51CTO博客,原文链接:http://blog.51cto.com/apprentice/1360568,如需转载请自行联系原作者

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

iOS学习——iOS系统架构(三)

iOS的系统架构分为四个层次:核心操作系统层(Core OS layer)、核心服务层(Core Services layer)、媒体层(Media layer)和可触摸层(Cocoa Touch layer)。下面是IOS系统结构图。 iOS结构图 1、Core OS是位于iOS系统架构最下面的一层是核心操作系统层,它包括内存管理、文件系统、电源管理以及一些其他的操作系统任务。它可以直接和硬件设备进行交互。作为app开发者不需要与这一层打交道。 2、Core Services是核心服务层,可以通过它来访问iOS的一些服务。 3、Media是媒体层,通过它我们可以在应用程序中使用各种媒体文件,进行音频与视频的录制,图形的绘制,以及制作基础的动画效果。 4、Cocoa Touch是可触摸层,这一层为我们的应用程序开发提供了各种有用的框架,并且大部分与用户界面有关,本质上来说它负责用户在iOS设备上的触摸交互操作。 iOS是基于UNIX内核,android是基于Linux内核,iOS和android作为两款优秀的手机操作系统,他们有共性有区别,下面分享一张android系统架构图: /** * @author 张兴业 * http://blog.csdn.net/xyz_lmn * iOS入门群: 83702688 * android开发进阶群: 241395671 * 我的新浪微博: @张兴业TBOW */ 本文转自xyz_lmn51CTO博客,原文链接:http://blog.51cto.com/xyzlmn/1230738 ,如需转载请自行联系原作者

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

iOS学习——UI基础UIButton(七)

前面写了UIWindow、UIViewController,那些都是一些框架,框架需要填充上具体的view才能组成我们的应用,移动应用开发中UI占了很大一部分,最基础的UI实现是使用系统提供的各种控件,其他的就是自定义实现了,作者目前是入门状态,只能写写基础控件了。 iOS中提供了UIButton、UILable、UITextField、UIImageView等基础UI控件,继承于UIView。这里先拿UIButton练练手,为什么拿UIButton呢,因为UIbutton继承自UIControl,UIControl派生自UIView类,每个控件都有很多视图的特性,包括附着于其他视图的能力,所有控件都拥有一套共同的属性和方法,包含显示内容,点击事件等等,UIControl的子类都有事件处理能力。 图、UIControl UIButton的定义: UIButton可使用initWithFrame、buttonWithType两种方式创建: 1)initWithFrame UIButton *btn=[[UIButton alloc]initWithFrame:CGRectMake(60, 60, 200, 60)]; btn.backgroundColor=[UIColor greenColor]; [btn setTitle:@"btn1" forState:UIControlStateNormal]; [self.view addSubview:btn]; 2)buttonWithType UIButton *btn2=[UIButton buttonWithType:UIButtonTypeRoundedRect]; CGRect rect=CGRectMake(60, 160, 200, 60); btn2.frame=rect; btn2.tag=1001; btn2.backgroundColor=[UIColor colorWithRed:30/255.0 green:200/255.0 blue:125/255.0 alpha:1.0]; [btn2 setTitle:@"btn2" forState:UIControlStateNormal]; [btn2 addTarget:self action:@selector(btn2Pressed) forControlEvents:UIControlEventTouchDown]; [self.view addSubview:btn2]; btn2Pressed方法: -(void)btn2Pressed{ NSLog(@"button pressed"); } UIButtonType: typedef enum { UIButtonTypeCustom = 0, // no button type 自定义,无风格 UIButtonTypeRoundedRect, // rounded rect, flat white button, like in address card 白色圆角矩形,类似偏好设置表格单元或者地址簿卡片 UIButtonTypeDetailDisclosure,//蓝色的披露按钮,可放在任何文字旁 UIButtonTypeInfoLight,//微件(widget)使用的小圆圈信息按钮,可以放在任何文字旁 UIButtonTypeInfoDark,//白色背景下使用的深色圆圈信息按钮 UIButtonTypeContactAdd,//蓝色加号(+)按钮,可以放在任何文字旁 } UIButtonType; UIButton常用属性: //设置对应状态的标题内容default is nil. title is assumed to be single line - (void)setTitle:(NSString *)title forState:(UIControlState)state; //设置对应状态的标题颜色 - (void)setTitleColor:(UIColor *)color forState:(UIControlState)state; //设置对应状态的标题阴影颜色 - (void)setTitleShadowColor:(UIColor *)color forState:(UIControlState)state; //设置对应状态的按钮的图片 - (void)setImage:(UIImage *)image forState:(UIControlState)state; //设置对应状态的按钮背景图片 - (void)setBackgroundImage:(UIImage *)image forState:(UIControlState)state; UIButton的UIControlState : typedef NS_OPTIONS(NSUInteger, UIControlState) { UIControlStateNormal = 0, UIControlStateHighlighted = 1 << 0, // used when UIControl isHighlighted is set UIControlStateDisabled = 1 << 1, UIControlStateSelected = 1 << 2, // flag usable by app (see below) UIControlStateApplication = 0x00FF0000, // additional flags available for application use UIControlStateReserved = 0xFF000000 // flags reserved for internal framework use }; 更多属性可参考官方文档。 UIButton添加事件: UIButton使用如下方法添加事件。 [btn addTarget:<#(id)#> action:<#(SEL)#> forControlEvents:<#(UIControlEvents)#>] 这些事件都是基于触摸、基于值、基于编辑。可相应如下事件。 typedef NS_OPTIONS(NSUInteger, UIControlEvents) { UIControlEventTouchDown = 1 << 0, // on all touch downs UIControlEventTouchDownRepeat = 1 << 1, // on multiple touchdowns (tap count > 1) UIControlEventTouchDragInside = 1 << 2, UIControlEventTouchDragOutside = 1 << 3, UIControlEventTouchDragEnter = 1 << 4, UIControlEventTouchDragExit = 1 << 5, UIControlEventTouchUpInside = 1 << 6, UIControlEventTouchUpOutside = 1 << 7, UIControlEventTouchCancel = 1 << 8, UIControlEventValueChanged = 1 << 12, // sliders, etc. UIControlEventEditingDidBegin = 1 << 16, // UITextField UIControlEventEditingChanged = 1 << 17, UIControlEventEditingDidEnd = 1 << 18, UIControlEventEditingDidEndOnExit = 1 << 19, // 'return key' ending editing UIControlEventAllTouchEvents = 0x00000FFF, // for touch events UIControlEventAllEditingEvents = 0x000F0000, // for UITextField UIControlEventApplicationReserved = 0x0F000000, // range available for application use UIControlEventSystemReserved = 0xF0000000, // range reserved for internal framework use UIControlEventAllEvents = 0xFFFFFFFF }; /** * @author 张兴业 * http://blog.csdn.net/xyz_lmn * iOS入门群:83702688 * android开发进阶群:241395671 * 我的新浪微博:@张兴业TBOW */ 参考: http://developer.apple.com/library/ios/#documentation/UIKit/Reference/UIButton_Class/UIButton/UIButton.html http://developer.apple.com/library/ios/#documentation/uikit/reference/UIKit_Framework/Introduction/Introduction.html#//apple_ref/doc/uid/TP40006955-CH1-SW1 一、UIKit结构图 本文转自xyz_lmn51CTO博客,原文链接:http://blog.51cto.com/xyzlmn/1230732,如需转载请自行联系原作者

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

Android学习笔记--WIFI的操作

MicrosoftInternetExplorer402DocumentNotSpecified7.8Normal0 1.什么是WIFI WIFI就是一种无线联网的技术,则又称为"热点" 2.获取WIFI网卡的状态 0-->正在关闭 1-->关闭状态 2-->正在打开 3-->网卡可用 4-->位置状态 3.操作WIFI所需要的权限 4.改变WIFI网卡的状态 例: 1.声明控件对象(略) 2.获得控件对象(略) 3.绑定事件(略) 4.创建监听器对象 PublicvoidonClick(Viewv){ WifiManagerwifiManager=(WifiManager)WifiActivity.this.getSystemService(Serivce.WIFI_SERVICE); wifiManager.setWifiEnabled(true);//打开WIfi网卡false关闭 System.out.println("wifistate--->"+wifiManager.getWifiState()); Toast.makeText(WifuActivity.this,"当前的WIFI网卡状态为"+wifiManager.getWifiState()); } 本文转自My_King1 51CTO博客,原文链接:http://blog.51cto.com/apprentice/1360563,如需转载请自行联系原作者

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

Android OpenGL 学习笔记 --开始篇

1、什么是 OpenGL? OpenGL是个专业的3D程序接口,是一个功能强大,调用方便的底层3D图形库。 OpenGL 的前身是 SGI 公司为其图形工作站开的 IRIS GL。IRIS GL 是一个工业标准的3D图形软件接口,功能虽然强大但是移植性不好,于是 SGI 公司便在 IRIS GL 的基础上开发 OpenGL 。具体详细的介绍请 点击这里。 2、OpenGL 的发展历程 1992年7月 发布了 OpenGL 1.0版本,并与微软共同推出 Windows NT 版本的 OpenGL。 1995年 OpenGL 1.1版本面市,加入了新功能,并引入了纹理特性等等。 一直到 2009年8月Khronos小组发布了 OpenGL3.2,这是一年以来 OpenGL进行的第三次重要升级。 具体特点及功能、 OpenGL现状、发展历程、 OpenGL规范、编程入门请 点击这里。 3、OpenGL ES 简介 Android 3D 引擎采用的是 OpenGL ES 。 OpenGL ES 是一套为手持和嵌入式系统设计的3D 引擎API ,由Khronos 公司维护。在PC 领域,一直有两种标准的3D API 进行竞争, OpenGL 和DirectX 。一般主流的游戏和显卡都支持这两种渲染方式,DirectX 在Windows 平台上有很大的优势,但是 OpenGL 具有更好的跨平台性。 由于嵌入式系统和PC 相比,一般说来,CPU 、内存等都比PC 差很多,而且对能耗有着特殊的要求,许多嵌入式设备并没有浮点运算协处理器,针对嵌入式系统的以上特点,Khronos 对标准的 OpenGL 系统进行了维护和改动,以期望满足嵌入式设备对3D 绘图的要求。 4、Android OpenGL ES简介 Android 系统使用 OpenGL 的标准接口来支持3D 图形功能,android 3D 图形系统也分为java 框架和本地代码两部分。本地代码主要实现的 OpenGL 接口的库,在Java 框架层,javax.microedition.khronos.opengles 是java 标准的 OpenGL 包,android.opengl 包提供了 OpenGL 系统和Android GUI 系统之间的联系。 5、Android 支持 OpenGL 列表 1、GL 2、GL 10 3、GL 10 EXT 4、GL 11 5、GL 11 EXT 6、GL 11 ExtensionPack 我们将使用 GL10 这个类开始接触 OpenGL,探索3D 领域。 6、一步一步实现自己的 Renderer 类 在 Android 中我们使用 GLSurfaceView 来显示 OpenGL视图,该类位于 android.opengl 包里面。它提供了一个专门用于渲染3D 的接口 Renderer 。接下来我们就来一步步构建自己的 Renderer 类。 1、为 Renderer 类赶回命名空间 import android.opengl.GLSurfaceView.Renderer; 2、新建一个类来实现 Renderer 接口,代码如下: public class ThreeDGl implements Renderer { } 3、如上代码所写,程序实现了 Renderer 类,则必须重写以下方法 public void onDrawFrame(GL10gl) { } public void onSurfaceChanged(GL10gl, int width, int height) {} public void onSurfaceCreated(GL10gl,EGLConfigconfig) {} 4、当窗口被创建时需要调用 onSurfaceCreate ,我们可以在这里对OpenGL做一些初始化工作,例如: // 启用阴影平滑 gl.glShadeModel(GL10.GL_SMOOTH); // 黑色背景 gl.glClearColor( 0 , 0 , 0 , 0 ); // 设置深度缓存 gl.glClearDepthf( 1.0f ); // 启用深度测试 gl.glEnable(GL10.GL_DEPTH_TEST); // 所作深度测试的类型 gl.glDepthFunc(GL10.GL_LEQUAL); // 告诉系统对透视进行修正 gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT,GL10.GL_FASTEST); glHint 用于告诉OpenGL我们希望进行最好的透视修正,这会轻微地影响性能,但会使得透视图更好看。 glClearColor 设置清除屏幕时所用的颜色,色彩值的范围从 0.0f~1.0f 大小从暗到这的过程。 glShadeModel 用于启用阴影平滑度。阴影平滑通过多边形精细地混合色彩,并对外部光进行平滑。 glDepthFunc 为将深度缓存设想为屏幕后面的层,它不断地对物体进入屏幕内部的深度进行跟踪。 glEnable 启用深度测试。 5、当窗口大小发生改变时系统将调用 onSurfaceChange 方法,可以在该方法中设置OpenGL场景大小 ,代码如下: // 设置OpenGL场景的大小 gl.glViewport( 0 , 0 ,width,height); 6、场景画出来了,接下来我们就要实现场景里面的内容,比如:设置它的透视图,让它有种越远的东西看起来越小的感觉,代码如下: // 设置投影矩阵 gl.glMatrixMode(GL10.GL_PROJECTION); // 重置投影矩阵 gl.glLoadIdentity(); // 设置视口的大小 gl.glFrustumf( - ratio,ratio, - 1 , 1 , 1 , 10 ); // 选择模型观察矩阵 gl.glMatrixMode(GL10.GL_MODELVIEW); // 重置模型观察矩阵 gl.glLoadIdentity(); gl.glMatrixMode(GL10.GL_PROJECTION); 指明接下来的代码将影响 projection matrix (投影矩阵),投影矩阵负责为场景增加透视度。 gl.glLoadIdentity(); 此方法相当于我们手机的重置功能,它将所选择的矩阵状态恢复成原始状态,调用glLoadIdentity(); 之后为场景设置透视图。 gl.glMatrixMode(GL10.GL_MODELVIEW);指明任何新的变换将会影响 modelview matrix (模型观察矩阵)。 gl.glFrustumf(-ratio,ratio,-1,1,1,10);此方法,前面4个参数用于确定窗口的大小,而后面两个参数分别是在场景中所能绘制深度的起点和终点。 7、了解了上面两个重写方法的作用和功能之后,第三个方法 onDrawFrame 从字面上理解就知道此方法做绘制图操作的。嗯,没错。在绘图之前,需要将屏幕清除成前面所指定的颜色,清除尝试缓存并且重置场景,然后就可以绘图了, 代码如下: // 清除屏幕和深度缓存 gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT); // 重置当前的模型观察矩阵 gl.glLoadIdentity(); 8、Renderer 类在实现了上面的三个重写之后,在程序入口中只需要调用 Rendererrender = new ThreeDGl( this ); /** Calledwhentheactivityisfirstcreated. */ @Override public void onCreate(BundlesavedInstanceState){ super .onCreate(savedInstanceState); GLSurfaceViewgview = new GLSurfaceView( this ); gview.setRenderer(render); setContentView(gview); } 即可将我们绘制的图形显示出来。 下面分享一段使用Renderer类绘制的三角形和四边形的代码: OpenGL 参考代码 package com.terry; import java.nio.IntBuffer; import javax.microedition.khronos.egl.EGLConfig; import javax.microedition.khronos.opengles.GL10; import android.opengl.GLSurfaceView.Renderer; public class GLRender implements Renderer{ float rotateTri,rotateQuad; int one = 0x10000 ; // 三角形的一个顶点 private IntBuffertriggerBuffer = IntBuffer.wrap( new int []{ 0 ,one, 0 , // 上顶点 - one, - one, 0 , // 左顶点 one, - one, 0 // 右下点 }); // 正方形的四个顶点 private IntBufferquateBuffer = IntBuffer.wrap( new int []{ one,one, 0 , - one, - one, 0 , one, - one, 0 , - one, - one, 0 }); private IntBuffercolorBuffer = IntBuffer.wrap( new int []{ one, 0 , 0 ,one, 0 ,one, 0 ,one, 0 , 0 ,one,one }); @Override public void onDrawFrame(GL10gl){ // TODOAuto-generatedmethodstub // 清除屏幕和深度缓存 gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT); // 重置当前的模型观察矩阵 gl.glLoadIdentity(); // 左移1.5单位,并移入屏幕6.0 gl.glTranslatef( - 1.5f , 0.0f , - 6.0f ); // 设置旋转 gl.glRotatef(rotateTri, 0.0f , 1.0f , 0.0f ); // 设置定点数组 gl.glEnableClientState(GL10.GL_VERTEX_ARRAY); // 设置颜色数组 gl.glEnableClientState(GL10.GL_COLOR_ARRAY); gl.glColorPointer( 4 ,GL10.GL_FIXED, 0 ,colorBuffer); // 设置三角形顶点 gl.glVertexPointer( 3 ,GL10.GL_FIXED, 0 ,triggerBuffer); // 绘制三角形 gl.glDrawArrays(GL10.GL_TRIANGLES, 0 , 3 ); gl.glDisableClientState(GL10.GL_COLOR_ARRAY); // 绘制三角形结束 gl.glFinish(); /** ******************** */ /* 渲染正方形 */ // 重置当前的模型观察矩阵 gl.glLoadIdentity(); // 左移1.5单位,并移入屏幕6.0 gl.glTranslatef( 1.5f , 0.0f , - 6.0f ); // 设置当前色为蓝色 gl.glColor4f( 0.5f , 0.5f , 1.0f , 1.0f ); // 设置旋转 gl.glRotatef(rotateQuad, 1.0f , 0.0f , 0.0f ); // 设置和绘制正方形 gl.glVertexPointer( 3 ,GL10.GL_FIXED, 0 ,quateBuffer); gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0 , 4 ); // 绘制正方形结束 gl.glFinish(); // 取消顶点数组 gl.glDisableClientState(GL10.GL_VERTEX_ARRAY); // 改变旋转的角度 rotateTri += 0.5f ; rotateQuad -= 0.5f ; } @Override public void onSurfaceChanged(GL10gl, int width, int height){ // TODOAuto-generatedmethodstub float ratio = ( float )width / height; // 设置OpenGL场景的大小 gl.glViewport( 0 , 0 ,width,height); // 设置投影矩阵 gl.glMatrixMode(GL10.GL_PROJECTION); // 重置投影矩阵 gl.glLoadIdentity(); // 设置视口的大小 gl.glFrustumf( - ratio,ratio, - 1 , 1 , 1 , 10 ); // 选择模型观察矩阵 gl.glMatrixMode(GL10.GL_MODELVIEW); // 重置模型观察矩阵 gl.glLoadIdentity(); } @Override public void onSurfaceCreated(GL10gl,EGLConfigconfig){ // TODOAuto-generatedmethodstub // 启用阴影平滑 gl.glShadeModel(GL10.GL_SMOOTH); // 黑色背景 gl.glClearColor( 0 , 0 , 0 , 0 ); // 设置深度缓存 gl.glClearDepthf( 1.0f ); // 启用深度测试 gl.glEnable(GL10.GL_DEPTH_TEST); // 所作深度测试的类型 gl.glDepthFunc(GL10.GL_LEQUAL); // 告诉系统对透视进行修正 gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT,GL10.GL_FASTEST); } } 到此基本对 OpenGL 有一些了解,当然OpenGL 还有更多的东西需要我们去探索,努力吧。 本文转自 terry_龙 51CTO博客,原文链接:http://blog.51cto.com/terryblog/346996,如需转载请自行联系原作者

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

Spark SQL 中 dataFrame 学习总结

dataFrame多了数据的结构信息。就是schema。 RDD是分布式的 Java对象的集合。DataFrame是分布式的Row对象的集合。 DataFrame 提供了详细的结构信息,可以让sparkSQL清楚的知道数据集中包含哪些列,列的名称和类型各是什么? RDD是分布式的 Java对象的集合。DataFrame是分布式的Row对象的集合。DataFrame除了提供了 比RDD更丰富的算子以外,更重要的特点是提升执行效率、减少数据读取以及执行计划的优化,比如 filter下推、裁剪等。 提升执行效率 RDD API是函数式的,强调不变性,在大部分场景下倾向于创建新对象而不是修改老对象。这一特点虽然 带来了干净整洁的API,却也使得Spark应用程序在运行期倾向于创建大量临时对象,对GC造成压力。在 现有RDD API的基础之上,我们固然可以利用mapPartitions方法来重载RDD单个分片内的数据创建方式 用复用可变对象的方式来减小对象分配和GC的开销,但这牺牲了代码的可读性,而且要求开发者对Spark 运行时机制有一定的了解,门槛较高。另一方面,Spark SQL在框架内部已经在各种可能的情况下尽量重 用对象,这样做虽然在内部会打破了不变性,但在将数据返回给用户时,还会重新转为不可变数据。利 用 DataFrame API进行开发,可以免费地享受到这些优化效果。 减少数据读取 分析大数据,最快的方法就是 ——忽略它。这里的“忽略”并不是熟视无睹,而是根据查询条件进行恰 当的剪枝。 上文讨论分区表时提到的分区剪 枝便是其中一种——当查询的过滤条件中涉及到分区列时,我们可以根 据查询条件剪掉肯定不包含目标数据的分区目录,从而减少IO。 对于一些“智能”数据格 式,Spark SQL还可以根据数据文件中附带的统计信息来进行剪枝。简单来 说,在这类数据格式中,数据是分段保存的,每段数据都带有最大值、最小值、null值数量等 一些基本 的统计信息。当统计信息表名某一数据段肯定不包括符合查询条件的目标数据时,该数据段就可以直接 跳过(例如某整数列a某段的最大值为100,而查询条件要求a > 200)。 此外,Spark SQL也可以充分利用RCFile、ORC、Parquet等列式存储格式的优势,仅扫描查询真正涉及的 列,忽略其余列的数据。 Dataset可以认为是DataFrame的一个特例,主要区别是Dataset每一个record存储的是一个强类型值而不 是一个Row。因此具有如下三个特点: DataSet可以在编译时检查类型 并且是面向对象的编程接口 DataFrame是面向sparkSQL的接口。 DataFrame和dataSet可以相互转化。 df.as[ElementType] 这样可以把DataFrame转化为DataSet, ds.toDF() 这样可以把DataSet转化为DataFrame。 本文转自 ChinaUnicom110 51CTO博客,原文链接:http://blog.51cto.com/xingyue2011/1964917

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

Android学习笔记--Content Provider 2

FirstContentProvider继承ContentProvider例: PublicclassFirstContentProviderextendsContentProvider{ PublicstaticfinalUriMatcheruriMatcher; PublicstaticfinalintINCOMING_USER_COLLECTION=1; PublicstaticfinalintINCOMING_USER_SINGLE=2; Private DatabaseHelperdh; Static{ uriMatcher=newUriMatcher(UriMatcher.NO_MATCH); //URI限定名的添加验证定义了一个验证的规则 uriMatcher.addURI(FirstMetaData.AUTHORTY,"/users",INCOMING_USER_COLLECTION); uriMatcher.addURI(FirstMetaData.AUTHORTY,"/users/#",INCOMING_USER_SINGLE); } PublicstaticHashMap<String,String>userProjectionMap; Static { userProjectionMap=newHashMap<String,String>(); //._ID就是baseColumns实现的结果 userProjectionMap.put( FirstMetaData._ID,FirstMetaData._ID ); userProjectionMap.put( FirstMetaData.USER_NAME,FirstMetaData.USER_NAME ); } @Override Publicintdelete(Uriarg0,Stringarg1,String[]arg2){ System.out.println("delete"); Return0; } //根据传入的Uri,返回该Uri所表示的数据类型 @Override PublicStringgetType(Uriuri){ System.out.println("getType"); Switch(uriMatcher.match(uri)){ CaseINCOMING_USER_COLLECTION: Return FirstMetaData.CONTENT_TYPE; CaseINCOMING_USER_SINGLE: ReturnFirstMetaData.CONTENT_TYPE_ITEM; Default: ThrownewIllegalArgumentExecption("UnknownURI"+uri); } } //该函数的返回值是一个Uri,这个URi表示的是刚刚使用这个函数所插入的数据 //content:// com.android.FirstContentProvider/users/1 @Override PublicUriinsert(Uriuri,ContentValuevalues){ System.out.println("insert"); SQLiteDatabasedb=dh.getWrittableDatabase(); LongrowId=db.insert( FirstMetaData.TABLE_NAME,null,values ); If(rowId>0){ //以Content起头的Uri都可以用ContentUris来处理 UriinsertedUserUri=ContentUris.withAppendedId(UserTableMetaData.CONTENT_URI,rowId); //通知监听器,数据已经改变 getContext().getContentResolver().notifyChange(insertedUserUri,null); ReturninsertedUserUri; } ThrownewSQLExecption("Failedtoinsertrowinto"+uri); } @Override PublicbooleanonCreate(){ Dh=newDatabaseHelper(getContext(), FirstMetaData.DATABASE_NAME ); System.out.println("onCreate"); Returntrue; } @Override PublicCursorquery(Uriuri,String[]projection,Stringselection,String[]selectionArgs,StringsortOrder){ SQLiteQueryBuilderqb=newSQLiteQueryBuilder(); Switch(uriMatcher.match(uri)){ CaseINCOMING_USER_COLLECTION: qb.setTables( FirstMetaData.TABLE_NAME ); qb.setProjectionMap(userProjectionMap); Break; CaseINCOMING_USER_SINGLE: qb.setTables( FirstMetaData.TABLE_NAME ); qb.setProjectionMap(userProjectionMap); //取回了单条数据list qb.appendWhere( FirstMetaData._ID+"="+uri.getPathSeqments().get(1) ); Break; } StringorderBy; If(TextUtils.isEmpty(sortOrder)){ orderBy= FirstMetaData.DEFAULT_SORT_ORDER; }else{ orderBy=sortOrder; } SQLiteDatabasedb=dh.getWritableDatabase(); Cursorc=qb.query(db,projection,selection,selectionArgs,null,null,orderBy); c.setNotificationUri(getContext().getContentResolver(),uri); System.out.println("query"); Returnc; } @Override Publicintupdate(Uriarg0,ContentValuesarg1,Stringarg2,String[]arg3){ System.out.println("update"); } } FirstMetaData(一些静态常量)例: PublicclassFirstMetaData{ //URI限定名的名称包名+类名 PublicstaticfinalStringAUTHORTY="com.android.FirstContentProvider"; //数据库名称 PublicstaticfinalStringDATABASE_NAME="FirstContentProvider.db"; //数据库版本 PublicstaticfinalintDATABASE_VERSION=1; //表名 PublicstaticfinalStrintUSERS_TABLE_NAME="users"; //BaseColumns实现了表的_id列 PublicstaticfinalclassUserTableMetaDataimplementsBaseColumns{ //表名 PublicstaticfinalStringTABLE_NAME="users"; //访问该ContentProvider的URI PublicstaticfinalUriCONTENG_URI=Uri.parse("content://"+AUTHORY+"/users"); //整张表的数据类型是vnd.android.cursor.dir/vnd+name; PublicstaticfinalStringCONTENT_TYPE="vnd.android.cursor.dir/vnd.FinrstContentProvider.ser"; //单条数据类型定义vnd.android.cursor.item/vnd+name PublicstaticfinalStringCONTENT_TYPE_ITEM="vnd.android.cursor.item/vnd.FinrstContentProvider.user"; //列名 PublicstaticfinalStringUSER_NAME="name"; //默认排序方法 PublicstaticfinalStringDEFAULT_SORT_ORDER="_iddesc"; } } 最后在androidMnaifest.xml中注册provider与Activity同级authorities中的数据一定要与CONTENG_URI的一致 <providerandroid:name="com.android.FirstContentProvider" Android:authorities="com.android.FirstContentProvider"/> 本文转自My_King1 51CTO博客,原文链接:http://blog.51cto.com/apprentice/1360567,如需转载请自行联系原作者

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

Android学习笔记--Activity和intent

MicrosoftInternetExplorer402DocumentNotSpecified7.8Normal0 多个Activity之间的关系 跳转关键startActivity(Intentintent) 在onClickListener监听器的onClick方法中 内部类继承OnClickListener Intentintent=newIntent(); intent.putExtra(key,value);//设置传参数据 intent.setClass(this,class);//设置跳转参数 Activity.this.startActivity(intent); 事件绑定 myButton=(Button)findViewById(R.id.myButton); myButton.setOnClickListener(new内部类名());//注册成功 Intent对象的获取 Intentintent=getIntent(); Stringvalue=intent.getStringExtra(key); TextView=(TextView)findViewById(R.id.myTextView); TextView.setText(value); 2.Intent的基本作用 Intent对象包含了一组信息相当于一个请求 1.Componentname(欲启动Activity的名称等等) 2.Action(另一个Activity的动作) 3.Data(传递的数据) 4.Category 5.Exreas(额外的键值对信息) 6.Flags 启动另一个Activity 例Urlurl=Url.parse("smsto://08000000123"); Intentintent=newIntent(Intent.ACTION_SENDTO,url); intent.putExtra("sms_body","TheSMStext"); startActivity(intent); 本文转自My_King1 51CTO博客,原文链接:http://blog.51cto.com/apprentice/1360578,如需转载请自行联系原作者

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

Android学习笔记--XML文件解析

MicrosoftInternetExplorer402DocumentNotSpecified7.8Normal0 1.什么是SAX SimpleAPIforXML,既是指一种接口,也是指一个软件包 作为接口,SAX是事件驱动型XML解析的一个标准接口 2.SAX基本原理 SAX的哦给你工作原理简单地说就是对文档进行顺序扫描,当扫描到文档(document)开始与结束,元素(element)开始与结束等地方时通知事件处理函数,由事件处理函数做相应动作,然后继续同样的扫描,直至文档结束. 大多数SAX实现都会产生一下类型的事件 { 在文档的开始和结束时出发文档处理事件 在文档内每一XML元素接受解析的前后触发元素事件 任何元数据通常都由氮素的事件交付 在处理文档的DTD或Schema时产生DTD或Schema事件 产生错误事件用来通知主机应用程序解析错误 } 3.SAX常用接口 ContentHandler接口 ContentHandler是java类包中一个特殊的SAX接口,位于org.xml.sax包中.该接口封装了一些对事件处理的方法,当XML解析器开始解析XML输入文档时,它会遇到某些特殊的事件,比如文档的开头和结束,元素的开头和结束,以及元素中的字符数据等事件.当遇到这些事件时,XML解析器会调用ContentHandler接口中相应的方法来响应该事件 ContnetHandler接口的方法有以下几种 { VoidstartDocument(); VoidendDocument(); VoidstartElement(Stringuri,StringlocalName,stringqName,Attributesatts) VoidendElement(Stringuri,StringlocalName,StringqName) Voidcharacters(char[]ch,intstart,intlength) } 4.SAX解析 解析文档过程 例:<doc> <para>HelloWorld!</para> </doc> 在解析文档的过程中会产生如下一系列事件 Startdocument { Startelement:doc A:创建事件处理程序 Startelement:para Characters:HelloWorld! B:创建SAX解析器 Endelement:para Endelement:doc C:将事件处理程序分配给解析器 D:对文档进行解析,将每个事件发送给处理程序 Enddocument } 解析样例: 1.声明控件对象(略) 2.获得控件对象(略) 3.绑定事件(略) 4.创建监听器对象 PublicvoidonClick(Viewv){ HttpDownloaderhd=newHttpDownloader(); StringresultStr=hd.download("XMLURL"); System.out.priintln(resultStr); Try { //创建一个SAXParseFactory SAXParserFactoryfactory=SAXParserFactory.newInstance(); XMLReaderreader=factory.newSAXParser().getXMLReader(); //为XMLReader设置内容处理器MyContentHandler reader.setContentHandler(newMyContenHandler()); //开始解析文件字符串构造成reader之后构造成inputSource Reader.parse(newInputSource(newStringReader(resultStr))); }catch(Execptione){ e.printStackTrace(); } } XML文件写法: <wordkers> <workerid="AQ01"> <name>mark</name> <sex>male</sex> <status>manager</status> <address>NewYork</address> <salary>$4000</salary> <workerid="AQ02"> <name>lily</name> <sex>female</sex> <status>assists</status> <address>H</address> <salary>$2000</salary> <workerid="AQ03"> <name>tom</name> <sex>male</sex> <status>manager</status> <address>F</address> <salary>$5000</salary> </wordkers> MyContenHandler的写法例: PublicclassMyContenHandlerExtendsDefaultHandler{//此处体现了适配器模式 StringName,Sex,Status,Address,Salary StringtagName; //开始document PublicvoidstartDocument()throwsSAXExecption{ System.out.println("-------begin--------"); } //结束document PublicvoidendDocument()throwsSAXExecption{ System.out.println("-------end--------"); } //开始节点对象 PublicvoidstartElement(StringnamespaceURI,StringlocalName,StringqName,Attributesattr)throwsSAXExecption{ tagName=localName; If(localName.equals("worker")){ //获取标签的全部属性 For(inti=0;i<attr.getLength();i++){ System.out.println(attr.getLocalName(i)+"="+attr.getValue(i)) } } } //结束节点对象 PublicvoidendElement(StringnamespaceURI,StringlocalName,StringqName)throwsSAXExecption{ //在一个标签解析完之后,打印所有标签的信息 If(localNmae.equals("worder")){ This.printout(); } } //读取文本对象 Publicvoidcharacters(char[]ch,intstart,intlength)throwsSAXExecption{ If(tagNmae.equals("name")) Hisname=newString(ch,start,length); Elseif(tagNmae.equals("sex")) Sex=newString(ch,start,length); Elseif(tagNmae.equals("status")) Status=newString(ch,start,length); Elseif(tagNmae.equals("address")) Address=newString(ch,start,length); Elseif(tagNmae.equals("salary")) Salary=newString(ch,start,length); } //打印读出的信息 Publicvoidprintout(){ System.out.println("name--->"+Name); System.out.println("name--->"+Sex); System.out.println("name--->"+Status); System.out.println("name--->"+Address); System.out.println("name--->"+Salary); } } 本文转自My_King1 51CTO博客,原文链接:http://blog.51cto.com/apprentice/1360566,如需转载请自行联系原作者

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

Linux日志管理学习

1、日志介绍 日志记录了系统每天发生的各种事情,可以通过它检查错误发生的原因,或者受到攻击留下的痕迹。为了便于管理日志通常存放在/var/log/下,一部分程序公用一个日志文件,一部分程序使用单个的日志文件,有些大型服务程序日志文件较多,会建立相应的子目录来存放日志文件。 2、日志类型 /var/log/secure:系统安装日志,文本格式,应周期性分析 /var/log/btmp:当前系统上,用户的失败尝试登录相关的日 志信息,二进制格式,lastb命令进行查看 /var/log/wtmp:当前系统上,用户正常登录系统的相关日志 信息,二进制格式,last命令可以查看 /var/log/lastlog:每一个用户最近一次的登录信息,二进制格 式,lastlog命令可以查看 /var/log/dmesg:系统引导过程中的日志信息,文本格式 文本查看工具查看 专用命令dmesg查看 /var/log/messages :系统中大部分的信息 /var/log/anaconda : anaconda的日志(centos6没有) 3、日志配置 Redhat5 服务名: syslog 配置文件:/etc/syslog.conf C/S架构:通过TCP或UDP协议的服务完成日志记录传送, 将分布在不同主机的日志实现集中管理 事件记录格式:日期时间 主机 进程[pid]: 事件内容 centos6 7 服务名:rsyslog 特性:多路工作模块,通过UDP, TCP, SSL, TLS, RELP协议的服务完成日志记录传送, 将分布在不同主机的日志实现集中管理 ,自定义输出格式,关系型数据库实现日志存储 配置文件:/etc/rsyslog.conf,/etc/rsyslog.d/*.conf 库文件: /lib64/rsyslog/*.so 配置文件格式:由三部分组成 MODULES:相关模块配置 GLOBAL DIRECTIVES:全局配置 RULES:日志记录相关的规则配置 RULES配置格式: facility.priority; facility.priority… target facility: 设施,从功能或程序上对日志进行归类 auth, authpriv, cron, daemon,ftp,kern, lpr, mail, news, security(auth), user, uucp, local0-local7, syslog priority: 优先级别,从低到高排序 debug, info, notice, warn(warning), err(error), crit(critical), alert, emerg(panic) *: 所有级别 none:没有级别,即不记录 PRIORITY:指定级别(含)以上的所有级别 =PRIORITY:仅记录指定级别的日志信息 target: 文件路径:通常在/var/log/,文件路径前的-表示异步写入 用户:将日志事件通知给指定的用户,* 表示登录的所有用户 日志服务器:@host,把日志送往至指定的远程服务器记录 管道: | COMMAND,转发给其它命令处理 例: 5、日志管理 Systemd 统一管理所有 Unit 的启动日志。带来的好处就是 ,可以只用journalctl一个命令,查看所有日志(内核日志和 应用日志)。日志的配置文件是etc/systemd/journald.conf 查看所有日志(默认情况下 ,只保存本次启动的日志) journalctl 查看内核日志(不显示应用日志) journalctl -k 查看系统本次启动的日志 journalctl -b journalctl -b -0 查看上一次启动的日志(需更改设置) journalctl -b -1 日志默认分页输出,--no-pager 改为正常的标准输出 journalctl --no-pager 6、日志滚动或者日志转储 日志长期记录会形成一个很大的文件,对于查找信息很不方便,所以在配置文件/etc/logrotate.conf中设定达到一定大小或者每隔一定时间生成新的日志文件,称为日志转储,旧的文件通常以日志名+日期的格式存储,可以在配置文件自定义。

资源下载

更多资源
Mario

Mario

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

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等操作系统。

WebStorm

WebStorm

WebStorm 是jetbrains公司旗下一款JavaScript 开发工具。目前已经被广大中国JS开发者誉为“Web前端开发神器”、“最强大的HTML5编辑器”、“最智能的JavaScript IDE”等。与IntelliJ IDEA同源,继承了IntelliJ IDEA强大的JS部分的功能。

用户登录
用户注册