首页 文章 精选 留言 我的

精选列表

搜索[基础搭建],共10000篇文章
优秀的个人博客,低调大师

高并发编程必备基础

一、前言 借用Java并发编程实践中的话"编写正确的程序并不容易,而编写正常的并发程序就更难了",相比于顺序执行的情况,多线程的线程安全问题是微妙而且出乎意料的,因为在没有进行适当同步的情况下多线程中各个操作的顺序是不可预期的,本文算是对多线程情况下同步策略的一个一个简单介绍。 二、 什么是线程安全问题 线程安全问题是指当多个线程同时读写一个状态变量,并且没有任何同步措施时候,导致脏数据或者其他不可预见的结果的问题。Java中首要的同步策略是使用Synchronized关键字,它提供了可重入的独占锁。 三、 什么是共享变量可见性问题 要谈可见性首先需要介绍下多线程处理共享变量时候的Java中内存模型。 Java内存模型规定了所有的变量都存放在主内存中,当线程使用变量时候都是把主内存里面的变量拷贝到了自己的工作空间或者叫做工作内存。 如图是双核C

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

JavaScript基础(六)面向对象

面向对象 对象创建方式: 1、调用系统函数创建对象 (创建对象的最简单方式就是创建一个 Object 的实例,然后再为它添加属性和方法。) var obj = new Object(); obj.name = "Daotin"; obj.age = 18; obj.eat = function () { console.log("我很能吃"); ); 缺点:使用同一个接口创建很多对象,会产生大量的重复代码。 2、自定义构造函数创建对象 工厂模式创建对象:考虑到在 ECMAScript 中无法创建类,开发人员就发明了一种函数,用函数来封装以特定接口创建对象的细节(把创建一个函数的过程封装在一个函数里面),缺点:创建的对象属性都是一样的。 function creatObject() { var obj = new Object(); obj.name = "Daotin"; obj.age = 18; obj.eat = function () { console.log("我很能吃"); }; return obj; } var person = creatObject(); person.eat(); 工厂模式创建对象进阶版:可以修改属性 function creatObject(name, age) { var obj = new Object(); obj.name = name; obj.age = age; obj.eat = function () { console.log("我很能吃"); }; return obj; }java var person = creatObject("Daotin", 18); person.eat(); 自定义构造函数:(函数和构造函数的区别:没有区别,但是通常构造函数首字母大写) 特点: 没有显式地创建对象; 直接将属性和方法赋给了 this 对象; 没有 return 语句。 function CreatObject() { // 首字母大写 this.name = "Daotin"; this.age = 18; this.eat = function () { console.log("我很能吃"); }; } var person = new CreatObject(); person.eat(); 进阶(传参数): function CreatObject(name, age) { this.name = name; this.age = age; this.eat = function () { console.log("我很能吃"); }; } var person = new CreatObject(); person.eat(); 构造函数的问题 构造函数模式虽然好用,但也并非没有缺点。使用构造函数的主要问题,就是每个方法都要在每个实例上重新创建一遍。在前面的例子中, person1 和 person2 都有一个名为 sayName()的方法,但那两个方法不是同一个 Function 的实例。不要忘了——ECMAScript 中的函数是对象,因此每定义一个函数,也就是实例化了一个对象。从逻辑角度讲,此时的构造函数也可以这样义。 function Person(name, age, job){ this.name = name; this.age = age; this.job = job; this.sayName = new Function("alert(this.name)"); // 与声明函数在逻辑上是等价的 } 从这个角度上来看构造函数,更容易明白每个 Person 实例都包含一个不同的 Function 实例(以显示 name 属性)的本质。说明白些,以这种方式创建函数,会导致不同的作用域链和标识符解析,但创建 Function 新实例的机制仍然是相同的。因此,不同实例上的同名函数是不相等的,以下代码可以证明这一点:alert(person1.sayName == person2.sayName); //false 然而,创建两个完成同样任务的 Function 实例的确没有必要;况且有 this 对象在,根本不用在执行代码前就把函数绑定到特定对象上面。因此,大可像下面这样,通过把函数定义转移到构造函数外部来解决这个问题。 function Person(name, age, job){ this.name = name; this.age = age; this.job = job; this.sayName = sayName; } function sayName(){ alert(this.name); } var person1 = new Person("Nicholas", 29, "Software Engineer"); var person2 = new Person("Greg", 27, "Doctor"); 在这个例子中,我们把 sayName() 函数的定义转移到了构造函数外部。而在构造函数内部,我们将 sayName 属性设置成等于全局的 sayName 函数。这样一来,由于 sayName 包含的是一个指向函数的指针,因此 person1 和 person2 对象就共享了在全局作用域中定义的同一个 sayName() 函数。 3、使用对象字面量表示法 对象字面量是对象定义的一种简写形式,目的在于简化创建包含大量属性的对象的过程。 如果留空其花括号,则可以定义只包含默认属性和方法的对象 var person = {}; //与 new Object()相同 。 缺点:一次性对象,无法修改属性的值。 var obj = { name:"Daotin", // 注意是属性赋值是冒号 age: 18, eat: function () { console.log("我很能吃"); } // 最后一个后面没有逗号 }; obj.eat(); 访问对象属性 点表示法 和 方括号表示法 alert(person["name"]); //"Nicholas" alert(person.name); //"Nicholas" 从功能上看,这两种访问对象属性的方法没有任何区别。但方括号语法的主要优点是可以通过变量来访问属性(属性绑定),例如: var propertyName = "name"; alert(person[propertyName]); //"Nicholas" 如果属性名中包含会导致语法错误的字符,或者属性名使用的是关键字或保留字,也可以使用方括号表示法。 例如:person["first name"] = "Nicholas"; 由于"first name"中包含一个空格,所以不能使用点表示法来访问它。然而,属性名中是可以包含非字母非数字的,这时候就可以使用方括号表示法来访问它们。通常,除非必须使用变量来访问属性,否则我们建议使用点表示法。 PS: 如果访问一个没有的属性的值,那么这个值为 undefined,而不是报错? 因为js是一门动态类型的元,不管使用点表示法还是方括号表示法,如果没有这个属性,就相当于在创建这个属性,然而这个时候没有赋值,所以就是 undefined。 访问对象方法 对象名.函数名(); JSON 什么是JSON? JavaScript Object Notation(JavaScript对象表示形式:就是对象字面量) JSON格式的数据:一般都是成对的,键值对。 JSON和对象字面量的区别? json和对象(对象字面量)的区别仅仅在于,json格式的数据中的键必须用双引号括起来; var json = { "name" : "zs", "age" : 18, "sex" : true, "sayHi" : function() { console.log(this.name); } }; 字面量的遍历 对象本身没有 length ,所以不能用 for 循环遍历。要使用 for...in... var json = {“aaa”: 1, “bbb”: 2, “ccc”: 3, “ddd”: 4} for(var key in json){ //key代表aaa,bbb.....等 //json[key]代表1,2,3....等(k 不要加引号) } 值传递和引用类型传递 分析值传递和址传递最好的方法就是画图分析,最简单。 内置对象 Math, Date, String, Array MDN:在线文档 菜鸟教程 基本包装类型 本身是基本类型,但是在执行的过程中,如果这种类型的变量调用了属性或者方法,那么这种类型就不是基本类型了,而是基本包装类型。这个变量也不是普通变量了,而是基本包装类型的变量。 var str = "hello"; str = str.replace("he", "wo"); console.log(str); // wollo 需要注意的地方: 如果一个对象&&true,那么结果是true 如果一个true&&对象,那么结果是对象。 var flag = new Boolean(false); var result = flag && true; var result1 = true && flag; console.log(result); // true console.log(result1); // Boolean var num = 10; // 基本类型 var num2 = Number("10"); // 不是基本包装类型,而是转换,这里换成 Boolean 也成立 var num3 = new Number("10"); // 这才是基本包装类型

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

Android面试之Java基础

一、java面向对象的三大特性与含义 1、继承:从已有的类得到继承信息创建新类的过程,继承让变化中的软件系统有了一定的延续性,同时继承也是封装程序的可变因素的重要手段。 2、封装:通常认为封装是把数据和操作数据的方法绑定起来,对数据的访问只能通过已经定义的接口。面向对象的本质就是将现实世界描绘成一系列完全自制、封闭的对象。可以说,封装就是隐藏一切可隐藏的东西,只向外界提供简单的编程接口; 3、多态:允许不同子类型的对象对同一消息作出不同的响应。简单说就是用同样的对象引用调用同样的方法但是做了不同的事情。 4、实现多态需要做的两件事:①、方法重写;②、对象造型 二、java多态 1、多态定义:允许不同类的对象对同一消息作出响应,即同一消息可以根据发送对象的不同而表现出多种不同的行为方式。 2、多态的作用:消除类型间的耦合关系。 3、实现多态的技术:动态绑定 4、多态存在的必要条件:①有继承;②有重写;③父类引用指向子类对象。 5、多态的好处:①可替换性、②可扩充性、③接口性、④灵活性、⑤简化性。 6、多态的实现方式:接口实现、继承父类进行方法重写、同一个类内进行方法重载。 三、Java中的SoftReference是什么? 1、Java 中的 SoftReference 即对象的软引用。如果一个对象具有软引用,内存空间足够,垃圾回收器就不会回收它;如果内存空间不足了,就会回收这些对象的内存。只要垃圾回收器没有回收它,该对象就可以被程序使用。软引用可用来实现内存敏感的高速缓存。使用软引用能防止内存泄露,增强程序的健壮性。 2、SoftReference的特点:它的一个实例保存对一个Java对象的软引用,该软引用的存在不妨碍垃圾收集线程对该Java对象的回收。也就是说,一旦SoftReference保存了一个Java对象的软引用后,在垃圾线程对这个Java对象回收前,SoftReference类所提供的get()方法返回Java对象的强引用。但是,一旦垃圾线程回收该Java对象之后,get()方法将返回null。 四、abstract关键字 1、abstract可以修饰类、方法 2、如果一个类被abstract修饰,此类必须被继承使用,此类不可以生成对象,但是可以声明。 3、abstract可以 将子类的共性最大限度的抽取出来放在父类,以提高代码的简洁性。 4、abstract修饰方法时,方法为抽象方法,该方法不需要进行实现,实现留给子类,子类覆盖该方法之后才能生效。 5、abstract不能与static、final放在一起否则会出现错误 五、重写和重载 1、重写:如果子类中定义的某个方法与其父类有相同的名称和参数,则该方法被重写了。 2、重载:如果一个类内有多个重名的方法,它们或有不同的参数个数、或有不同的参数类型、或有不同的参数次序,则称为重载。 3、重载的规则:必须改变参数列表、可以改变返回类型、可以改变访问修饰符、可以声明新的或更广的检查异常、能够在同一个类中或者在一个子类中被重载、无法通过返回值类型来判断方法是否重载。 4、重写的规则:参数列表、返回值类型必须相同,访问权限不能低于父类的方法,被final修饰的方法不能被重写,static修饰的方法不能被重写但是可以再次声明,构造方法不能被重写,重写方法不能抛出更广泛的强制异常,访问权限不能下降。 六、Java中如何定义常量 1、接口中常量默认为static final; 2、Java 5.0 中引入类Enum类型; 3、在普通类中使用static final修饰的变量; 七、abstract、interface、final、static总结 abstract 1、只要含有抽象方法的类必须声明为抽象类; 2、抽象类可以有具体的实现方法; 3、抽象类内可以没有抽象方法; 4、抽象方法必须被子类实现,或者子类也是抽象的; 5、抽象类不可以被实例化,但是可以被声明; 6、若使用抽象类内部的方法,则必须有一个子类继承这个抽象类,并且实现抽象方法,通过子类实例化去调用; interface 1、接口内成员变量必须定义初始化; 2、接口内的成员方法只能是方法原型,不能有方法体; 3、接口内的成员变量和方法只能是public的; 4、实现接口的类必须全部实现接口的方法; final 1、可以修饰成员变量、非抽象类、非抽象类成员方法、方法参数; 2、final方法不能被子类重写,但是可以被继承; 3、final类不可以被继承,final类内部的方法也无法被继承; 4、final修饰的变量只能被赋值一次,赋值之后不能被修改; 5、final不能修饰构造方法; 6、final的参数:只能被使用,不能修改该参数的值 static 1、可以修饰成员变量和成员方法,但是不能修饰类(静态内部类除外)以及构造方法; 2、static修饰的成员变量和成员方法独立于这个类,被类的所有实例共享; 3、static修饰的类和成员方法可以通过类名直接访问,也可以通过实例来访问; 4、private修饰的static变量和static方法只能在声明的本类方法及静态块内访问,但不能使用this方法,因为this是非静态变量。 static+final同时修饰 1、该变量或者方法可以简单理解为全局常量; 2、对于变量一但给值就不可以修改,可以通过类名进行访问; 3、对于方法,表示不可覆盖,可以通过类名直接访问; switch是否可以使用string来作为参数? Java 5之后switch可以引用enum、byte、short、char、int作为参数 Java 7 之后引入string 八、Object有哪些公用方法 1、clone方法 保护方法,实现对象的浅复制,只有实现了Cloneable接口才可以调用该方法,否则会抛出CloneNotSupportException异常。 2、getClass()方法 final方法,获得运行时类型 3、toString()方法 不用多说了( ̄ ̄)~* 4、finalize方法 释放资源使用,很少使用; 5、equals()方法 只有在Object中equals方法和==是一样,其他时候两者不一样。 6、hashCode()方法 该方法用于哈希值的查找,可以减少equals方法的使用,提高代码运行效率。 7、wait()方法 wait方法就是使当前线程等待该对象的锁,当前线程必须是该对象的拥有者,也就是具有该对象的锁。wait方法一直等待,直到获得锁或者被中断。 调用该方法后当前线程进入睡眠状态,直到发生以下事件 ①、其他线程调用了该对象的notify方法; ②、其他线程调用该对象的notifyAll方法; ③、其他线程调用了interrupt方法中断该线程; ④、时间间隔到了。 八、int和integer的区别 1、int是基本数据类型 2、integer是int的封装类 3、int和integer都可以表示某一个数值 4、int和integer不能够互用,因为他们两种不同的数据类型 九、string是否可以被继承 不可以,因为String为final类 十、常量 final String str=“ab”可不可以编程“abc”,为什么? 不可以,因为使用final修饰的变量不可改变 十一、String、StringBuffer、StringBuilder之间的区别 三者执行效率为:StringBuilder>StringBuffer>String String字符串为常量,不可改变; StringBuilder字符串变量(非线程安全) StringBuffer字符串变量(线程安全) String类型进行改变的时候其实等同于生成 一个新的String对象,然后指针指向新的String对象。会导致jvm的gc开始工作导致速度变慢; StringBuffer一个类似于String的字符串缓冲区,但是不能修改。但是可以通过某些方法来改变该序列的长度和内容。 StringBuffer上主要操作的是append方法和insert方法,append方法是将任意类型的数据转换成字符串添加到缓存区末端,而insert方法是制定的添加字符串。 String s=new Sting(“abc”);new了几个对象? 两个 String源码分析 String对象是不可变类型,返回类型为String的String方法每次返回的都是新的String对象,除了某些方法的某些特定条件返回自身。 String对象的三种比较方式: 1、==内存比较:直接对比两个引用所指向的内存值,精确简洁直接明了。 2、equals字符串值比较:比较两个引用所指对象字面值是否相等。 3、hashCode字符串数值化比较:将字符串数值化。两个引用的hashCode相同,不保证内存一定相同,不保证字面值一定相同。 十二、内部类 静态内部类和非静态内部类的区别 1、静态内部类不持有外部类的引用,非静态内部类持有外部类的引用 2、静态内部类可以有静态成员,非静态内部类不能持有静态成员; 3、静态内部类只能访问外部类的静态成员和静态方法,非静态内部类可以访问外部类的所有成员和方法; 4、实例化一个静态内部类不需要外部类的实例;实例化一个非静态内部类需要通过外部类的实例生成内部类的实例; 5、调用静态内部类的方法或变量可以通过类名直接调用。 为什么内部类拥有外部类的所有元素的访问权? 内部类对象只能在与其外部类对象关联的情况下才能被创建,构建内部类需要一个外部类的引用,内部类正是通过这个引用去访问外部类的。 内部类的种类 成员内部类、方法内部类、匿名内部类、静态内部类 内部类的作用 1、内部类可以 用多个实例,每个实例都有自己的状态信息,并且与其他外围对象的信息相互独立; 2、单个外围类中,可以让多个内部类以不同的方式实现同一个接口,或者继承同一个类。 3、创建内部类对象的时刻并不依赖于外围类对象的创建; 4、内部类是一个独立的实体; 5、内部类提供了更好的封装,除了外围类,其他类都不能进行访问 静态内部类、内部类、匿名内部类,为什么内部类会持有外部类的引用?持有的引用是this?还是其它? 因为内部类的产生依赖于外部类,持有的引用是“类名.this”; 十三、抽象类和接口 抽象类的总结 1、抽象类不能被实例化 2、抽象类内部不一定包含抽象方法,有抽象方法的类一定是抽象类 3、抽象类内部的方法只是声明,不包含方法体,就是不给出具体的实现也就是方法的具体功能; 4、构造方法、类方法不能声明为抽象方法 5、抽象类的子类必须给出抽象类中抽象方法的具体实现,除非这类也是抽象类。 接口与类的区别 接口不能用于实例化对象; 接口没有构造方法; 接口内的方法必须是抽象方法; 接口不能包含成员变量,除非是static 和 final修饰的; 接口不是被类继承而是被类实现; 接口支持多重继承 接口特性 1、接口中的每一个方法都是隐式抽象的,接口中的方法会被隐式的指定为 public abstract; 2、接口内可以含有变量,但是接口中的变量会被隐式的指定为public static final 变量; 3、接口中的方法是不能在接口中实现的,只能由实现接口的类来实现接口内部的方法; 抽象类与接口的区别 1、抽象类内部的方法可以有方法体,但是接口内部的方法不行; 2、抽象类中的成员变量可以是各种类型的,而接口的成员变量只能是public static final类型的; 3、接口中不能有静态代码块以及静态方法,而抽象类内可以有静态代码块和静态方法,java8新特性允许接口内存在静态方法; 4、一个类只能继承一个抽象类,而一个类可以实现多个接口; 5、接口中不能有构造函数和main方法;抽象类内可以有; 6、接口是被实现;抽象类类是被继承。 接口的意义 1、提供一个规范,要求类必须实现指定的方法; 2、解决Java中的单继承问题,可以用接口来实现多继承的功能,简单化多重继承中继承树的复杂程度; 3、增强程序的扩展性。 抽象类的意义 为其子类提供一个公共的类型,封装子类中的重复内容,定义抽象方法,子类虽然有不同的实现,但是定义是一致的。 十四、接口是否可继承接口? 抽象类是否可实现(implements)接口? 抽象类是否可继承实体类(concreteclass)? 1、接口可以继承接口,使用关键字extends 2、抽象类可以实现接口。AbstractCollection类就实现了Collection接口; 3、抽象类可以继承实体类。 十五、abstract的方法是否可以同时是static,是否可同时是native,是否可同时是final? 都不行 abstract的方法不可以是static的,因为抽象的方法是要被子类实现的,而static与子类没有关系! native方法表示该方法要用另外一种依赖平台的编辑语言实现的,不存在者被子类实现的问题,所以,他也不能是抽象的,不能与abstract混用。 十六、final关键字 1、final修饰的类不能被继承,final类内部的方法都被隐式的指定为final方法; 2、final修饰的方法的原因:明确禁止该方法在子类中被覆盖; 3、修饰变量:①、基本数据类型的变量,数值一旦被初始化便不能更改;②、引用类型变量,初始化之后不能再让其指向另一个对象 4、final修饰的引用形变量其指向的对象内容可变。 十七、finally final finalize的作用? final用于声明属性、方法和类; finally是异常处理语句结构的一部分,表示总是执行; finalize是Object类的一个方法。 十八、Collection与Collections的区别 Collection是一个接口,它是Set、List等容器的父接口; Collections是一个工具类,提供了一系列的静态方法来辅助容器操作,这些方法包括对容器的搜索、排序、线程安全化等 十九、Set和List的区别 1、Set接口存储的是无序的、不重复的数据;List接口存储的是有序的、可以重复的数据; 2、Set检索效率低,删除和插入效率高、删除和插入不会引起元素位置变化,实现类有HashSet、TreeSet。 List检索效率高、插入和删除效率低,因为引起其他元素的位置变化,实现类有ArrayList、LinkdList、Vector。 二十、hashCode方法的作用 hashCode方法主要作用是为了配合基于散列的集合一起正常的运行,这样的散列的集合包括hashSet、HashMap、HashTable。 why?考虑到一种情况就是当向集合内部插入对象时,不允许有重复对象。 当向集合内部添加新对象时,首先调用对象的hashCode方法得到对象的哈希值,实际上在HashMap的具体实现中会用到一个table保存已经存进去的对象的hashCode,如果table内没有该哈希值,它就可以直接存进去不用进行比较了,如果存在则调用它的equals方法与新元素进行比较如果相同的话就不存了,不同的话存进去。这样的话就大大降低了equals方法的使用,提高了程序的运行效率。 如果equals方法得到的结果为true,则两个对象的hashcode值必定相等; 如果equals方法得到的结果为false,则两个对象的hashcode值不一定不同; 如果两个对象的hashcode值不等,则equals方法得到的结果必定为false; 如果两个对象的hashcode值相等,则equals方法得到的结果未知。 多线程环境中安全使用集合API 在集合API中最初设计的Vector和HashTable是多线程安全的。例如Vector,用来添加和删除元素的方法是同步的,如果只有一个线程与其进行交互,那么要求获取和释放对象锁是一种浪费,另外在不必要的时候滥用同步化也可能带来死锁现象。因此集合的本质上是非多线程安全的,当与多线程交互时,为了使它多线程安全,必须采取额外措施。 HashMap的实现原理 HashMap底层就是一个数组结构,数组中的每一项又是一个链表。当新建一个HashMap的时候就会初始化一个数组。 二十一、容器之间的区别 HashMap与HashTable的区别 1、继承不同 HashMap继承自Dictionary 、HashTable继承自AbstractMap 2、HashTable中的方法是同步的,HashMap的方法不是同步的; 3、HashTable内的key和value都不允许出现null,HashMap中的null可以作为键,这样的键只能有一个;可以有一个或者是多个键对应的值是null; 4、两个遍历方式不同 5、HashTable直接使用对象的哈希值、HashMap重新计算哈希值; ArrayMap和HashMap的区别 1、存储方式不同。ArrayMap使用的两个数组进行存储,HashMap使用链表进行存储; 2、扩容处理方法不一样。ArrayMap使用System.arraycopy()copy数组,而 HashMap 使用 new HashMapEntry 重新创建数组。 3、ArrayMap 提供了数组收缩的功能,在clear或remove后,会重新收缩数组,节省空间。 4、ArrayMap 采用二分法查找。 ArrayList Vector LinkedList 三者的区别 1、三者都实现了List 接口;但 LinkedList 还实现了 Queue 接口。 2、ArrayList 和 Vector 使用数组存储数据;LinkedList 使用双向链表存储数据。 3、ArrayList 和 LinkedList 是非线程安全的;Vector 是线程安全的。 4、ArrayList 数据增长时空间增长50%;而 Vector 是增长1倍; 5、LinkedList 在添加、删除元素时具有更好的性能,但读取性能要低一些。 6、LinkedList 与 ArrayList 最大的区别是 LinkedList 更加灵活,并且部分方法的效率比 ArrayList 对应方法的效率要高很多,对于数据频繁出入的情况下,并且要求操作要足够灵活,建议使用 LinkedList;对于数组变动不大,主要是用来查询的情况下,可以使用 ArrayList。 二十二、内存相关知识点 Java程序运行时的内存分配策略有三种,分别是静态分配、栈式分配和堆式分配。对应的就是静态存储区、栈区、堆区。 1、静态存储区:主要存放静态数据、全局static数据和常量。这块内存在程序编译时已经分配确定,并且在程序整个运行期间都会存在; 2、栈区:当方法执行时,方法体内部的局部变量都在栈上创建,并在方法执行结束时这些局部变量持有的内存将会自动释放 3、堆区:又称之为动态内存分配,通常指程序运行时直接new出来的内存,也就是对象的实例。这部分内存不使用时会由垃圾回收器进行回收 栈与堆的区别 栈:在方法体内定义的一些基本类型变量和对象引用的变量都是在方法的栈内存中进行分配的。 堆:用来存放所有由new创建的对象和数组。在堆中分配的内存,将由Java垃圾回收器自动管理。当在堆中产生一个数组或者对象后,还可以在栈中定义一个特殊的变量,这个变量取值等于数组或者对象在堆内存中的首地址,这个特殊变量就是引用变量。可以通过引用变量来访问堆中的对象或者是数组 结论: 1、局部变量的基本数据类型和引用存储于栈中,引用对象的实体存储于堆中。 2、成员变量存储于堆中。因为他们属于类,类对象终究是要被new出来使用的。 3、栈存取速度仅次于寄存器,存储效率比堆高,可以共享存储数据,但是其中数据大小和生存期必须在运行前确定。 4、堆是运行时可动态分配的数据区,从速度看比栈慢,堆里面的数据不共享大小和生存期都可以在运行时再确定。 Java如何管理内存? Java的内存管理就是对象的内存分配和释放问题。在Java中程序员通过new来为每个对象在堆中申请内存空间,所有的对象都在堆中分配空间。对象的释放由GC决定和执行,由于内存分配和释放由两条线来完成简化了程序员的工作,但是增加了jvm的工作。这也是Java运行速度较慢的原因之一。因为GC为了能够正确释放对象,GC必须监控每一个对象的运行状态,监视对象的目的是为了更加准确及时的释放对象,而释放对象的原则是该对象不被引用。 为了更好理解 GC 的工作原理,我们可以将对象考虑为有向图的顶点,将引用关系考虑为图的有向边,有向边从引用者指向被引对象。另外,每个线程对象可以作为一个图的起始顶点,例如大多程序从 main 进程开始执行,那么该图就是以 main 进程顶点开始的一棵根树。在这个有向图中,根顶点可达的对象都是有效对象,GC将不回收这些对象。如果某个对象 (连通子图)与这个根顶点不可达(注意,该图为有向图),那么我们认为这个(这些)对象不再被引用,可以被 GC 回收。 Java使用有向图的方式进行内存管理,可以消除引用循环的问题,例如有三个对象,相互引用,只要它们和根进程不可达的,那么GC也是可以回收它们的。这种方式的优点是管理内存的精度很高,但是效率较低。另外一种常用的内存管理技术是使用计数器,例如COM模型采用计数器方式管理构件,它与有向图相比,精度行低(很难处理循环引用的问题),但执行效率很高。 什么是Java内存泄漏? 这些对象具有如下两个特点。①、这些对象是可达的即在有向图内存在通路与其相连;②、这些对象是无用的,即以后程序不会再使用这些对象。如果对象满足这两个条件,那么我们就可以认为这些对象为Java中的内存泄漏,但是这些对象不会被GC回收,然而占用内存。 Java的内存回收机制 所有的编程语言的内存分配方式都需要返回分配内存的真实地址,也就是返回一个指针到内存块的首地址,Java中对象是采用new或者反射的方式创建的,这些对象的创建都是在堆中分配的,所有对象的回收都是由Java虚拟机通过垃圾回收机制完成的。GC为了能够准确的释放对象会监控每一个对象的运行状况(申请、引用、被引用、赋值),Java使用由向意图的方法进行管理内存,实时监控对象是否可以到达,如果不可到达则进行回收。这样也可以消除引用循环的问题。 判断内存空间是否符合垃圾回收标准? ①、对象被赋予了空值null,再也没有调用过; ②、给对象赋予了新值,这样重新分配了内存空间; Java内存泄漏引起的原因 内存泄漏的定义:无用的对象持续占有内存或无用对象的内存得不到及时释放,从而导致内存空间的浪费。严重的内存泄漏会导致内存溢出(OOM)。 内存泄漏的根本原因: 长生命周期的对象持有短生命周期对象的引用就很可能发生内泄漏。 具体导致内存泄漏的原因: 1、静态集合引起的内存泄漏 HashMap、Vector等的使用容易出现内存泄漏,这些静态变量的生命周期和应用程序一致,他们所引用的所有的对象Object也不能被释放,因为他们也将一直被Vector等引用着。 解决方法:及时将集合对象设置为null。 2、监听器 在释放对象的时候忘记删除对象的监听器,从而增加了内存泄漏的机会。 解决方法:及时删除监听器 3、各种连接 比如数据库连接(dataSourse.getConnection()),网络连接(socket)和io连接。 解决方法:显示调用close()方法,否则是不会自动被GC回收的。 4、内部类和外部模块的引用 解决方法:细节,时刻提醒提供相应方法去除引用 5、单例模式 不正确使用单例模式导致。单例对象在初始化后将在jvm的整个生命周期中存在,如果单例对象持有外部类的引用,那么这个对象将不能被JVM正常回收导致内存泄漏。 Java内存回收机制,GC 垃圾回收机制,垃圾回收的优点和原理,并说出3种回收机制。 优点: 1、Java语言显著的特点就是引入了垃圾回收机制,它使程序员在编写程序时不再考虑内存管理问题,直接解放了程序员的大脑; 2、由于有了垃圾回收机制,Java对象不再有“作用域的概念”,只有引用对象才有“作用域”的概念; 3、垃圾回收机制有效的防止了内存泄漏,可以有效的使用空闲的内存; 4、垃圾回收器通常作为一个单独的低级别的线程运行,在不可预知的情况下进行对内存堆中的已经死亡的或者长时间没有用过的对象进行清除和回收。 5、程序员实时的对某个对象调用垃圾回收器进行垃圾回收。 垃圾回收机制:分带复制垃圾回收、标记垃圾回收、增量垃圾回收 垃圾回收算法 1、引用计数算法:缺点是无法处理循环引用问题 2、标记-清除算法:标记所有从根节点开始的可达的对象。缺点是会造成空间不连续,导致不容易分配内存 3、标记-压缩算法:标记清除算法的升级版,原理:清除未标记对象时还将所有的存活对象压缩到内存的另一端,之后清理边界所有的空间既避免碎片产生,又不需要两块同样大小的内存块。适用于老年代。 4、复制算法:将内存空间分为两块,每次将正在使用的内存中存活对象复制到未使用的内存块中,之后清除正在使用的内存块。算法效率高,但是代价是系统内存折半。适用于新生代。 5、分代 Java虚拟机的特性 Java语言的一个非常重要的特性就是与平台无关性,而Java虚拟机是实现这一特性的关键。一般的高级语言在不同的平台上运行,至少需要编译成不同的目标代码。然而引入Java语言虚拟机之后,Java在不同平台运行的时不需要重新编译,Java语言使运行时Java虚拟机屏蔽了与具体平台相关的信息,使得Java语言编译程序只需生成在Java虚拟机上运行的目标代码(字节码),就可以在多种平台上不加修改地运行。Java虚拟机在执行字节码时,把字节码解释成具体平台上的机器指令执行。 哪些情况下的对象会被垃圾回收器回收掉 Java的回收机制最基本的做法就是分代回收。内存中的区域被划分为不同的世代,对象根据其存活时间被保存在在不同的世代内。一般被分为三个世代分别为:年轻、年老、永久。内存分配是发生在年轻世代内,对于不同的世代可以才用不同的垃圾回收算法。基于这一点针对世代的垃圾回收算法就很有针对性了。 二十三、多线程 一个线程的生命周期 新建状态:使用new关键字和Thread类或其子类建立一个线程对象,该线程对象就处于新建状态。它保持这个状态直达程序start()这个程序。 就绪状态:当线程对象调用start()方法之后,该线程就进入就绪状态。就绪状态的线程处于就绪队列中,等待JVM里线程调度器的调度。 运行状态:如果就绪状态的线程获取CPU资源,就可以执行run()方法,此时的线程处于运行状态。处于运行时的状态最为复杂,可以变为阻塞状态、就绪状态、死亡状态。 阻塞状态:线程执行了sleep(睡眠)、suspend(挂起)等方法,失去所占用资源之后,该线程从运行状态进入阻塞状态。在睡眠时间已到或获得设备资源后可以重新进入就绪状态。 阻塞状态可以分为三种:①、等待阻塞:运行状态中的线程执行wait()方法;②、同步阻塞:线程在获取synchronized同步锁失败; ③、其他阻塞 死亡状态:一个运行时状态的线程完成任务或者其他终止条件发生时,该线程切换到终止状态。 线程与进程的区别 程序是一段静态的代码,一个进程可以有一个或者多个线程,每个线程都有唯一的标识 区别:①、进程大体分为数据区、代码区、栈区、堆区。多个进程之间的内部数据和状态是完全独立的;线程共享进程的数据区、代码区、堆区、只有栈区是独立的。所以线程切换代价小于进程切换代价。 ②、一个程序至少有一个进程,一个进程至少有一个线程; ③、线程划分尺度小于进程、多线程的程序并发高; ④、进程在执行过程中拥有独立的内存单元,而多线程共享内存,从而极大地提高了程序运行效率; 什么导致线程阻塞 1、调用sleep(毫秒),使得线程进入睡眠状态; 2、调用suspend()暂停线程执行。除非线程收到resume()消息否则返回不可运行状态; 3、调用wait()方法暂停线程执行。除非调用notify()或者notifyAll()消息,否则不可运行; 4、线程正在等候IO操作的完成; 5、线程试图调用另一个对象的同步方法,但是那个对象处于锁定状态暂时无法使用。 多线程的实现方法 1、实现Runnable接口; 2、继承Thread类本身; 3、通过callable和Future创建线程(Java 5 之后出现); 实现Runnable接口相比继承Thread类有如下优势 1、可以避免Java单继承的特性带来的局限性; 2、增强程序的健壮性,代码可以被多个程序共享,代码与数据是独立的; 3、适合多个相同程序代码的线程区处理同一资源的情况 同步有几种实现方法,都是什么? 两种 synchronized wait和notify 锁的等级 方法锁、对象锁、类锁 同步和异步的区别? 同步:A线程请求某资源时,B线程占用该资源,则A只能等待下去 异步:A线程请求某个资源时,B线程占用该资源,则A无需等待可以请求。 sleep和wait的区别 ①、sleep:线程休息;wait:线程挂起。 ②、sleep方法属于Thread类的方法;wait属于Object类方法 ③、sleep:sleep正在执行的线程主动放出cpu,指定时间后cpu回到该线程继续向下执行。注意sleep只是让出CPU而并不是释放同步资源锁; wait:当前线程让自己暂时退让出同步资源锁,以便其他正在等待该资源的线程得到该资源而运行,只有调用notify方法之后调用wait方法的线程才会接触wait状态进而参与竞争同步资源锁,进而执行 Java线程池线程同步 同步操作产生的原因:当多个线程同时访问对象并要求操作相同资源时,分割了原子操作就有可能出现数据的不一致或数据不完整情况,为了避免发生这种情况,我们会采取同步机制。 synchronized修饰符实现的同步机制叫做互斥锁机制。 互斥锁:每个对象都有一个锁标记,当线程拥有锁机制的时候才可访问这个资源,没有锁标记便进入锁池。任何一个对象系统都会创建一个互斥锁,这个锁为了分配给线程,防止打断原子操作,每个对象锁只能分配给一个线程。 当一个线程进入一个对象的一个synchronized方法后,其他线程是否可进入此对象的其他方法? 可以调用此对象的其他非synchronized方法; 可以调用此对象synchronized static方法; 线程加锁的作用:互斥行为和内存可见性 内存可见性定义 某个线程正在使用对象状态而另一个线程在同时修改该状态,当该状态被修改之后可以立刻被其他线程感知该对象的状态改变了 Atomic、volatile、synchronized区别 1、synchronized是解决多线程共享资源的问题同步机制采用了“以时间换取空间”的做法,访问串行化、对象共享化。同步机制是提供一份变量,让所有线程都可以访问。 2、Atomic是通过原子操作指令+Look-Free完成,从而实现非阻塞的并发问题。 3、Volatile是为了多线程资源共享问题解决了部分需求,在非依赖自身的操作的情况下,对变量的改变将对任何线程可见。 4、ThreadLocal是为了解决多线程资源共享问题,用来提供线程内局部变量,省去参数传递这个不必要的麻烦,做到了“以空间换取时间”的方式。 5、如果是一个类的多个对象想公用对象内部的一个变量,而不想使用static,可以使用浅复制的方式。 并发编程实现内存可见性的方式- - - ->加锁和volatile变量 volatile变量 1、volatile变量是一种脆弱的同步机制,由于访问volatile变量时不会执行加锁操作,因此也就不会执行线程阻塞,因此volatile变量是一种比synchronized关键字轻量级的同步机制; 2、从内存可见度角度来看,写入volatile操作相对于退出同步代码块,读取volatile变量相对于进入同步代码块; 3、代码中过度使用volatile编写来控制可见性,通常会比使用锁更加脆弱和难以理解。 4、volatile只能保证可见性,不能保证原子性。 使用volatile的情景: 1、对变量的读写操作不依赖变量的当前值,或者可以保证只有单个线程更新变量的值; 2、该变量没有包含在具有其他变量的不变式中。 守护线程与阻塞线程的四种情况 用户线程:运行在前台的线程; 守护线程:运行在后台的线程,为其他前台线程的运行变量提供便利服务的,仅当非守护线程运行时,才需要守护线程例如垃圾回收线程; 可以人为创建守护线程,通过Thread的setDeamon(ture)方法设置当前线程为守护线程。 禁止在守护线程内创建耗时操作,比如IO操作 setDeamon(ture)方法必须在调用线程的start()方法之前设置,否则会抛出IllegalThreadStateException异常。 守护线程内产生的新线程也是守护线程。 死锁 线程A持有互斥锁lock1,线程B持有互斥锁lock2。当线程A持有lock1时,师徒获取lock2,因为B持有lock2,因此线程A会阻塞等待线程B对lock2的释放。如果此时B在持有lock2的时候也试图获取lock1,因为A持有lock1,因此线程B会阻塞等待A对lock1的释放。二者都在等待对方所持有的锁释放,而二者却又都没释放自己所持有的锁,这时二者会一直阻塞下去,这种情况为死锁现象。 如何避免死锁现象产生 1、只在必要的最短时间内持有锁,可以考虑使用同步语句块代替整个同步方法; 2、尽可能不编写在同一时刻需要持有多个锁的代码,如果不可避免则确保线程持有第二个锁的时间尽量短; 3、创建一个大锁来代替若干个小锁。 可重入内置锁 使用wait/notify/notifyAll实现线程间通信 可以通过调用Object对象的wait()方法和notify()方法或者说notifyAll方法来实现线程间通信。在线程中调用wait()方法,将阻塞等待其他线程的通知,在线程中调用notify()方法或notifyAll方法,将通知其他线程wait()方法处返回。 notify()、notifyAll()、wait()、wait(long)和wait(long,int),他们都被声明为final,因此在子类中不能覆写任何一个方法。 如果调用wait()时,没有持有适当的锁,则抛出IllegalMonitorStateException; 如果调用notify()时没有持有适当的锁,也会抛出IllegalMonitorStateException 如果线程调用了对象的wait方法,那么线程便会处于对该对象的等待池中,等待池中的线程不会去竞争该对象的锁; 当线程调用了对象的notiAll方法或者notify方法,被唤醒的线程便会进入该对象的锁池中,锁池中的线程会去竞争该对象锁; 优先级高的线程竞争到对象锁的概率大,如果没有竞争到对象锁那么他会留在锁池中只有线程再次调用wait方法的时候,它才会再次进入等待池中。竞争到对象锁的线程则会继续向下执行,直到执行完了synchronized代码块,才会释放掉对象锁,此时锁池内线程会继续竞争该对象锁。 Error和Exception的区别 Error是Throwable的子类用于标记严重错误,合理的应用程序不可以用try/catch这种错误。绝大多数错误都是非正常的,不应该出现的。 Exception是Throwable的子类,用于指示合理的程序想去catch的条件,即它仅仅是一种程序运行的条件,而非严重错误。 checked exceptions: 通常是从一个可以恢复的程序中抛出来的,并且最好能够从这种异常中使用程序恢复。比如FileNotFoundException, ParseException等。 unchecked exceptions:就是程序中的bug Java中的异常处理机制的简单原理和应用 Java中通过面向对象的方式,把各种异常进行了分类,并且提供了良好的接口,在Java中每一个异常就是一个的对象。当一个方法抛出异常的时候便抛出了一个异常对象,该对象内包含异常的信息,调用这个对象的方法就可以捕获到这个异常并进行处理。 try/catch的执行过程 一般情况由try来执行一段程序,如果出现异常,系统则会抛出一个异常,此时程序员可以通过他的类型进行捕捉(catch操作),或在最后(finally)由缺省处理器来进行处理。 用try来指定一块预防所有“异常”的程序。紧跟在try程序后面,应包含一个catch子句来指定你想要捕捉的“异常”的类型。throw语句用来明确地抛出一个“异常”。throws用来标明一个成员函可能抛出的各种“异常”。Finally为确保一段代码不管发生什么“异常”都被执行一段代码。 try{ return} catch{} finally{}; return 还是 finally 先执行? 任何执行try或者catch内的return语句之前,都会先执行finally语句,如果finally存在的话。 如果finally中有return语句,那么程序就return了,所以finally中的return是一定会被return的 在try语句中,在执行return语句时,要返回的结果已经准备好了,就在此时,程序转到finally执行了。在转去之前,try中先把要返回的结果存放到不同于x的局部变量中去,执行完finally之后,在从中取出返回结果,因此,即使finally中对变量x进行了改变,但是不会影响返回结果。 二十四、序列化 对象Object读写是哪两个流 ObjectInputStream ObjectOutputStream 什么是Java序列化,如何实现序列化? 序列化就是一种用来处理对象流的机制,所谓对象流就是讲对象的内容流化。可以对流化后的对象进行读写操作,也可将流化后的对象传输于网络之间。序列化是为了解决在对对象流进行读写操作时所引发的问题。 实现:Serializable接口和Parcelable接口 Serializable和Parcelable的区别 两者最大的区别在于存储媒介的不同,Serializable使用IO读写存储在硬盘上,而Parcelable是直接在内存中读写,很明显内存的读写速度通常大于IO读写,所以在Android中通常优先选择Parcelable。 二十五、反射 反射机制 运行状态中,对于任意一个类,都能够知道这类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能被称为Java语言的反射机制。 反射机制的用处 1、观察或者操作应程序的运行时行为; 2、调试或测试程序,因为可以直接访问方法、构造函数和成员字段; 3、通过名字调用不知道的方法并使用该信息来创建对象和调用方法。 二十六、泛型 泛型的优缺点 优点: 使用泛型可以最大限度的重用代码、保护类的安全以及提高性能。 缺点: 性能上不如数组快 二十七、网络 网络参考模型 四层分法:应用层、运输层、网络层、网络接口层 七层分法:应用层、表示层、会话层、运输层、网络层、数据链路层、网络层 Tcp与UDP的区别 1、tcp是面向有链接的通信服务;udp是面向无连接的通信服务 2、tcp传输可靠;udp传输不可靠、会丢包 3、tcp保证数据顺序;udp不保证数据顺序; 4、tcp无边界;udp有边界; 5、tcp传输速度慢;udp传输速度快; 6、tcp面向字节流;udp面向报文 7、tcp一对一;udp一对一或者一对多 TCP:面向连接、传输可靠(保证数据正确性,保证数据顺序)、用于传输大量数据(流模式)、速度慢,建立连接需要开销较多(时间,系统资源)。 UDP:面向非连接、传输不可靠、用于传输少量数据(数据包模式)、速度快。 get和post请求的区别 1、get请求能被缓存;post请求不能被缓存 2、get保存浏览器浏览记录;post不保存浏览器浏览记录; 3、get请求的url可以保存为浏览器书签;post的不可以; 4、get请求长度有限制;post请求长度无限制 5、get请求主要用以获取数据;post提交数据 6、post请求相对安全 Tcp的三次握手 1、客户端发送:SYN=1,SEQ=X,端口号 2、服务的回复:SYN=1,ACK=X+1,SEQ=Y 3、客户端发送:ACK=Y+1,SEQ=X+1 tcp的四次挥手 1、A向B提出停止连接请求,FIN = 1 2、B收到,ACK = 1 3、B向A提出停止连接请求,FIN = 1 4、A收到,ACK = 1 优点:稳定可靠 缺点:传输慢效率低、容易受攻击 udp传输的优缺点 优点:传输速率快,较安全 缺点:不可靠、不稳定 用udp进行通信如何知道目标机是否获得到数据包? 仿TCP的做法,每发一个UDP包,都在里面加一个SEQ序号,接收方收到包后,将SEQ序号回复给发送方。如果发送方在指定时间以内没有收到回应,说明丢包了。 为什么udp比tcp快? 1、无需三次握手 2、tcp有拥塞控制,控制流量等机制 为什么tcp比udp可靠? 1、TCP是面向有连接的,建立连接之后才发送数据;而UDP则不管对方存不存在都会发送数据。 2、TCP有确认机制,接收端每收到一个正确包都会回应给发送端。超时或者数据包不完整的话发送端会重传。UDP没有,因此可能丢包。 什么时候使用Tcp? 当对网络通信质量有要求的时候 例如 浏览器 什么时候使用udp? 当对网络通讯质量要求不高的时候,要求网络通讯速度能尽量的快,这时就可以使用UDP TCP无边界,UDP有边界 TCP:客户端分多次发送数据给服务器,若服务器的缓冲区够大,那么服务器端会在客户端发送完之后一次性接收过来,所以是无边界的; udp:客户端每发送一次,服务器端就会接收一次,也就是说发送多少次就会接收多少次,因此是有边界的。 scoket编程的步骤 1、 创建Socket; 2、 打开连接到Socket的输入/出流; 3、 按照一定的协议对Socket进行读/写操作; 4、关闭Socket.(在实际应用中,并未使用到显示的close,虽然很多文章都推荐如此,不过在我的程序中,可能因为程序本身比较简单,要求不高,所以并未造成什么影响。)

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

Hadoop零基础入门

转自:http://blog.csdn.net/column/details/13153.html 【Hadoop入门学习系列之一】Ubuntu下安装Hadoop(单机模式+伪分布模式) 【Hadoop入门学习系列之一】Ubuntu下安装Hadoop(完全分布模式) hadoop安装配置中的权限管理 【Hadoop入门学习系列之二】HDFS架构和编程 【Hadoop入门学习系列之三】YARN原理和资源调度 【Hadoop入门学习系列之四】MapReduce 2.0应用场景和原理、基本架构和编程模型 【Hadoop入门学习系列之五】MapReduce 2.0编程实战 【Hadoop入门学习系列之六】HBase基本架构、编程模型和应用案例

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

QTQuick控件基础(3)视图

1、spliteview 2、stackview ApplicationWindow {visible:truewidth:640height:480MouseArea{anchors.fill:parentacceptedButtons:Qt.LeftButton|Qt.RightButton|Qt.MiddleButtononClicked:{if(mouse.button===Qt.LeftButton ){stackView.push([blueView,greenView,yellowView]);}elseif(mouse.button===Qt.RightButton){stackView.pop();}else{stackView.push({item:orangeView,replace:ture})}}}Rectangle {id:blueView;color:"blue"}Rectangle {id:greenView;color:"green"}Rectangle {id:yellowView;color:"yellow"}Rectangle {id:orangeView;color:"orange"}StackView{id:stackViewanchors.fill:parentinitialItem:Item{id:redViewRectangle{anchors.fill:parent;color:"red"}}}} 3、messagedialog ApplicationWindow {visible: truewidth: 640height: 480Button{id:windowwidth: 300height: 300anchors.centerIn: parentonClicked: messageDialog.open()}MessageDialog{id:messageDialogtitle:"注意注意"text: "欢迎使用QTQuick"detailedText: "这里是具体文字"icon:StandardIcon.QuestionstandardButtons: StandardButton.Yes|StandardButton.Help|StandardButton.OpenonYes: {}onHelp: {}onAccepted: {}}} 来自为知笔记(Wiz) 目前方向:图像拼接融合、图像识别 联系方式:jsxyhelu@foxmail.com

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

.NET Timer控件基础用法

使用C#的Timer控件来实现定时触发事件,其主要参数如下: Timer.Enabled属性用于设置是否启用定时器 Timer.Interval属性,事件的间隔,单位毫秒 Timer.Elapsed事件,达到间隔时发生 示例: [csharp]view plaincopy usingSystem; usingSystem.Collections.Generic; usingSystem.Linq; usingSystem.Text; usingSystem.Timers; namespaceConsoleApplication1 { classProgram { staticvoidMain(string[]args) { System.Timers.TimeraTimer=newSystem.Timers.Timer(); aTimer.Elapsed+=newElapsedEventHandler(OnTimedEvent); //SettheIntervalto5seconds. aTimer.Interval=5000; aTimer.Enabled=true; Console.WriteLine("Press/'q/'toquitthesample."); while(Console.Read()!='q'); } privatestaticvoidOnTimedEvent(objectsource,ElapsedEventArgse) { Console.WriteLine("HelloWorld!"); } } }

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

1.python基础阶段

#python输出 print("xubin") #python注释法 print("hello word") '''print("徐彬") print("xubin")''' #print("xubin") #python标识符 abc = 1111 _bc = 222 print(abc+_bc) #python变量 a=5 a=a+1 a+=1 print(a) #python数据类型 '''数、字符串、列表list、元组tuple、集合set、字典dictionary''' a=10 b="i am a boy" c=["my","you"] d=("my","you") print(c) print(c[1]) print(d) print(d[0]) #元组不支持修改 a="faretesdfbfhs" #集合中元素不能重复 b="safnkrlewjroiuoitn" c=set(a) d=set(b) print(c&d) print(d|c) #字典 #{key1:value1,key2:value2} a={"name":"xubin","sex":"man","age":25} print(a['sex']) #python运算符 a='xubin' b='is' c='a man' print(a+" "+b+c) a=9 b=2 print(a/b) print(a//b) print(a%b) #python缩进 a=10 b=9 if(a>9): print(a) if(b==9): print(b) elif(a<10): print(abc) #python控制流 #程序执行流程叫程序的控制流:顺序结构,条件分支结构,循环结构,(中断结构break continue) score=91 if(90>score>=60): #if score<60 print("成绩为及格") elif(score>=90): print("成绩为优秀") else: print("成绩不及格") i=5 while(i<10): print(i) i+=1 a=["a","b","c","d"] for s in a: print(s) for i in range(0,10): print(i) #终止循环一次continue,终止循环break for j in range(0,8): if(j==5): continue print(j) for j in range(0,8): if(j==5): break print(j) #python输出乘法口诀 for i in range(1,10): for j in range(1,i+1): print(str(i)+"*"+str(j)+"="+str(i*j)+" ",end="") print() for i in range(9,0,-1): for j in range(i,0,-1): print(str(i)+"*"+str(j)+"="+str(i*j)+" ",end="") print()

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

C#基础知识

1.c#概述,c#语言及其特点;c#与.net框架关系 C#概述:C#是微软公司发布的一种面向对象的、运行于.NET Framework之上的高级程序设计语言,C#是一种安全的、稳定的、简单的、优雅的,由C和C++衍生出来的面向对象的编程语言 特点:1.简单 2.现代 3.面向对象 4.类型安全 5.相互兼容性 6.可伸缩性和可升级性 关系:.NET框架是由微软开发的,致力于敏捷软件开发、快速应用开发、平台无关性和网络透明化的软件开发平台。 C#只是用于编写运行在该平台上的一种语言。 2.编写第一个c#程序(注释,命名空间,类,Main方法,标识符,关键字,输入,输出语句,) [csharp] view plain copy using System; namespace ConsoleApp2 { class Program { static void Main(string[] args) { //输出 Hello word Console.WriteLine("Hello word"); //输入 Console.ReadLine(); } } } 3.变量与常量(值类型,引用类型,两者区别,枚举类型,类型转换,变量声明,变量作用域,变量赋值,常量) 值类型 引用类型 1、值类型的数据存储在内存的栈中;引用类型的数据存储在内存的堆中 2、值类型表示实际数据,引用类型表示指向存储在内存堆中的数据的指针或引用 枚举: 枚举使用enum关键字来声明,与类同级。 枚举是值类型,隐式继承自System.Enum,不能手动修改。System.Enum本身是引用类型,继承自System.ValueType。 枚举都是隐式密封的,不允许作为基类派生子类。 枚举类型的枚举成员均为静态,且默认为Int32类型。 每个枚举成员均具有相关联的常数值。 枚举成员不能相同,但枚举的值可以相同。 枚举最后一个成员的逗号和大括号后面的分号可以省略 类型转换: 1.(int)变量名[强制类型转换] 2.int.Parse(string 变量名) 3.int.TryParse(string s, out int result) Convert.ToInt32 变量赋值: 值类型变量的赋值:值类型变量中保存的是实际数据,在赋值的时候只是把数据复制一份,然后赋给另一个变量。 引用类型变量的赋值: 引用类型变量中保存的是“指向实际数据的引用指针”。在进行赋值操作的时候,它和值类型一样,也是先有一个复制的操作,不过它复制的不是实际的数据,而是引用(真实数据的内存地址)。所以引用类型的变量在赋值的时候,赋给另一变量的实际上是内存地址。这样赋值完成后,2个引用变量中保存的是同一引用,他们的指向完全一样。 变量声明: 数据类型 变量名=值; 常量: C#常量主要分为两种:编译时和运行时常量 1、编译时常量,在编译时便用该常量的值代替常量变量。 2、运行时常量,在运行时返回一个运行时常量的变量引用 4.表达式与运算符(表达式概念,运算符种类,运算符优先级) 表达式概念:变量常量运算符组成 1.带( )号,[ ]号, . 号的,new,typeof,sizeof,checked,x++,x--级别最高,先计算. 2.++x,--x,+,! 3.算术运算符,先,/,%,再+,- 4.关系运算符,先>,<,>=,<=,is ,as再==和!= 5.条件逻辑运算符&&和|| 6.条件运算符b?x:y 7,赋值运算符=,=,/=,+=,-= 5.字符与字符串(Char类,Char类的使用,String的基本使用,StringBulider的使用) 字符串是由多个字符组成,字符串是引用类型 字符:Char类在C#中表示一个Unicode字符。 3)ToUpper(转换为大写)和ToLower(转换为小写) string s="RaSer"; string s1=s.ToUpper();//s1="RASER"; string s2=s.ToLower();//s2="raser"; Trim() 出去两边的空格 string str=" dd "; string s=str.Trim();//s="dd"; Substring 截取字符<str>以index开始截取,并截取lenth个字符(string <str>.Substring(index,lenth)) string str="还在下雨"; string s=str.Substring(2,2);//s="下雨"; Remove删除字符串(字符) 在字符串中移除从startIndex开始,长度为length的字符串,剩下的字符合为一个新的字符串 、Insert 插入 在字符串的index位置上插入字符,原来的字符依次后移,变成一个新的字符串 string str="夜深了"; string s=str.Insert(1,"已经");// s="夜已经深了" Replace 字符串(字符也是可以的)替换,返回新的字符串 string str="好困呀"; string s=str.Replace("困","精神");//s="好精神呀"; 、Equals 比较两个字符串是否相等 6.流程控制语句(选择包括switch,迭代语句即循环(搞明白为什么可以循环),跳转(break,continue,goto,return)) [csharp] view plain copy int a=6; switch(a) { case:"4" console.writeline("4"); break; case:"5" console.writeline("5"); break; default console.writeline("666"); break; } break从循环体跳出 continue结束本次循环 goto无条件转移语句 return 跳出循环的同时也做函数返回 7.数组和集合(一维数组和二维数组的声明以及使用,ArrayList类,HashTable,List,Directory字典等常用集合(泛型和非泛型)) [csharp] view plain copy string[] names = new string[5];//动态初始化 string[] names1 = new string[3] { "张三", "李四", "王二" };//定义并且赋予初值 动态初始化 int[] array = { 1, 2, 3, 4, 5 };//静态初始化变量,系统会自动分配内存空间 int[,] array = new int[2, 3];//声明一个两行3列的数组 声明并且进行初始化 [csharp] view plain copy int[,] array = new int[2, 3] { { 1, 2, 3 }, { 1, 3, 4 } }; ArrayList类是一个特殊的数组。通过添加和删除元素,就可以动态改变数组的长度。 Dictionary表示键和值的集合。 8.属性和方法(属性和方法的概念以及使用,注意,新特性中的自动属性,方法的重载) 1、类的属性:对象所拥有的特征,在类中表示时称为类的属性。 2、类的方法:对象执行的操作称为类的方法。 重载: 方法名相同。 方法的参数类型、个数、顺序至少有一项不相同。 方法的返回类型可以不相同,但只有返回类型不同是不可以的。 方法的修饰符可以不相同,但只有修饰符不同是不可以的 9.结构和类(结构的概念,类的概念,声明,构造函数,对象的实例化,类和对象的关系,实例的和静态的) 10.密封类和密封方法 密封类使用sealed关键字进行修饰,它不能用作其他类的基类,并且他没有派生类,密封类的作用是防止其他类继承该类,密封方法是使用sealed关键字进行修饰的方法,他并不能影响类的继承,但它可以防止重写基类中特定的虚方法。 [csharp] view plain copy public sealed class SealClass { } public sealed override void MyMethod() { Console.WriteLine("这是一个密封方法!"); } 本文转自 宁金峰 51CTO博客,原文链接:http://blog.51cto.com/13243523/2047608,如需转载请自行联系原作者

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

android—label窗口——基础

今天写了一个关于label的显示窗口,代码量也挺简单的,大家一看就明白。不管在哪里我们做软件的都需要用到label 先让我们看一下图先。 packagecom.smart.widget; importandroid.content.Context; importandroid.util.AttributeSet; importandroid.view.LayoutInflater; importandroid.widget.LinearLayout; importandroid.widget.TextView; importcom.smart.acitivy.R; publicclassLabelEditextendsLinearLayout{ privateTextViewtextView; privateStringlabelText; privateintlabelFontSize; privateStringlabelPosition; publicLabelEdit(Contextcontext,AttributeSetattrs) { super(context,attrs); //读取labelText属性的资源ID intresourceId=attrs.getAttributeResourceValue(null,"labelText",0); //未获得资源ID,继续读取属性值 if(resourceId==0) labelText=attrs.getAttributeValue(null,"labelText"); //从资源文件中获得labelText属性的值 else labelText=getResources().getString(resourceId); //如果按两种方式都未获得labelTex属性的值,表示未设置该属性,抛出异常 if(labelText==null) { thrownewRuntimeException("必须设置labelText属性."); } //获得labelFontSize属性的资源ID resourceId=attrs.getAttributeResourceValue(null,"labelFontSize",0); //继续读取labelFontSize属性的值,如果未设置该属性,将属性值设为14 if(resourceId==0) labelFontSize=attrs.getAttributeIntValue(null,"labelFontSize", 14); //从资源文件中获得labelFontSize属性的值 else labelFontSize=getResources().getInteger(resourceId); //获得labelPosition属性的资源ID resourceId=attrs.getAttributeResourceValue(null,"labelPosition",0); //继续读取labelPosition属性的值 if(resourceId==0) labelPosition=attrs.getAttributeValue(null,"labelPosition"); //从资源文件中获得labelPosition属性的值 else labelPosition=getResources().getString(resourceId); //如果未设置labelPosition属性值,将该属性值设为left if(labelPosition==null) labelPosition="left"; StringinfService=Context.LAYOUT_INFLATER_SERVICE; LayoutInflaterli; //获得LAYOUT_INFLATER_SERVICE服务 li=(LayoutInflater)context.getSystemService(infService); LinearLayoutlinearLayout=null; //根据labelPosition属性的值装载不同的布局文件 if("left".equals(labelPosition)) linearLayout=(LinearLayout)li.inflate(R.layout.labeledittext_horizontal,this); elseif("top".equals(labelPosition)) linearLayout=(LinearLayout)li.inflate(R.layout.labeledittext_vertical,this); else thrownewRuntimeException("labelPosition属性的值只能是left或top."); //下面的代码从相应的布局文件中获得了TextView对象,并根据LabelTextView的属性值设置TextView的属性 textView=(TextView)findViewById(R.id.textview); textView.setTextSize((float)labelFontSize); textView.setTextSize(labelFontSize); textView.setText(labelText); } } 我看一下Label类 package com.smart.widget; import android.content.Context; import android.util.AttributeSet; import android.view.LayoutInflater; import android.widget.LinearLayout; import android.widget.TextView; import com.smart.acitivy.R; public class LabelEdit extends LinearLayout{ private TextView textView; private String labelText; private int labelFontSize; private String labelPosition; public LabelEdit(Context context, AttributeSet attrs) { super(context, attrs); // 读取labelText属性的资源ID int resourceId = attrs.getAttributeResourceValue(null, "labelText", 0); // 未获得资源ID,继续读取属性值 if (resourceId == 0) labelText = attrs.getAttributeValue(null, "labelText"); // 从资源文件中获得labelText属性的值 else labelText = getResources().getString(resourceId); // 如果按两种方式都未获得labelTex属性的值,表示未设置该属性,抛出异常 if (labelText == null) { throw new RuntimeException("必须设置labelText属性."); } // 获得labelFontSize属性的资源ID resourceId = attrs.getAttributeResourceValue(null, "labelFontSize", 0); // 继续读取labelFontSize属性的值,如果未设置该属性,将属性值设为14 if (resourceId == 0) labelFontSize = attrs.getAttributeIntValue(null, "labelFontSize", 14); // 从资源文件中获得labelFontSize属性的值 else labelFontSize = getResources().getInteger(resourceId); // 获得labelPosition属性的资源ID resourceId = attrs.getAttributeResourceValue(null, "labelPosition", 0); // 继续读取labelPosition属性的值 if (resourceId == 0) labelPosition = attrs.getAttributeValue(null, "labelPosition"); // 从资源文件中获得labelPosition属性的值 else labelPosition = getResources().getString(resourceId); // 如果未设置labelPosition属性值,将该属性值设为left if (labelPosition == null) labelPosition = "left"; String infService = Context.LAYOUT_INFLATER_SERVICE; LayoutInflater li; // 获得LAYOUT_INFLATER_SERVICE服务 li = (LayoutInflater) context.getSystemService(infService); LinearLayout linearLayout = null; // 根据labelPosition属性的值装载不同的布局文件 if("left".equals(labelPosition)) linearLayout = (LinearLayout)li.inflate(R.layout.labeledittext_horizontal, this); else if("top".equals(labelPosition)) linearLayout = (LinearLayout)li.inflate(R.layout.labeledittext_vertical, this); else throw new RuntimeException("labelPosition属性的值只能是left或top."); // 下面的代码从相应的布局文件中获得了TextView对象,并根据LabelTextView的属性值设置TextView的属性 textView = (TextView) findViewById(R.id.textview); textView.setTextSize((float)labelFontSize); textView.setTextSize(labelFontSize); textView.setText(labelText); } } 本文转自 llb988 51CTO博客,原文链接:http://blog.51cto.com/llb988/495893,如需转载请自行联系原作者

资源下载

更多资源
Mario

Mario

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

Nacos

Nacos

Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service 的首字母简称,一个易于构建 AI Agent 应用的动态服务发现、配置管理和AI智能体管理平台。Nacos 致力于帮助您发现、配置和管理微服务及AI智能体应用。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据、流量管理。Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。

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

用户登录
用户注册