首页 文章 精选 留言 我的

精选列表

搜索[程序设计],共1339篇文章
优秀的个人博客,低调大师

Python 面向对象程序设计

类的设计 方法优先的原则, 在__init__方法中创建出需要的属性, 对于基类来说, 只进行默认值得初始化, 0, None等, 对于真正需要使用的子类, __init__方法则是进行我们需要的初始化, 不在基类中进行初始化就与Java中的构造方法不能继承是一样的了, 要在子类中初始化所有的属性, 还可以提供方便的代码提示(在PyCharm中) 属于类的属性称之为类成员变量, 对于类成员的初始化, 如果简单的初始化则直接赋值, 如果是复杂的初始化就采用函数方式, 此方法类似于Java中的静态代码块, 用于加载图片音乐 等静态资源 在第一点中提到了基类, 该基类不能直接拿来用, 但是在Python有没有Java中的接口或者抽象类, 在编译的时候就会报错, 在Python中要解决这个问题可以通过命名的方法人为的判断, 使用形容或者Base开头的类表示不要直接使用该类 对于常量, 定义一个专门的类来存放常量, 将常量作为静态的属性(大写), 或者直接定义在模块中

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

Spark SQL程序设计(2)

读取JSON数据 {"age":"45","gender":"M","occupation":"7","userID":"4","zipcode":"02460"} {"age":"1","gender":"F","occupation":"10","userID":"1","zipcode":"48067"} scala> val jsondf=spark.read.textfile("//user.json") 生成另外一个json文件 scala> josndf.write.mode("overwrite").json("//user2.json") 查看DF scala>userDF.show(4) scala> userDF.printSchema root |-- age: string (nullable = true) |-- gender: string (nullable = true) |-- occupation: string (nullable = true) |-- userID: string (nullable = true) |-- zipcode: string (nullable = true) 修改DF/DS元信息

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

Spark SQL程序设计(1)

Spark SQL编写流程 1. SparkSession对象 封装了spark sql执行环境信息,是所有Spark SQL程序的唯一入口 sparkSession中包含 sparkContext和sqlContext两个对象,不用再自己创建sparkContext 2. 创建DataFrame或Dataset Spark SQL支持各种数据源 3. 在DataFrame或Dataset之上进行transformation和action Spark SQL提供了多种transformation和action函数 4. 返回结果 保存到HDFS中,或直接打印出来 val spark=SparkSession.build .master("local") .appName("appName") .getOrCreate() // 注意,后面所有程序片段总的spark变量均值SparkSession // 将RDD隐式转换为DataFrame import spark.implicits._ DataFrame与Dataset 1. DataFrame=Dataset[Row] row表示一行数据,例如Row=["1",23,44] RDD /DataFream/Dataset 之间可以相互转化 2. DataFream 内部数据无类型统一为row DataFream是一种特殊的Dataset 3. Dataset 内部数据有类型,需要用户自己设定 Spark SQL数据源 RDD->DataFrame:反射方式 1.定义case class ,作为RDD的schema 2. 直接通过RDD.toDF,将RDD转为DataFream import org.apache.spark.sql.SparkSession import org.apache.spark.sql.Row case class User(userID:Long,gennder:String, age: Int, occupation: String, zipcode: String) val userRdd=sc.textFile("//") val userRDD=usrRdd.map(_.split("::")).map(p=>User(p(0).ToLong,p(1).ToStringp(2).toInt, p(3), p(4))) val userDF=userRDD.toDF() userDF.count() json->DataFrame val userjson=spark.read.format("json").load("//user.json") //一行json数据要在一行 userjson.take(10) val userjson=spark.read.json("") userjson.take(10) text->DataSet val userDS=spark.read.textFile("").map(_.split(":")) RDD、DataFrame与Dataset的关系 val ds = df.as[Person] // DataFrame -> Dataset val df2 = ds.toDF() / Dataset -> DataFrame val rdd1 = ds.rdd // Dataset -> RDD val rdd2 = df.rdd // DataFrame -> RDD

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

《.Ne框架程序设计》随记(3)

以往,每个应用程序进程都有自己的虚拟地址空间,通过地址空间的隔离来保证一个进程不会干扰另一个进程的运行。但通过验证托管代码,可以确保不会访问不该访问的内存,因此可以一个单独的虚拟地址空间内运行多个托管应用程序。由于太多的进程会占用过多的系统资源,损伤系统性能,并限制系统可用的资源。因此在一个进程中运行多个托管应用程序可以减少进程的数量,提高系统性能,降低资源需求,而同时应用程序仍然可以保持良好的健壮性。 CLR中,一个托管应用程序叫一个应用程序域(AppDomain)。默认地,一个托管exe仅仅执行在它自己拥有的地址空间中(这个地址空间只含有一个应用程序域),但CLR 的宿主进程(如IIS服务器等)可以决定在一个操作系统进程中运行多个应用程序域。 .net framework提供了一组丰富的类库(FCL),其中含有几千个类型的定义。CLR 和FCL使开发者可以创建以下应用程序:(1)XML Web服务;(2)Web窗体;(3)windows窗体;(4)控制台应用程序;(5)windows服务:windows服务控制管理器(SCM)控制的服务程序;(6)组件库; CLR支持三种互操作: (1) 托管代码调用DLL中的非托管函数。托管代码可以使用一种叫P/Invoke(就是平台调用)的机制来调用DLL中的函数。实际上,许多FCL中定义的类型内部都调用了从Kernel32.dll,User32.dll等DLL中导出的函数。例如,C#程序可以调用从Kernel32.dll中导出的CreateSemaphore函数。 (2) 托管代码使用现存的COM组件(非托管组件作为COM服务器)。利用现有的COM组件的类型库,我们可以创建出描述它们的托管程序集,托管代码可以象访问其他托管代码一样访问这些托管程序集中的类型。有时候没有类型库,我们可以在代码中创建自己的类型,CLR可以用这些类型进行正确的互操作,例如,可以在C# 应用程序中使用DirectX COM 组件。 (3) 非托管代码使用托管类型(托管类型作为COM服务器)。许多现存的非托管代码都需要提供COM组件才能正常运行。而用托管代码来实现这些组件更容易,因为这样可以避免处理引用计数和COM接口。例如,可以用C#来创建ActiveX控件或者shell扩展程序。 #include <stdio.h> #include <mscorlib.dll> using namespace System; void main() { printf("Hello,"); Console::WriteLine("World!"); } 在安装新的应用程序时却损坏了现有的应用程序,这叫“Dll hell”.现在大多数应用程序的安装都会影响系统的各个部分。例如,会复制许多文件到许多目录中,更新注册表设置,安装快捷键到桌面,开始菜单和快速启动中。这就是备份应用程序比较困难,因为必须复制所有的文件和相关的注册表内容,而要将应用程序移植到另外一抬机器也很困难,必须 重新安装。最后,卸载应用程序也很麻烦。.net framework使组件不再需要象COM那样在注册表中进行注册。它还包含了一个叫代码访问安全的安全模型,这是基于程序集的标识来控制的。 一个托管PE文件包含4部分:PE表头,CLR表头,元数据和IL代码。PE表头是系统要求的标准信息。CLR表头专用于那些需要CLR 才能运行的模块(托管模块)。CLR表头中包含和模块一起创建的元数据的主版本号和次版本号,一些标记,若模块是CUI或GUI,可执行文件还有一个标识入口点方法的MethodDef标记,以及一个可选的强命名数字签名。该表头还包括模块内某些元数据表的大小和偏移量。 元数据实际是一块二进制数据,其中包含一些表,可以分为3类:定义表,引用表,清单表。程序集中包含了一个文件用于保存清单(manifest).清单是另外一组元数据的集合,其中主要包含了程序集中一部分文件的名称,还描述了程序集的版本,语言文化,发布者,公有导出类型,以及组成程序集的所有文件。CLR总是先加载包含清单元数据的文件,然后利用该清单来获取程序集中的其他文件。程序集的特性:1)定义了可重用的类型。2)程序集标识有一个版本号。3)可以包含与之相关的安全信息。 可以在应用程序的配置文件中指定一个codeBase元素来配置程序需要下载的程序集文件。codeBase元素标识了一个可以找到程序集所有文件的URL地址。当尝试加载一个程序集的文件时,CLR首先获取codeBase元素的URL地址,然后检查本地机器的下载缓存看是否已经存在该文件,若存在,该文件就被加载,否则,CLR将codeBase元素的URL地址中将该文件下载到缓存,若找不到该文件,CLR将在运行时抛出FileNoFoundException异常。 程序集是一个可重用,可实施版本策略和安全策略的单元,它允许我们将类型和资源划分到不同的文件中,这样程序集的使用者就可以决定将哪些文件打包在一起部署,一旦CLR加载了程序集中包含清单的那个文件,就可以确定程序集的其他文件中包含了程序正在引用的类型和资源,任何程序集的使用者只需要知道包含清单的文件名称,文件的划分对使用者是透明的,并且可以在将来改变,同时又不会破坏现有应用程序的行为。 对于可执行应用程序(exe),配置文件必须位于应用程序的基目录中,并且它的名字必须是exe文件名再加.config扩展名。对于asp.net web窗体和xml web服务应用程序,配置文件必须位于 web应用程序的虚拟根目录下,并且名称总是web.config.另外,子目录也可以包含它们自己的web.config文件,并继承上一目录的配置设置。配置设置可以用于特定的应用程序,也可以用于整个机器。 强命名程序集有一个发布者的公钥/私钥对签名,其中公钥/私钥对唯一地标识了程序集的发布者,利用公钥/私钥对,我们可以对程序集进行唯一的标识,实施安全策略和版本策略。一个程序集有两种部署方式:私有方式和全局方式。私有方式将程序集部署在应用程序的基目录及其子目录下。弱命名程序集只能够进行私有部署。全局方式将程序集部署在一些CLR确知的地方,当CLR搜索程序集时,它就到这些地方去找。强命名程序集即可以进行私有部署,也可以进行全局部署。一个强命名程序集包含四个唯一标识程序集的特性:文件名(没有扩展名),版本号,语言文化标识,和一个公有密钥标记(由公有密钥产生的一个值)。若想唯一标识一个程序集,就必须首先获取一个公钥/私钥对,再将公钥/私钥对与程序集相关联。 CLR能够将名称相同但路径不同的多个文件加载到同一个地址空间,这叫“并存执行”,这是解决”Dell hell”的一个关键技术。在解析一个被引用的类型时,CLR可以在下面三个地方之一找到该类型:(1)同一个文件。对同一个文件中类型的访问在编译时就确定了。CLR直接从该文件中加载被引用的类型。(2)不同的文件,相同的程序集。(3)不同的文件,不同的程序集。当被引用的类型在一个不同的程序集文件中时,CLR会首先加载包含被引用程序集的清单所在的文件。若该文件没有包含需要的类型,CLR则会根据此清单文件加载适当的文件. 本文转自Phinecos(洞庭散人)博客园博客,原文链接:http://www.cnblogs.com/phinecos/archive/2006/09/01/491831.html,如需转载请自行联系原作者

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

《Android程序设计》一3.5 Resources

3.5 Resources Android应用把图像、图标和用户界面布局文件都放在名为res的目录中。res目录通常至少包括4个子目录,如下所示:layout包含Android用户界面XML文件,这个文件将在第7章详细介绍。drawable包含绘制相关的工具,如之前所描述的应用图标。raw保存了应用执行时可能以stream(流)方式读取的文件。原始文件是为运行的应用提供调试信息的一种很好的方式,不需要访问网络来检索数据。values包含应用在执行中要读取的值,或应用在某些使用中的静态数据,如对UI字符串的国际化。应用通过方法Context.getResour ces()和类R来访问这些目录下的资源。要访问res目录下的数据,传统的Java开发人员可能会考虑编写代码构建相关的资源文件路径,然后使用文件API打开这些资源。加载完资源字节

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

C++程序设计基础(2)变量

注:读《程序员面试笔记》笔记总结 1.知识点 (1)C++变量命名只能包含字母、数字、下划线,其中开头不能是数字;大小写敏感;习惯上变量用小写字母,常量、宏定义用大写字母。 (2)变量的作用域分为局部变量(函数内部定义),全局变量(函数外部定义)。 (3)关键字extern:在头文件总声明变量,并在前面加上extern,在源文件中定义变量,其他文件使用#include导入头文件,即可使用该变量。附详细链接https://blog.csdn.net/chenqiai0/article/details/8490665 1 //test.h 2 extern int age; 3 //test.cpp 4 #include"test.h" 5 int age = 10; //直接使用age=10是不行的 6 //test1.cpp 7 #include"test.h" 8 int main(int argc, char *argv[]) { 9 cout << age << endl; 10 getchar(); 11 return 0; 12 } 13 14 /*output 15 10 16 */ (4)关键字static:静态变量,首次执行时初始化,其后再执行将不再进行初始化,虽然可能是局部变量,但其生命周期是整个程序运行过程。 (5)关键字const:常量型变量,在头文件中直接定义和声明(不同于一般全局变量),其他文件通过#include使用(多个文件引用不会造成重复定义),如果在源文件中定义,则其作用域值是本源文件。 2.面试题 2.1简述i++和++i的区别 写出下面代码执行后i,j,m,n的值 1 int i=10,j=10; 2 int m=(i++)+(i++)+(i++); 3 int n=(++j)+(++j)+(++j); 知识点:++i是先自身加一,然后再参与赋值运算,i++是先参与赋值运算,然后再自身加一。 本题的特殊之处是不同的编译器会产生不同的结果,在VC编译器中,全部会先完成三个++j,然后再做加法运算,而在gcc编译器中当有两个操作数时就会进行加法运算。故结果如下: 1 #VC编译器 2 i=13,j=13,m=30,n=39;//13+13+13=39 3 #gcc编译器 4 i=13,j=13,m30,n=37; //12+12+13=37 2.2简述C++的类型转换操作符 在C语言中类型转换只需要通过变量前面加上变量类型,并且转换是双向的,这种方式对于简单类型可以,复杂数据类型就力不从心了。 C++提供了四种类型转换操作符:static_cast,dynamic_cast,const_cast,reinterpret_cast。 (1)static_cast可以完全替代C风格类型转换实现基本类型转换; 1 int i = 1; 2 double d = 1.5; 3 int d2i = static_cast<int>(d); 4 double i2d = static_cast<double>(i); 同时相关类(如父子关系)可以完成转换,但是如果父类指针本身指向父类对象,不存在安全问题,如果父类指针本身指向子类对象,则不存在安全问题; 1 class Base {}; 2 class Derived:public Base{}; 3 Base *b1 = new Base; //父类指针指向父类对象 4 Base *b2 = new Derived; //父类指针指向子类对象 5 Derived *b2d1 = static_cast<Derived *>(b1); //转换成功(不安全) 6 Derived *b2d2 = static_cast<Derived *>(b2); //转换成功(安全) (2)dynamic_cast:只能进行对象指针之间的转;转换结果可以使指针也可以是引用;转换时会进行类型检查(static_cast不会进行检查);只有当父类指针指向一个子类对象,并且父类中包含了虚函数,转换才会成功,否则返回空指针,引用的话抛出异常。 1 class Base { virtual void dummy() {}; }; 2 class Drived : public Base{}; 3 Base *b1 = new Base; 4 Base *b2 = new Drived;//父类指针指向子类对象,且父类中包含虚函数 5 //转换结果为指针 6 Drived *b2d1 = dynamic_cast<Drived*>(b1);//转换失败(返回NULL) 7 Drived *b2d2 = dynamic_cast<Drived*>(b2);//转换成功 8 //转换结果为引用 9 Drived &b2d3 = dynamic_cast<Drived &>(*b1);//转换失败(抛出异常) 10 Drived &b2d4 = dynamic_cast<Drived &>(*b2);//转换成功 (3)const_cast:可以在转换过程中增加或删除const属性。一般情况下,无法将常量指针直接赋值给普通指针,但通过const_cast可以移除常量指针的const属性,从而实现const指针到非const指针的转换。 1 class Test{}; 2 const Test *t1 = new Test; 3 Test *t2 = const_cast<Test *>(t1); (4)reinterpret_cast:可以将一种类型的指针直接转换成另一种类型的指针,无论两个类型之间是否有继承关系。此外还可以吧一个指针转换为一个整数,也可以把一个整数转换成一个指针。另外还经常用在不同函数指针之间的转换。 1 class A{}; 2 class B{}; 3 A *a = new A; 4 B *b = reinterpret_cast<B *>(a); //转换成功 2.3简述静态全局变量的概念 (1)在全局变量前面加上static关键字就成为的静态全局变量。 (2)静态全局变量通常在源文件中声明定义,作用域为本文件,(而全局变量一般头文件声明,源文件定义,通过extern关键字,其作用域为整个工程。) (3)如果在头文件中声明了静态全局变量,那么即使在没有初始化的情况下,也会被初始化为默认值,即相当于也被定义了,这时其他文件#include该头文件,相当于拷贝了一份,其初始值相同,后面各个文件中将互相不影响。 下面是静态全局变量的一个例子: 1 static int sgn;//声明定义静态全局变量 2 void increaseSG() { sgn++; } 3 int main(){ 4 sgn = 10; 5 cout << sgn << endl; 6 increaseSG(); 7 cout << sgn << endl; 8 getchar(); 9 return 0; 10 }

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

华文慕课Java程序设计笔记

对象的自动清除 对象回收是由垃圾回收线程负责 System.gc()方法可以要求系统进行垃圾回收,仅仅是建议系统 java没有“析构方法”,但Object的finalize()有类似方法 系统在回收时会自动调用对象的finalize()方法 protected void finalize() throws Throwable{} 子类的finalize方法可以在里面释放系统资源,一般来说,子类的finalize方法中应该调用父类的finalize方法。 内部类与匿名类 内部类 定义在一个类的内部 使用分为内部使用和外部使用 内部类总可以直接访问外部类的字段及放啊 内部类总访问外部类的字段可以用“外部类名.this.字段”的方式 用static修饰内部类,表明该内部类实际是一种外部类 因为它与外部类的实例无关 有人认为static的类是嵌套类,不是内部类 内部类的使用 匿名类 它没有类名,在定义类的同时就生成该对象的一个实例,不取名字,直接用父类或接口的名字 一次性使用的类 例子: new Handler(){ ... } 局部类 同局部变量一样,方法中的内部类 不能用public,private,protected,static修饰 但可以被final,abstract修饰 可以访问器外部类的成员 不能够访问该方法的局部变量,除非是final局部变量。 Lambda表达式 基本写法 (参数) -> 结果 例子: (String s) -> s.lenth(); x -> x*x; () -> {System.out.println("aaa")} 大体上相当于其它语言的”匿名函数”或”函数指针” 在java中它实际上是“匿名类的一个实例” 装箱 基本类型的包装类 它将基本类型包装成Object integer i = new Integer(10); Integer i=10; 实际为:Integer i=Integer.valueOf(10); 拆箱 int a=i; 实际为:a=i.intValue(); 枚举 可以在enum定义体中,添加字段,方法,构造方法 image 注解 又称为注记,标记,标记,注释 是在各种语法要素上加上附加信息,以供编译器或其他程序使用 常用注解: @Override 表示覆盖父类的方法 @Deprecated 表示过时的方法 @SuppressWarnings 标识让编译器不产生警告 引用与指针 引用实质就是指针 但是它是受控的,安全的 比如: 会检查空指引 没有指针运算 不能访问没有引用到的内存 自动回收垃圾 (1) 指针 》引用类型,引用本身就相当于指针,可以用来修改对象的属性,调用对象的方法 (2)指针运算 》数组 (3)函数指针 》接口,lambda表达式 (4)指向结点的指针 》对象的引用 (5)使用JNI java Native interface 它允许java代码和其他语言写的代码进行交互 基本类型的相等 基本类型: 数值类型:转换后比较 浮点数,最好不直接用== Double.NAN==Double.NAN结果为false boolean型无法与int比较 注 valueOf() -128到127会有缓存,超过的话就没有缓存了 枚举类型 内部进行了唯一实例化,可以直接判断 引用对象 “==”是直接看两个引用是否一样 如果要判断内容是否一样,则要重写equals方法 如果重写equals方法,则最好重写hashCode方法,因为一般以内容的hashCode作为唯一性标志 [图片上传失败...(image-845e09-1522336106762)] String对象的特殊性 判断对象,一定不要用==,要用equals 但是字符串变量及字符串常量会进行内部化,相同的字符串常量是==的 String对象的特殊性 异常 异常又称为例外,差错 对应着java运行错误处理机制 基本写法: try{ 语句组 }catch(Exception ex){ 异常处理语句组; } java中处理异常 抛出异常 运行时系统在调用栈中查找:从生成异常的方法开始进行回溯,直到找到 捕获异常的代码 异常的分类 Throwable Error:JVM错误 Exception 多异常的处理 子类异常要排在父类异常的前面 finally语句 无论有无异常,都会执行处理语句 受检的异常 Exception分两种 RuntimeException及其子类,可以不明确处理 否则,称为受检的异常,受检的异常,要求明确进行语法处理,要么捕获,要么抛出异常 自定义异常 创建用户自定义异常类 继承自Exception类或某个子Exception类 定义属性和方法,或重载父类的方法 对于异常,不仅要进行捕获处理,有时候还需要将异常进一步传给调用者,一变让调用者也能感受到这种异常,这是可以在catch语句块或finally 语句块中采取以下三种方式: 将当前捕获的异常再次抛出 重新生成一个异常,并抛出 重新生成一个新异常,该异常中包含了当前异常的信息,如throw new Exception (“some message “,e) 断言及程序的调试 断言 assert 表达式 assert 表达式,信息 在调试程序时,如果表达式不为true,则程序会产生异常,并输出相关的错误信息 例 assert hypotenuse(3,4)==5:”算法不正确”; 它起到对程序的检测作用 编译及运行 只有在JDK1.4及以上的版本才可以使用断言 在运行时,要使assert起作用,则在运行时,使用选项(-ea ,即-enableassetions) 如 java -ea - classpath.Assertion 程序的测试及Junit 在编写程序代码的同时,还编写测试代码来判断这些程序是否正确,这个过程称为“测试驱动”的开发过程 在java的测试过程,经常使用Junit框架 测试函数 @Test来标注测试函数 fail(info) :表示信息出错 assertEqauls(arg1,arg2):表示程序要保证两个参数相等 assertNull(arg):表示参数要为null 程序的调试 语法错误(Syntax error):编辑,编译器发现 运行错误(Runtime error):异常处理机制 逻辑错误(Logic error):调式(debug),单元测试(unit test) 程序的调试 在IDE中,项目中点右键,debug as 进入到调试视图(debug perspective) 调试的手段 断点(breakpoint) 跟踪(trace) 监视(watch) 在很有可能有错误的地方设置断点,然后跟踪 java基础类库 java.lang core java.util java.io java.awt java.net java.sql Object类 Object类是所有类的直接或间接父类 让所有的类有了一致性 equals() ==是引用相等,equals是内容相等 如果覆盖equals方法,一般也要覆盖hashcode方法 getClass()方法是final方法,它返回一个对象在运行时所对应的标识 toString返回对象的字符串表示 finalize用于在垃圾收集前清除对象 notify(),notifyAll(),wait()线程相关 System类 System.getProperty(String name)获取特定的系统属性值 线程 进程:一个程序的运行 线程:程序中单个顺序的流控制称为线程 一个进程中可以含有多个线程 一个进程中的多个线程 特点 分享CPU(并发的或以时间片的方式) 共享内存 线程体 — run()方法来实现的 线程启动后,系统就自动调用run()方法 使用 通过继承Thread类 通过向Thread()构造方法传递Runnable对象 可用匿名类实现Runnable或用lambda表达式 线程池封装

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

JavaScript高级程序设计基本概念

ECMAscript到底是什么?它和JavaScript的关系?(这个概念我也是百度的) 要讲清楚这个问题,需要回顾历史。1996年11月,JavaScript的创造者Netscape公司,决定将JavaScript提交给国际标准化组织ECMA,希望这种语言能够成为国际标准。次年,ECMA发布262号标准文件(ECMA-262)的第一版,规定了浏览器脚本语言的标准,并将这种语言成为ECMAScript,这个版本就是1.0版。 该标准从一开始就是针对JavaScript语言制定的,但之所以不叫JavaScript,有两个原因。一是商标,Java是Sun公司的商标,根据授权协议,只有Netscape公司可以合法地使用JavaScript这个名字,且JavaScript本身也已经被Netscape公司注册为商标。二是想体现这门语言的制定者是ECMA,不是Netscape,这样有利于保证这门语言的开放性和中立性。 因此,ECMAScript和JavaScript的关系是,前者是后者的规格(标准),后者是前者的一种实现(另外的ECMAScript方言还有Jscript和 ActionScript)。在日常场合,这两个词是可以互换的。 如果通过<script>元素包涵外部javascr文件,那么src属性是必须的。 把javascript 插入到html中要使用<script> 异步脚本: async属性 的目的是为了不让页面等待两个脚本下载和执行,从而一部加载页面的其他内容,异步脚本一定会在页面的load事件前执行。 可以表示当前脚本不用等待其他脚本,也不必阻塞文档呈现,但不能保证异步脚本按照他们在 页面中出现的顺序执行 <script type="text/javascript"><![CDATA[ function compare(a,b) { } ]]></script> CData片段事文档中的一个特殊区域 这个区域可以包含不需要解析任意格式的文本内容,所以在CData片段中就可以使用任何字符--小于号当然也是 可以的,而且不会有语法错误 如果在不兼容xhtml的浏览器中 不支持CData片段就就可以用//来注释掉 在不支持<script>的浏览器中 可以选择<!--//-->来隐藏掉 <script><!-- function sayHi() { alert("hi!"); } //--></script> 不过现在所有的浏览器都已经支持javascript 所以 就没再必要使用这种格式了 文档模式也都是必备的 如: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 就是过渡型 <body> <noscript> <p>本网页需要浏览器支持(启用)javascript </noscript> </body> 当浏览器不支持脚本,或者浏览器支持脚本,但是脚本被禁用的时候 会显示<noscript>中的信息 需要注意的是: 在包含外部javascript文件时,必须将src属性设置为指向相应文件的URL 所有<script>元素都是按照他们再页面中出现的先后顺序依次被解析。在没有defer和async属性的情况下,只有在解析玩前面的<script>元素中的代码之后,才会解析后面<script>元素中的代码. <script>引用外部js文件时,必须是<script ...></script>标记格式,不要采取省略形式。 现代的web应用程序一般把全部javascript引用都放在<body>元素中页面内容的后面,因为代码都是从上往下解析的,如果javascript引用放在head 则网页出现空白页面的时间增长 延迟脚本: defer是延迟脚本的属性 设置defer=“defer” 是为了让脚本延迟到整个页面都解析完毕后运行,意思就是相当于告诉浏览器立即下载,但延迟执行。 延迟脚本总是按照他们的顺序执行 最好只包含一个延迟脚本 还有defer属性只适用于外部脚本文件。 <noscript>可以指定在不支持脚本的浏览器中显示的替代内容 ,但是启动了脚本的情况下,浏览器不会显示<script>元素中的任何内容 区分大小写的 标识符的第一个字符必须是字母.下划线或者$符号 采用驼峰大小写格式,也就是第一个字母小写,剩下的每个单词的首字母大写 不能把关键字,保留字,true,false和null作为标识符 单行注释// 多行注释/**/ 语句结尾的分号虽然不是必需的,但是建议不要忽略它 在控制语句中使用代码快可以使编程意图更加清晰 比如 if(test){ alert("sdf"); } 变量是松散类型 意思就是 定义变量时使用var操作符 var message="hi"; 可以 message=10; 有效但是不推荐 还有var定义的是局部变量 比如在一个函数中用var定义了一个变量,那么这个变量在函数退出后就会被销毁 如果 在一个函数中省略var 定义了一个变量 则这个变量就是全局变量 只要调用一次函数 这个变量就有了定义,就可以在函数外部的任何地方被访问到. 但是不推荐,因为在局部作用域定义的全局变量很难维护 可以用一条语句定义多个变量.如: var message="hi", found=false, age=29; 定义并初始化了三个变量,因为是松散类型,所以 使用不同类型初始化变量的操作可以放在一条语句来完成. 数据类型有 Undefined ,Null,Boolean,Number,String和一种复杂的数据类型--Object typeof是负责检测给定变量的数据类型 对一个值使用typeof可能返回下列字符串 undefined---这个值未定义 使用var声明变量,但是未对其加以初始化时,这个变量的值就是undefined boolean---布尔值 string---字符串 number---数值 object---对象或者null function---函数 举个例子 var message="some string"; alert(typeof(message)); //string alert(typeof 95); //number typeof是一个操作符,所以例子中的圆括号尽管可以使用,但不是必需的. var car=null; alert(typeof car) //"object" 如果定义的变量准备在将来存放对象,那么最好将该变量初始化为null而不是其他值 还有实际上 undefined值派生自null值,所以 alert(null==undefined) //true 虽然null和undefined有这样的关系 但是无论什么情况下都没有必要将一个变量的值显示设置为undefined 但是 只要意在保存对象的变量还有没真正保存对象,就应该明确让该变量保存null值 还有boolean是将其他类型的值转化为一个Boolean值 比如空字符串转化为false 数值0转化为false 还有if的控制语句会自动执行相应的Boolean Number可以保存+0和-0并且两者被认为是相等的 var floatNum1=1. //小数点后面没有数字,解析为1 var floatNum2=10.0 //整数, 解析为10 var floatNum3=3.125e7 //等于31250000 0.0000003 转化为3e-7 数值的范围: 数值的范围超过了javascript数值范围的值 会被自动转换为特殊的Infinity值 如果是负数就会被转换为-Infinity 正数就会被转换为Infinity 可以用isFinite() 会返回一个Boolean值 NaN 是一个特殊的数值 , 数值的转换: 数值转换用Number()可以用于任何数据类型 如果是Boolean 则true 和false转换为1和0 如果是数字值,则简单的传入和返回 如果是null值,返回0 如果是undefind 返回NaN 如果是字符串 将其转换为十进制数值 如"123"变成123 "011"转换为11 如果字符串包含有效的浮点格式"1.1" 则将其转换为对应的浮点数值 (同样会忽略前导0) 如果字符串是空,将其转换为0 举几个例子: var num1=Number("sdf"); //NaN 因为不包涵任何有意义的数字值 var num2=Numebr(""); //0 var num3=Number("00011") //11 var num4=Number(true) //1 parseInt()和parseFloat()是专门用于把字符串转化为数值的 parseInt()经常用于处理整数 例子 : var num1=parseInt("1234blue"); //1234 因为不包涵任何有意义的数字值 var num2=parseInt(""); //NaN var num1=parseInt("22.2"); //22 var num1=parseInt("70"); //70 var num3=parseInt("0xAF",16); // 175 指明转换的基数很重要 所以什么情况下都要明确指定的基数 多数情况下 我们要解析的都是十进制数值,所以始终将10作为第二个参数是很必需的. parseFloat() 字符串中的第一个小数点是有效的,第二个是无效的,因此他后面的字符串会被忽略 "22.34.45" 转换为22.34 parseFloat和parseInt的还有区别是 它始终忽略掉前面的0 比如"045.1" 转换为45.1 string类型:可以“” 或者‘’但是必须得匹配 字符字面量:也叫做转义序列 \n表示换行 \t表示制表 \b表示空格 \r表示回车 \\表示斜杠 \‘表示单引号 \"表示双引号 任何字符串的长度都可以通过访问其length属性取得 比如 var text=“sdfsadf” alert(text.length); 字符串可以通过直接相加来实现拼接 转化为字符串: 通常toString()方法 var age=11; var ageAsString=age.toString(); //字符串11 var found=true; var foundAsString=found.toString(); //字符串“true” 但是null和undefined没有这个方法 调用数值的tostring()时候可以传参 ,默认返回是10进制的字符串,可以添加基数,来输出任意有效进制的数 var num=10; alert(num.toString(2));// "1010" toString()方法遵循下面规则 1.如果值有tostring()方法,则调用该方法返回相应的结果 2.如果是null,则返回“null” 3.如果是undefined,则返回“undefined”; Object: 创建Object: var o=new Object(); Object的每个实例都具有下列属性和方法 1.Object()保存着用于创建当前对象的函数 2.hasOwnProperty 用于检测给定的属性在当前对象实例中是否存在。其中作为参数的属性名,必须以字符串形式指定 例如o.hasOwnProperty("name"); 3.isPrototypeOf(object)用于检测传入的对象是否是传入对象的原型/ 4.propertyIsEnumerable 用来检测给定的属性是否能够使用for-in语句来枚举 ,作为参数的属性名必须以字符串的形式指定 5.toLocaleString()返回对象的字符串表示,该字符串和执行环境的地区对应 6.toString()返回对象的字符串表示 7.valueOf() 返回对象的字符串。数值或者布尔值表示。通常与toString()的返回值相同。 valueOf():返回最适合该对象类型的原始值; toString(): 将该对象的原始值以字符串形式返回。 Object是所有对象的基础,所以,所有对象都具有这些基本的属性和方法 但是BOM和DOM中的对象属于寄主对象,他们是由寄主实现提供和定义的。而ECMA-262不负责定义寄主对象,所有寄主对象可能会也可能不会继承Object; 操作符: 一元递增递减操作符:++;前置和后置和c语言的效果一样 不仅适用于整数,还可以用于字符串布尔值和浮点数值和对象,都遵循下面规则: 1.在应用于一个包涵有效数字字符的字符串时,先将其转化为数字值,然后在执行加减操作 2.在应用于一个不包涵有效数字字符的字符串时,将变量的值设置为NaN 3.布尔值时先转化为1或者0再执行加减操作,布尔值变量变成数值变量 4.应用于对象时,先调用对象的valueof()方法已取得一个可操作的数值,然后对该值进行上述规则 举例子: var s1=“2”; var s2="z"; var b=false; var f=1.1; var o= { valueOf:function(){ return -1; } } s1++; //变成数值3; s1++; //变成NaN; b++; //变成数值1; f--; //变成数值0.100000000000009 o-- //变成数值-2; 一元加和减操作符: var num=23; num=+num; //实际还是23 如果是对非数值应用一元加操作符 则会像Numebr函数一样 比如 var s1="01"; var s2="1.1"; var s3="z"; var b=false; var f=1.1; s1=+s1; //1 s2=+s2; //1.1 s3=+s3; //NaN b=+b; //0 f=+f; //任然是1.1 一元减操作符主要用于表示负数 例如 将1转换为-1 var num=23; num=-num; // -23 若是用于非数值 按照一元加操作符的相同规则,然后将得到的数值转换为负数 位操作符: 1.按位非~ 2.按位与& 3.按位或| 4.按位异或^ 5.左移 << 左移不会影响操作数的符号位 6.有符号的右移 7.无符号的右移 布尔操作符 1.非 ! 2.与 && 是一个短路操作 如果第一个操作数是false 则第二个操作数是什么值,结果都不会是true var found=true; var result=(found&&somUndefind); //会报错 因为第二个操作数没有声明 alert(result);这一行不会被执行 var found=false; var result=(found&&somUndefind); //不会发生错误 alert(result);会执行(“false”) 因为第一个操作符是false 意味着结果必定是false 根本用不着再对&&右侧的操作数求值了 3.逻辑或 也是短路操作 var result=true || false; 我们可以利用逻辑或的这一行为来避免为变量赋null或者undefined 例如 var myobject=preferredObject||someUndefinedVariable 在这个例子中 变量preferredObject优先赋值给myObject。 someUndefinedVariable负责在preferredObject中不包含有效值的情况下提供后备值 意思就是preferredObject不是null他的值会被赋值给myobject。如果是null,则将someUndefinedVariable的值赋值给myObject。以后的赋值语句经常 会使用这种模式。 乘性操作符:乘法和除法,求模% 加性操作符: 加法:注意 -0加-0结果是-0 +0加-0结果是+0 如果两个都是数值,直接相加 如果俩个操作数都是字符串则直接拼接 如果一个操作数是字符串,则将另一个操作数转换为字符串,然后将两个字符串拼接 如果有一个操作数是对象,数值,布尔值,则调用他们的tostring()方法取得相应的字符串,然后再拼接 有()和无()是两个结果 比如 var num1=5; var num2=10; var message="sdf"+num1+num2; 结果是 sdf510 如果是 var message="sdf"+(num1+num2); 结果是 sdf15 减法:调用number()将其转化为数值然后操作 true变成1 “”变成0 null变成0 “2”变成2 关系操作符: <> <= >= 如果两个操作数都是数值,则执行数值比较 如果两个都是字符串,则比较两个字符串对应的字符编码值 如果一个是数值,则将另一个操作符转换为一个数值,然后进行比较 如果一个操作数是布尔值,则将其转换为数值,然后比较 字符串比较是两个字符串中对应位置的每个字符的字符编码值,大写字母的编码值全部小于小写的 “23”<"3"成立 ,因为比骄傲的是字符编码 “23”<3 错误 因为“23”被转化为了23 “a”<3 “a”>=3 错误,因为“a”被转化为NaN 在与NaN进行比较时,这两个比较操作符都返回了false 相等操作符: 如果有一个操作数时布尔值,则比较前先转换为数值 如果一个操作数是字符串,另一个操作数是数值,则先将字符串转换为数值 如果一个操作数是对象,另一个不是,则调用对象的valueOf方法 规则: null和undefined是相等的 如果有一个操作数是NaN则 返回false 即使两个操作数都是NaN 也返回false 如果连哥哥操作数都是i对象 则比较他们是不是同一个对象,如果两个都指向同一个对象则返回true null==0 false NaN==NaN false 全等操作符=== “55”===55 false 因为不同的数据类型不同 记住 null==undefined 会返回true 但是 null===undefined会返回false因为他们是不同类型 注意:由于相等和不相等操作符存在类型转换问题,为了保持代码中数据类型的完整性,我们推荐使用全等和不全等操作符 条件操作符: 条件?返回1:返回2 赋值操作符*= /= %= += -= <<=左移 >>=有符号右移 >>>=无符号右移 逗号操作符 ,,,表示可以在一条语句中执行多个操作 var num =(3,4,5,6,0) num的值是0 逗号操作符总是会返回表达式中的最后一项 语句: if()语句 if else if else do while()语句 循环至少被执行一次 while语句 for语句 for in语句:for(var propName in window){ document.write(propName); } 建议在使用for in循环之前,先检测确定对象的值不是null或者undefined 如果是 ,则不执行循环体 break是直接跳出这个循环 continue 是跳出这次循环 进入下一次循环 不建议使用label语句 with语句的作用是将代码的作用于设置在一个特定的对象里 with(location){ var qs=search.substring(1); var hostName=hostName; var url=href; } 严格模式下不允许使用with语句,否则视为语法错误 大量使用with语句会导致性能下降 所以在开发大型应用程序的是偶,不建议使用with语句 swith语句。 switch 语句在比骄傲的时候使用的是全等操作符,因此不会发生类型转换 例如字符串“10”不等于10 函数:function 里面位于return 后面的代码都不会被执行,也可以包括多个return 严格模式对函数有一些限制: 不能把函数名字命名为eval或者arguments 不能把参数命名eval或者arguments; 不能出现两个命名参数同名的情况 函数的理解: ECMAScript函数的参数 可以不用写,因为它的参数在内部是用一个数组来表示的 意思是 如果你定义了一个函数只接受两个参数 ,但是 你调用这个 函数的时候未必就要传递两个参数,而且 可以通过arguments来访问他的每一个元素 函数也不在乎传入多少参数,参数是什么类型都无所谓 没有传递值的命名参数将自动被赋值undefined值 这就跟定义了变量但是没有初始化一样。 ECMAScript中的所有参数传递的都是值,不可以通过引用传递参数 ECMAScript函数不能像传统意义上那样实现重,因为其参数是由包涵0或者多个值的数组来表示的。 通过检查传入函数中参数的类型和数量做出不同的反应,可以模仿方法的重载。 比如 : function sayHi(){ alert("heLLEO"+arguments[0]+,arguments[1]); } function howManyArgs(){ alert(arguments.length); } howManyArgs("sdf",45); //2 howManyArgs(); //0 howManyArgs(12); //1 总结 :1.ECMAScript的基本类型包括: Undefined,Null,Boolean,Number,String 2.没有为整数和浮点数值分别定义不同的数据类型,Numebr类型可用于表示所有的数值 3.Object是这门语言所有对象的基础类型 4.无需指定函数的返回值 5.实际上未指定返回值的函数返回的是一个特殊的undefined值 6.也没有函数签名的概念,因为其函数参数是以一个包涵0或者多个值的数组的形式传递的 7.可以向函数传递任意数量的函数,并且可以通过arguments对象来访问这些函数。 8.由于不存在函数签名的特性,函数不能重载

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

《Android程序设计》一2.3 作用域

2.3 作用域 作用域决定了程序中的变量、方法和其他符号的可见范围。任何符号在其作用域外都是完全不可见的,不能被使用。在这一节我们将简要地介绍作用域的主要内容,从最高层开始。 2.3.1 Java包 Java包提供了一种机制,它把相关类型分组到一个全局唯一的命名空间。这种分组机制可以防止在一个包的命名空间内的标识符和其他开发人员在其他命名空间内创建和使用的标识符冲突。一个典型的Java程序由很多Java包的代码组成。典型的Java运行时环境提供了如java.lang和java.util这样的包。此外,程序可能会依赖于其他通用的库,类似于org.apache树。传统上,应用代码(你所创建的代码)在你所创建的包内,包名是通过反转域名并附加程序名字生成的。因此,如果你的域名是androidhero.com,你的包所属的树的根是com.andr

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

《Android程序设计》一1.5 示例代码

1.5 示例代码 Android SDK安装完成并经过测试证明已经可以正常工作之后,可以进一步探索Android。即使你对Android的框架不熟悉,并且是Java新手,学习一些示例代码可以使你在阅读本书的其他部分之前,对SDK的安装更有自信。 1.5.1 SDK示例代码 SDK提供了最便捷的示例代码。可以使用SDK示例创建新的项目,如图1-16所示。选定的示例会出现在Eclipse窗口的左窗格,可以浏览该示例中所包含的文件,运行它查看它实现了什么功能。如果已经能够熟练使用IDE来调试这些代码,那么可以在示例代码中设置一些断点,分析一下什么时候执行了哪些方法。 警告: 在如图1-16所示的对话框中,在选择一个示例之前必须先选定一个build target。示例是按照API的级别组织的,如果还没有选择build target,那么下拉

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

读书笔记-JavaScript高级程序设计(1)

1.组合继承 (JavaScript中最常用的继承模式 ) (position: page168) (书中定义了两个变量名SuperType SubType 乍一看 感觉不太能区分,我将改为 a b ,更加明显区分开来这是两个东西。) function a(name){ this.name = name; this.colors = ["red", "blue", "green"]; } a.prototype.sayName = function(){ alert(this.name);} function b(name, age){ //继承属性 a.call(this, name); this.age = age; } //继承方法 b.prototype = new a(); b.prototype.constructor = b; b.prototype.sayAge = function(){ alert(this.age); }; var instance1 = new b("Nicholas", 29); instance1.colors.push("black"); alert(instance1.colors); //"red,blue,green,black" instance1.sayName(); //"Nicholas"; instance1.sayAge(); //29 var instance2 = new b("Greg", 27); alert(instance2.colors); //"red,blue,green" instance2.sayName(); //"Greg"; instance2.sayAge(); //27 完成继承的思路: 使用原型链实现对原型属性和方法的继承, 使用构造函数来实现对实例属性的继承。 在这个例子中, a构造函数定义了两个属性: name 和 colors。 a的原型定义了一个方法 sayName()。 b构造函数在调用 a构造函数时传入了 name 参数,紧接着又定义了它自己的属性 age。然后,将 a的实例赋值给 b的原型, 然后又在该新原型上定义了方法 sayAge()。这样一来,就可以让两个不同的 b 实例既分别拥有自己属性——包括 colors 属性,又可以使用相同的方法了。 2.寄生组合式继承 (实现基于类型继承的最有效方式 ) function object(o){ function F(){} F.prototype = o; return new F(); } function inheritPrototype(subType, superType){ var prototype = object(superType.prototype); //创建对象 prototype.constructor = subType; //增强对象 subType.prototype = prototype; //指定对象 } function a(name){ this.name = name; this.colors = ["red", "blue", "green"]; } a.prototype.sayName = function(){ alert(this.name); }; function b(name, age){ a.call(this, name); this.age = age; } inheritPrototype(b, a); b.prototype.sayAge = function(){ alert(this.age); }; // 调用 var instance1 = new b("Nicholas", 29); instance1.colors.push("black"); alert(instance1.colors); //"red,blue,green,black" instance1.sayName(); //"Nicholas"; instance1.sayAge(); //29 var instance2 = new b("Greg", 27); alert(instance2.colors); //"red,blue,green" instance2.sayName(); //"Greg"; instance2.sayAge(); //27

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

C++程序设计基础(6)内存分配

1.知识点 三步走:申请,释放,指针置空。 1.1malloc、free函数 在C语言中内存malloc函数申请动态空间,以下展示其基本用法: 1 int *p = NULL; 2 p = (int *)malloc(sizeof(int) * 10);//申请 3 free(p);//释放,否则会造成内存泄漏 4 p = NULL;//指针置空,否则成为野指针 (1)动态分配的空间来自队空间,而指针本身作为局部变量存储在栈空间中。 (2)malloc有时候也可能申请空间失败,这时返回NULL,故需要对其进行判断。 (3)通过malloc动态申请的空间必须通过free函数释放,这两个函数成对出现。否则可用空间会越来越少。 (4)在通过free函数释放之后,最好将指针置空。 (5)malloc/free函数申请释放的过程其实就是可用空间链表不断在更新。 1.2new、delete函数 (1)new和delete运算符既可以应用于基本类型,也可以用于自定义类型,new操作符不仅申请了空间,然后还根据提供的参数进行构造函数初始化,delete在释放内存空间之前还会调用对象的析构函数,这些事new/delete比malloc/free更为丰富的地方。 2.面试题 2.1malloc和free的常识性问题 以下说法正确的是(D)。 (A)free会将指针置为空 //需要手动置空 (B)malloc函数的返回指针移动后,free函数会自动找到首地址并释放 //不能失去对首地址的控制,否则无法释放 (C)malloc函数一次申请N个int空间,使用后需要循环N次逐一调用free释放 //malloc和free成对出现 (D)malloc申请的空间位于堆上 2.2返回一个64整数倍的地址 编写两个函数,align64malloc和align64free,分别用于申请空间和释放空间,并要求申请空间返回的地址必须是64的整数倍。 解析:在所需空间前面再加上64个字节,可保证其中肯定有一个地址是64的倍数,再在这64个字节空间的前面再加上4个字节保证有地方可以存储返回的首地址。如下表所示 A 4个字节 B 64个 字节 C N个字节 1 void * align64malloc(int size) { 2 void *ptr = malloc(sizeof(int)*size + 64 + sizeof(void *)); 3 if (!ptr) { 4 return NULL; 5 } 6 ptr = (char *)(ptr)+sizeof(void *); //在最前面预留出来了存放首地址的存储空间 7 //接下来一步需要将首地址空间放入到64整数倍前面的空间中去 8 *((int *)(((int)ptr+64-(int)ptr%64)-sizeof(void *)))=(int)ptr - sizeof(void *);//等式右边为首地址,void*是不可以进行加减运算 9 return (void *)((int)ptr + 64 - (int)ptr % 64); 10 } 11 12 void algin64free(void * ptr) { 13 if (ptr) { 14 free((void *)(*((void **)ptr - 1)));//void *不能进行加减,转换成指针的指针之后可以进行加减 15 } 16 } 2.3简述malloc/free和new/delete的区别 (1)malloc/free是C语言提供的库函数,通过函数调用访问,需要传递参数并接收返回值;而new/delete是C++提供的操作符,有自己的一套语法规则和运算方式。 (2)malloc/free只能用于基本的数据类型,而new/delete不但能用于基本数据类型,还可以用于面向对象中的自定义类型。 (3)malloc函数返回的是void*类型,程序需要显示的转换成所需要的指针类型,new操作符后面直接指明了类型,不涉及类型转换问题。 (4)malloc只负责申请空间,并返回首地址;new运算符除了申请空间,还会调用构造函数初始化指针指向的内容;free韩式只负责 释放空间,并标识这段空间为可用空间;delete运算符除了释放空间,还会调用对象的析构函数。 (5)事实上,后者覆盖了前者的全部功能,之所以在C++中还保留malloc/free函数,主要是为了解决兼容性问题,防止C++中调用包含malloc/free的C函数时出现错误。 2.4简述delete和delete[]的区别 答案(1)当new[]中数组的元素是基本类型时,通过delete和delete[]都可以释放数组空间; (2)当new[]中的数组元素是自定义的类型时,只能通过delete[]释放数组空间(因为用delete只调用第一个元素的析构函数)。 强烈建议申请和释放空间是采用完全配对的方式:new和delete成对使用,new[]和delete[]成对使用。 以下两个例子说明: 1 //基本类型时二者都可以 2 //A 3 int *i = new int[5]; 4 delete i; 5 //B 6 int *i = new int[5]; 7 delete[] i; 1 //自定义类型new[]/delete[]必须成对 2 class Test { 3 private: 4 char *text; 5 public: 6 Test(int lenght = 100) { 7 text = new char[lenght]; 8 } 9 ~Test() { 10 delete text; 11 cout << "A destructor" << endl; 12 } 13 }; 14 15 Test *a = new Test[5]; 16 delete[] a;//使用delete会出错

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

C++程序设计基础(7)位运算

注:读《程序员面试笔记》笔记总结 1.知识点 运算 符号 说明 与 & 有0为0,都1为1 或 | 由1为1,都0为0 非(取反) ~ 0变1,1变0 异或 ^ 同为0,异为1 左移 << 高位移除,低位补零 右移 >> 低位移除,高位补0 1.1异或的性质 1 a^a==0 2 0^a==a 3 a^b^b==b^a^b==a 2.面试题 2.1不使用变量交换两个值 1 //method one 2 a = a - b;//save b message 3 b = a + b;//b= old a 4 a = b - a; 5 //method two 6 a = a ^ b; 7 b = a ^ b;//b= old a 8 a = a ^ b; 提示:利用位的运算性质 2.2计算二进制的1的个数 1 //method one 2 for ( count = 0; num != 0; num=num >> 1) { 3 if (num & 1) { 4 count++; 5 } 6 } 7 //method two 8 for ( count = 0; num != 0; num &= num - 1) {//每次消掉最后的一个1 9 count++; 10 } 提示:一个数与自身减一后与操作,会消除末尾的1,每次消除一个1 2.3将二进制数倒数第M位的前N位取反(比如M=2,N=4) (1)将1左移N位(00000001=>00010000); (2)将步骤一得到的数减1(00010000=>00001111); (3)将步骤二得到的数左移M位(00001111=>00111100); (4)得到的数字与原数字进行异或。 1 int getNum(int num, int n, int m) { 2 int res = 1 << n; 3 res--; 4 res = res << m; 5 return res ^ num; 6 } 2.4找出人群中的唯一单身狗(一个数组中唯一一个数出现一次,其余的数都出现过偶数次,求该数) 1 int getSingleDog(int *a, int n) { 2 int res = 0; 3 for (int i = 0; i < n; i++) { 4 res ^= a[i]; 5 } 6 return res; 7 } 提示:异或的性质b^b==0以及交换律 2.5(找出人群中三个单身狗中的任意一个) 1 #define BITNUM 32 2 int getSingelNum_OneOfThree(int *a, int len) { 3 for (int i = 0; i < BITNUM; i++) { 4 int countOdd = 0, countEven = 0; 5 int resOdd = 0, resEven = 0; 6 int tem = 1 << i; 7 8 for (int j = 0; j < len; j++) { 9 if (tem & a[j]) { 10 countOdd++; 11 resOdd ^= a[j]; 12 } 13 else { 14 countEven++; 15 resEven ^= a[j]; 16 } 17 } 18 19 if (countOdd & 1 && resEven)//一组个数为奇数,另一组异或值不为零 20 return resOdd; 21 if (countEven & 1 && resOdd)//一组个数为奇数,另一组异或值不为零 22 return resEven; 23 } 24 return -1; 25 } 提示:按位从尾部根据0和1分成两组,当两组都有数,且偶数个的组所有值取异或不为零时,另一组取异或的值极为其中一个满足的值。

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

C++程序设计基础(8)main函数

注:读《程序员面试笔记》笔记总结 1.知识点 (2)main函数的形式 1 //first type 2 int main() 3 //second type 4 int main(int argc,char *argv[]) 不推荐使用void格式,以上两种方式函数以return 0结束; argc(argument count):代表参数的个数; argv(argument value):代表命令行输入的参数,其中argv[0]是程序名; 2.面试题 2.1键鼠main函数执行前后发生了什么 答案:main函数第一行代码执行之前会调用全局对象和静态对象的构造函数,初始化全局变量和静态变量;main函数 最后一行代码执行之后会调用atexit中注册的函数,并且调用顺序与注册顺序相反。

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

JavaScript高级程序设计学习(五)之对象

众说周知,java是面向对象的编程语言。一个类包含多个对象,例如车类,它包含宝马,奔驰,东风,本田,莲花等这样的车,而品牌和颜色或者某种标识就是它的属性。车包含很多种类,但是共性还是有的,比如共性有四个轮子,有品牌,有发动机等等。这些可以抽象为一个类,让子类继承这些共性,子类重写父类的方法,然后在此可以新增自己的属性和方法,以此标明差异活不同。 js为什么不是面向对象的编程语言呢? 用一句说明: 面向对象(Object-Oriented,OO)的语言有一个标志,那就是它们都有类的概念,而通过类可 以创建任意多个具有相同属性和方法的对象。前面提到过,ECMAScript中没有类的概念,因 此它的对象也与基于类的语言中的对象有所不同。所以js不是面向对象的语言。 ECMA-262把对象定义为:“无序属性的集合,其属性可以包含基本值、对象或者函数。”严格来讲, 这就相当于说对象是一组没有特定顺序的值。对象的每个属性或方法都有一个名字,而每个名字都映射 到一个值。正因为这样(以及其他将要讨论的原因),我们可以把 ECMAScript的对象想象成散列表:无 非就是一组名值对,其中值可以是数据或函数。 var person = new Object(); person.name = "Nicholas"; person.age = 29; person.job = "Software Engineer"; person.sayName = function(){ alert(this.name); }; 上面的例子创建了一个名为 person 的对象,并为它添加了三个属性(name、age 和 job)和一个 方法(sayName())。其中,sayName()方法用于显示 this.name(将被解析为 person.name)的值。 早期的 JavaScript开发人员经常使用这个模式创建新对象。几年后,对象字面量成为创建这种对象的首选 模式。前面的例子用对象字面量语法可以写成这样: var person = { name: "Nicholas", age: 29, job: "Software Engineer", sayName: function(){ alert(this.name); } }; (1)属性类型 ECMA-262第 5版在定义只有内部才用的特性(attribute)时,描述了属性(property)的各种特征。 ECMA-262定义这些特性是为了实现 JavaScript引擎用的,因此在 JavaScript中不能直接访问它们。为了 表示特性是内部值,该规范把它们放在了两对儿方括号中,例如[[Enumerable]]。尽管 ECMA-262 第 3版的定义有些不同,但本书只参考第 5版的描述。 ECMAScript中有两种属性:数据属性和访问器属性。 a.数据属性 数据属性包含一个数据值的位置。在这个位置可以读取和写入值。数据属性有4个描述其行为的 特性。  [[Configurable]]:表示能否通过 delete 删除属性从而重新定义属性,能否修改属性的特 性,或者能否把属性修改为访问器属性。像前面例子中那样直接在对象上定义的属性,它们的 这个特性默认值为 true。  [[Enumerable]]:表示能否通过 for-in 循环返回属性。像前面例子中那样直接在对象上定 义的属性,它们的这个特性默认值为 true。  [[Writable]]:表示能否修改属性的值。像前面例子中那样直接在对象上定义的属性,它们的 这个特性默认值为 true。  [[Value]]:包含这个属性的数据值。读取属性值的时候,从这个位置读;写入属性值的时候, 把新值保存在这个位置。这个特性的默认值为 undefined。 对于像前面例子中那样直接在对象上定义的属性,它们的[[Configurable]]、[[Enumerable]] 和[[Writable]]特性都被设置为 true,而[[Value]]特性被设置为指定的值。 var person = { name: "Nicholas" }; b.访问器属性 访问器属性不包含数据值;它们包含一对儿 getter和 setter函数(不过,这两个函数都不是必需的)。 在读取访问器属性时,会调用 getter函数,这个函数负责返回有效的值;在写入访问器属性时,会调用 setter函数并传入新值,这个函数负责决定如何处理数据。访问器属性有如下 4个特性:  [[Configurable]]:表示能否通过 delete 删除属性从而重新定义属性,能否修改属性的特 性,或者能否把属性修改为数据属性。对于直接在对象上定义的属性,这个特性的默认值为 true。  [[Enumerable]]:表示能否通过 for-in 循环返回属性。对于直接在对象上定义的属性,这 个特性的默认值为 true。  [[Get]]:在读取属性时调用的函数。默认值为 undefined。  [[Set]]:在写入属性时调用的函数。默认值为 undefined。 访问器属性不能直接定义,必须使用 Object.defineProperty()来定义。 set和get方法作为java开发者再熟悉不过了。 var book = { _year: 2004, edition: 1 }; Object.defineProperty(book, "year", { get: function(){ return this._year; }, set: function(newValue){ if (newValue > 2004) { this._year = newValue; this.edition += newValue - 2004; } } }); book.year = 2005; alert(book.edition); //2 描述: 以上代码创建了一个 book 对象,并给它定义两个默认的属性:_year 和 edition。_year 前面 的下划线是一种常用的记号,用于表示只能通过对象方法访问的属性。而访问器属性 year 则包含一个 getter函数和一个 setter函数。getter函数返回_year 的值,setter函数通过计算来确定正确的版本。因此, 把 year 属性修改为 2005会导致_year 变成 2005,而 edition 变为 2。这是使用访问器属性的常见方 式,即设置一个属性的值会导致其他属性发生变化。 补充说明: 不一定非要同时指定 getter和 setter。只指定 getter意味着属性是不能写,尝试写入属性会被忽略。 在严格模式下,尝试写入只指定了 getter 函数的属性会抛出错误。类似地,只指定 setter 函数的属性也 不能读,否则在非严格模式下会返回 undefined,而在严格模式下会抛出错误。 在java中get和set是必须一同存在的,当然也可以不存在,前提是属性必须为非私有和默认,必须为公共的,即public。否则无法调用该属性。 (2)定义多个属性 由于为对象定义多个属性的可能性很大,ECMAScript 5 又定义了一个 Object.definePro- perties()方法。利用这个方法可以通过描述符一次定义多个属性。这个方法接收两个对象参数:第一 个对象是要添加和修改其属性的对象,第二个对象的属性与第一个对象中要添加或修改的属性一一对 应。 var book = {}; Object.defineProperties(book, { _year: { value: 2004 } , edition: { value: 1 }, year: { get: function(){ return this._year; }, set: function(newValue){ if (newValue > 2004) { this._year = newValue; this.edition += newValue - 2004; } } } } ); (3)读取属性特性 使用 ECMAScript 5的 Object.getOwnPropertyDescriptor()方法,可以取得给定属性的描述 符。这个方法接收两个参数:属性所在的对象和要读取其描述符的属性名称。返回值是一个对象,如果 是访问器属性,这个对象的属性有 configurable、enumerable、get 和 set;如果是数据属性,这 个对象的属性有 configurable、enumerable、writable 和 value。 var book = {}; Object.defineProperties(book, { _year: { value: 2004 }, edition: { value: 1 }, year: { get: function(){ return this._year; }, set: function(newValue){ if (newValue > 2004) { this._year = newValue; this.edition += newValue - 2004; } } } } ); var descriptor = Object.getOwnPropertyDescriptor(book, "_year"); alert(descriptor.value); //2004 alert(descriptor.configurable); //false alert(typeof descriptor.get); //"undefined" var descriptor = Object.getOwnPropertyDescriptor(book, "yea 作为java的开发者很容易理解对象。这个概念。不过如果是初学者的话对此往往头有点大。 因此记得一位朋友说过,学java的时候最好先是从前端html,css,js这样的学,因为学到js的时候存在一个对象的概念,有助于理解java的面向对象和比较。 当然,反过来java的话,也可以方便比较。 对象,这个概念,博大精深啊! 想起对象这个概念,我想起了伟大的spring,有了spring,再也不怕对象管理和操控问题。 因为spring有控制反转的概念,可以帮我们进行对象管理。但是js没有。 调侃一句,记得某个笑话讲过,程序员最怕什么?不懂这个是笑话的人肯定会讲最怕出bug。其实这个说的也是有道理的。 不过最终的答案是,程序员最怕找不到对象,作为java程序员,java称之为面向对象的编程语言,如果找不到对象,那还有什么意思呢? 玩笑一下,程序员有的时候还是得自我调侃调侃一下。有助于身心放松。

资源下载

更多资源
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文件系统,支持十年生命周期更新。

WebStorm

WebStorm

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

用户登录
用户注册