首页 文章 精选 留言 我的

精选列表

搜索[零知识证明],共10004篇文章
优秀的个人博客,低调大师

AngularJs 知识

简介 1.通过指令扩展了 HTML,通过表达式绑定数据到 HTML; 2.一个 Js 框架; 3.指令: 通过被称为指令的新属性来扩展 HTML, 即为应用添加新功能 ng-directives扩展了 HTML ng-app指令定义一个 AngularJS 应用程序 ng-model指令把元素值(比如输入域的值)绑定到应用程序,一个作用域的变量。 ng-bind指令把应用程序数据绑定到 HTML 视图 ng-init指令初始化 AngularJS 应用程序变量 4.表达式: 把数据绑定到 HTML 表达式写在双大括号内:` expression ` 表达式把数据绑定到 HTML,这与ng-bind指令有异曲同工之妙 5. 模块(Module)定义了 AngularJS 应用。 控制器(Controller)用于控制 AngularJS 应用。 ng-app指令定义了应用,ng-controller定义了控制器。 指令 1.前缀 ng-; 2.ng-app:初始化一个 AngularJS 应用程序; 3.ng-init:初始化变量。 4.ng-model指令把元素值(比如输入域的值)绑定到应用程序。 5.ng-repeat:表示重复输出. 6.创建自定义的指令 6.重复 HTML 元素 7.创建自定义的指令 作用域($scope) 1.应用在 HTML (视图) 和 JavaScript (控制器)之间的纽带 2. 是一个对象,有可用的方法和属性 3. View(视图),即 HTML。 Model(模型),当前视图中可用的数据。 Controller(控制器),即 Js 函数,可以添加或修改属性。 scope 是模型。 scope 是一个 JavaScript 对象,带有属性和方法,这些属性和方法可以在视图和控制器中使用。 过滤器 1.过滤器可以使用一个管道字符(|)添加到表达式和指令中。 服务 1.在 AngularJS 中,服务是一个函数或对象,在你的 AngularJS 应用中使用。 2.$location服务,它可以返回当前页面的 URL 地址。 3.$http 服务,该服务向服务器发送请求,应用响应服务器传送过来的数据。 4.创建自定义服务 本文转自 sshpp 51CTO博客,原文链接:http://blog.51cto.com/12902932/1928069,如需转载请自行联系原作者

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

数据库知识:SQLServer变量相关知识介绍

1、概述 SQLServer变量对应内存中的一个存储空间。它和常量不同,变量的值可以在执行过程中改变。 2、分类 SQLServer变量根据作用范围不同主要分为局部变量和全局变量。 2.1.局部变量 局部变量是用户在程序中定义的变量,它仅在定义的程序范围内有效。局部变量可以用来保存从表中读取的数据,也可以作为临时变量保存计算的中间结果。 注意:局部变量名称的第一个字符必须为一个@。 示例: --定义两个局部变量 DECLARE@mint,@nint; --赋值 SET@m=9; SET@n=1; --查询 SELECT@m+@n; 2.2 全局变量 全局变量通常以@@开头。这些变量一般都是SQL Server中的系统函数,它们的语法遵循函数的规则。用户可以在程序中使用这些函数测试系统特性和SQL命令的执行情况。常用的全局变量如下: @@ERROR--最后一个SQL错误的错误号 @@IDENTITY--最后一次插入的标识值 @@LANGUAGE--当前使用的语言的名称 @@MAX_CONNECTIONS--可以创建的同时连接的最大数目 @@ROWCOUNT--受上一个SQL语句影响的行数 @@SERVERNAME--本地服务器的信息 @@TRANSCOUNT--当前连接打开的事物数 @@VERSION--查看SQLServer的版本信息 3.声明变量 3.1、简单声明 变量只有在声明后才能使用,可以使用DECLARE语句来声明变量。在声明变量时可以指定变量的数据类型和长度。 DECLARE@namenvarchar(30); 3.2 声明多个变量 声明多个局部变量,需要在定义的局部变量后使跟上一个逗号,然后指定下一个局部变量名称和数据类型。 DECLARE@Namenvarchar(30),@Ageint; 3.3 变量作用域 在使用变量时,需要注意变量的作用域。变量具有局部作用域,只在定义它们的批处理或过程中可见。作用域范围从声明变量的地方开始到声明变量的批处理或存储过程的结尾。 USEDB; GO DECLARE@Ageint; SET@Age=30; GO--结束符 select@Age--报错 4.变量赋值 在声明变量后,变量值被默认设置为NULL。可以使用SET或SELECT语句。SET是为变量赋值的首选方法。 变量也可以通过选择列表中当前所引用的值赋值。如果在选择列表中引用变量,则它应当被赋以标量值或者SELECT语句应仅返回一行。 示例: DECLARE@Ageint; --SELECT语句赋值 SELECT@Age=agefromt_userORDERBYagedesc;--返回最后一行的值 select@Age;

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

Linux初级知识

Linux内核创始人 : 芬兰人李纳斯.托瓦兹Linux是一套免费使用、自由传播的类unix操作系统特点是多用户、多任务、支持多线程和多CPU的系统Linux的发行版:比较知名的有Ubuntu、Redhat、Centos、FedoraLinux应用领域:通常服务器使用LAMP(Linux+Apache+Mysql+Php) LNMP(Linux+Nginx+Mysql+Php) Linux的启动过程,可以分为5个阶段1.内核的引导2.运行Int3.系统初始化4.建立终端5.用户登录系统 操作系统——》/boot--》init进程——》运行级别——》/etc/init.d--》用户登录

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

Java知识整理

Java面向对象的特征有哪些方面? 抽象 忽略与主题无关的其他信息 继承 extends的意思是扩展,即子类是父类的扩展。扩展的意义在于不需要重新造轮子,这也是继承的意义。 子类继承父类就可以得到父类的全部属性和方法,除了私有的属性和方法以及父类的构造方法。 Java 只允许单继承,目的是不想使得继承链过于复杂而导致系统难以维护。如果想”多继承”,可以使用接口代为实现。 如果没有指定父类,那么它的直接父类是java.lang.Object 继承会导致重写,子类有时会需要重写父类的方法,自身的行为替换父类的行为。方法的重写是实现多态的必要条件。重写需要符合三个条件 方法名、形参列表相同。返回值类型和异常类型,子类需要小于父类。访问权限,子类需要大于父类。 封装 封装的意思是想让你看到的就让你看到,不想让你看见的就隐藏起来。优点是高内聚低耦合。 高内聚:封装细节,保证安全。 低耦合:简化使用,便于扩展。 Java使用访问修饰符实现封装 private:私有的,只能在同一个类中使用 default:默认的,可以在同一个包中使用 protected:受保护的,可以由子类使用 public:公开的,可以被所有的类访问 一般使用peivate修饰属性,但提供get/set方法供外界访问。 多态 同一个方法调用,不同的对象可能会有不同的行为。例如同样是十一假期,有人会出去旅游,有人会宅在家里。 多态是方法的多态不是属性的多态。 多态的必要条件,继承、方法重写、父类引用指向子类对象。 java.util.comparator 接口是干什么? 如果我们需要控制某个类的次序并且这个类本身不支持排序,那么就可以建立一个类比较器来进行排序。 类比较器的只需要实现 java.util.Comparator 接口并实现对应的方法就可以了~ String类为什么使用final修饰 ? 如果String类可以被修改的话,那么就很难做到修改A中的String值的同时而不修改B中的String值。原因是String的两个引用有可能会来自同一块内存地址。 final修饰符是线程安全的,在创建后就不能修改,因此不会产生线程安全问题,所以可以在多线程环境下使用。 在现实生活中,如密码,如手机号码,如文件名称之类都是以String类型的方式存储,如果String不使用final修饰,那么就有可能账号和密码会被人不知不觉地修改了。Interger等包装类型也是同样的道理。而用于精确计算的BigDecimel类则不同,它主要是为了解决二进制不能很好的表示浮点数而设计的。 String类还是用了Static修饰符修饰,目的是方便调用。如果不使用Static,那么就不能在静态方法下直接调用String的方法或值,而必须使用new进行实例化。 String常量池的存储位置 在JDK1.6中 String存储在jvm的PermGen中,并且限制大小。同时该区域还用于存储类信息。 在JDK1.7中 String存储在heap 中, 大小无限制。 序列化是什么和什么时候使用序列化? 序列化在Java中一般指对象的序列化。具体含义是将对象转换为字节序列即二进制的过程。在这个过程中不仅仅保留当前对象的数据,而且会以递归地形式保存引用的每个对象的数据。利用对象序列化可以实现对对象的”深复制”。即复制对象本身以及引用的对象本身。序列化一个对象就可以得到整个对象序列。而反序列化则是将字节序列恢复为对象的过程。 pojo implements Serializable 序列化通常有两种用途,都是将对象写入字节流中。 当需要把对象的字节序列永久的保存到硬盘上时,一般以文件的形式。字节序列需要在网络上传输时。P:选择一种高效的序列化和反序列化方式可以提升整个架构的性能。 Java虚拟机内存中的堆区(heap),栈区(stack),和静态区(static/method)。 堆区 存储真正的对象,每个对象都包含一个与之对应的class信息,这个class信息的作用是得到操作指令。 特点:只有一个堆区,随着JVM的启动而创建,所有线程共享区域,因此不存放基本类型和对象引用,只存放对象本身。如果堆内存剩余的空间不足以创建对象,JVM会抛出OutOfMemoryError的错误。P:堆一般由程序员分配。 栈区 存放基本数据类型和引用数据类型。P:Strtus中的压栈出栈操作 特点:每个线程包含一个栈区,并且栈中的数据都是私有的。栈中的数据由编译器自动分配释放。当一段代码定义一个变量时,JVM就为该变量在栈中开辟空间,当该变量退出作用域时,JVM就释放该空间,这个空间就随时可以被其他变量使用。P:栈分为三个部分。基本类型变量区、执行环境上下文、操作指令区。 静态区 又名方法区,是所有线程共享的区域,存放所有的类信息(类名,类方法信息,类字段信息)和static修饰的变量。 特点:整个程序中永远唯一的元素。全局变量和静态变量都放一起。不同的是,初始化的全局变量和静态变量在一块区域,未初始化的全局变量和静态变量在相邻的另一块区域。 HashMap和HashTable的区别? HashMap是HashTable的轻量级的非线程安全的实现。它们都完成了Map接口。采用的算法hash/rehash都大概一样,底层也都是采用数据加链表结构实现,所以性能上不会有很大差异。除了HashMap和HashTable,Hash集合中还有一个HashSet,它里面存储的并不是key-value结构,仅仅是存储不重复的元素,相当于简化版的HashMap,内部采用HashMap实现,所有的value都是同一个Object,只是包含HashMap中的key而已。 主要的区别在于HashMap允许空键值,而HashTable不允许。 由于HashMap是非线程安全,所以效率上会高于HashTable。 HashMap将HashTable中的contains()改成了containsValue()和containsKey()。原因大概是便于阅读吧~ HashMap直接继承Map,而Hashtable继承Dictionary。 HashMap在多线程的环境下需要为方法提供外同步(Collections.synchronizedMap),而HashTable不需要。 int类型和Integer类型有什么区别? Java提供了两种不同的类型,数据类型和引用类型,int是Java的数据类型,Integer是Java的引用类型。不仅是int,Java为每个基本类型都准备了对应的引用类型。它们的行为和语义都不同。 大小和速度的问题 存储数据结构问题 缺省值不同的问题 String、StringBuffer和StringBuilder的区别? String是作为常量在Java中被定义的,而StringBuffer是变量,意味着它可以修改对象内容。如果需要经常对一个字符串进行修改那么就可以考虑使用StringBuffer,因为它不会生成新的对象。 JDK1.5新增了一个可变的字符序列StringBuilder,它与StringBuilder有兼容但不同步的API,是StringBuilder的一个简单替换,用于字符串缓冲区被单个线程使用的时候,Java建议优先使用StringBuilder,因为在大多数实现中,它比StringBuffer速度要快,并且使用方法基本相同。 什么是运行时异常和非运行时异常? 非运行时异常指的是编译时异常或者说受检异常,Java编译器强制要求这类异常在代码编写的时候就处理,或抛出或捕获。运行时异常指的是虚拟机正常运行中可能会遇到的异常。 说说你常见的异常 *Java.lang.NullPointerException 程序遇上了空指针,简单地说就是调用了未经初始化的对象或者不存在的对象,这个错误经常出现在创建图片(路径),使用数组(初始化)中。 java.lang.ClassNotFoundException 类不存在,注意检查类的名称和路径是否正确 java.lang.ArrayIndexOutOfBoundsException 数组越界访问 java.lang.IllegalArgumentException 方法参数错误 java.lang.IllegalStateException org.springframework.web.util.NestedServletException 写一个Singleton单例模式吧 单例模式的特点 单例模式中的类只能有一个实例单例类必须自己创建自己的实例单例类必须给其他对象提供实例 在计算机系统中,线程池、端口、缓存、日志、对话框、打印机、显卡的驱动程序常常被设计成单例模式,这主要是为了避免发生诸如两台计算机同时打印时打印机该如何工作的问题,还有就是端口冲突的问题。再例如听歌,一般音乐软件同一时间只能播放一首歌。,虽然你有两个耳朵,但是这不代表你开心同时听两首歌~ 单例模式有两种表现形式 // 第一种形式 Class Singleton { Private Singleton(){} Private static Singleton instance = new Singleton(); // 提供一个供外界访问本类的静态API Public static Singleton getInstance(){} } // 第二种形式 Class Singleton { Private static Singleton instance = null; // 创建静态访问器,为了防止两个线程同时进行对象的创建,加上同步锁 Public static synchronized Singleton getInstance(){ If (instance == null) { Instance = new Singleton(); } Return instance; } } J2EE常用的设计模式,并重点说一下工厂模式。 Factory(工厂模式)Factory Method(工厂方法模式)Prototype(原始模型模式)Singleton(单例模式)Adapter(适配器模式)Decorator(装饰模式)Proxy(代理模式)Observer(观察者模式) 工厂模式是最常用的模式之一,根据工厂模式实现的类可以根据提供的数据生成一组类中的某一个类的实例,通过这一组类有一个公共的抽象父类并且实现了相同的方法,但是这些方法针对不同的数据进行了不同的操作。首先需要定义一个基类,该类的子类通过不同的方法实现了基类中的方法,然后需要定义一个工厂类,工厂类可以根据条件生成不同的子类实例。当得到子类实例侯,开发人员可以调用基类的方法而不必考虑到底返回哪一个子类的实例。 写一个工厂模式 工厂模式是Java中最常用的模式,原理是利用Java反射机制和多态的特性。目的是让程序更灵活,可以使项目并行开发,其中的粘合剂就是接口和配置文件。 Interface InterfaceTest{ Public void getName(); } // 有了接口就可以根据接口 进行并行开发 // 程序员A Class Test1 implements InterfaceTest{ Public void getName(){ System.out.println(“test1”); } } // 程序员B Class Test2 implements InterfaceTest{ Public void getName(){ System.out.println(“test2”); } } // 工厂类 生产接口对象 // 在调用时得到的是接口对象,一个接口变量指向实现该接口的类对象 // 通过键获取值,而不是类的全路径 Class Factory{ Private static Properties pro = new Properties(); Static { try { // 加载配置文件 Pro.load(new FileInputStream(“xxx.xxx”)); } catch (Exception e) { e.printStackTrace(); } } private static Factory factory = new Factory(); private Factory(){}; Public static Factory getFactory() { return factory; } Public InterfaceTest getInterface() { InterfaceTest interfaceTest = null; try { // 根据key,获取value value为类的全路径 String classInfo = pro.getProperty(“name”); // 利用反射生成class对象 Class c = Class.forName(classInfo); Object obj = c.newInstance(); interfaceTest = (interfaceTest )obj; }catch (Exception e) { e.printStackTrace(); } return interfaceTest ; } } // 调用方法 class FactoryTest { public static void main(String[] args) { Factory factory = Factory.getFactory(); // 通过创建的实例调用获得接口对象的方法获取接口对象 InterfaceTest inter = factory.getInterface(); // 调用接口定义的方法 Inter.getName(); } } 说出ArrayList、Vector、LinkedList的存储性能和特性。 ArrayList和Vector都使用数组的方式存储数据。当数组元素大于实际存储的数据时以便增加和插入元素,它们都允许直接按序号索引元素,但是插入数据要涉及到数组元素移动等内存操作,所以索引数据块而插入数据慢,Vector由于使用了synchronized方法保证线程安全,因此性能上较ArrayList差。 LinkedList使用双向链表实现存储,按序号索引数据需要进行前向或后向遍历,索引速度慢。因为插入数据时只需要记录本项的前后项即可,插入速度较快。 Collection和Collections Collection是集合类的上级接口,继承于它的接口主要是Set和List。 Collections是针对集合类的一个帮助类,提供了一系列静态API,实现了对集合的搜索、排序、线程安全化等操作。 final、finally、finalized之间的区别? final用于声明属性、方法和类,分别表示该属性不可变、该方法不可覆盖、该类不可继承。 定义变量时加上final,代表一旦被初始化后就不可改变 将方法声明为final,则说明你已经知道这个方法提供的功能已经满足你要求不需要进行扩展,并且也不允许任何从此类继承的类来覆写这个方法。只能通过继承这个方法来直接使用。 当final用于类的时候,代表此类在继承树中是一个叶子类,如果你认为此类涉及已经很完美而不需要进行修改和扩展的时候就大胆使用它吧。 finally是异常处理结构语句的一部分,表示该代码块中的代码总是执行。如果是断电或者强行中断程序,则该块中的代码才不会被执行。 finalize是Object类中的一个方法,在垃圾回收器执行的时候会调用被回收对象的此方法,可以覆盖此方法提供垃圾回收时其他资源的回收,例如关闭文件。 说出你知道的线程同步方法 wait()使一个线程处于等待状态,并释放所持有对象的lock. sleep()使一个正在运行的线程处于睡眠状态,是静态方法,调用此方法要捕捉InterruptedException异常。 notify()唤醒一个处于等待状态的线程。注意是在调用此方法时,并不能确切知道唤醒的是那个等待状态的线程,也不是按优先级,而是由JVM确定唤醒的线程。 allnotity()唤醒所有处于等待状态的线程,注意不是给所有唤醒线程一个对象的锁,而是让它们竞争。 OverLoad 和 Override的区别 方法的重载和重写是Java多态的表现。前者是父子类之间,后者是同一个类之中。如果说子类中定义某方法与父类中的方法名称和参数都相同的话,我们就说该方法被重写了。如果在同一个类中定义了多个同名的方法,它们有不同的参数个数和参数类型,则称之为方法的重载。 interface和abstract 两者是Java面向对象的重要实现。声明方法的存在而不去实现它的类叫做抽象类,它的子类必须全部实现它父类的所有方法,否则它也是一个抽象类。抽象类不能有抽象构造函数和抽象静态方法。也不能被实例化,并且它只能被public、protected修饰符修饰。 接口是抽象类的变体。在接口中所有方法都是抽象的,并且它只可以定义static final的成员变量。Instanceof运算符可以用来决定某对象的类是否实现了接口。 什么情况下使用同步或者异步编程 如果数据将在线程间共享,正在写的数据以后或者已经可能被另一个线程读到,那么这些数据就是共享数据,就必须使用同步存取。 当应用程序在对象上调用了一个需要花费很长时间来执行的方法,例如下载操作,这个时候不希望程序等待方法的返回,你在下载音乐的同时也可以听音乐,这个时候就需要使用异步编程。类似这种场景下异步途径往往更具有效率。 GC是什么?为什么需要GC? 内存处理是程序员最容易出错的地方,忘记或者错误的内存回收会导致堆栈溢出系统崩溃等严重错误。Java并没有提供显示的释放已分配内存的操作方法,而是提供GC功能,用于自动检测对象是否超出作用域从而达到自动回收内存的目的。这个功能被称之为垃圾回收机制。 垃圾回收的优缺点?和回收机制 优点是程序员不再需要考虑内存管理,同时垃圾回收可以有效地防止内存泄露,有效地使用可用的内存。 缺点则是垃圾回收器作为一个单独的低级别线程运行,在不可预知的情况下对内存已经死亡或者长时间没有使用的对象进行清除和回收,程序员不能监测到异常情况,也不能实时调用垃圾回收器对对象进行垃圾回收。程序员可以手动调用System.gc(),但java语言规范并不保证GC一定会运行。 垃圾回收的机制有:分代复制垃圾回收、标记垃圾回收、增量垃圾回收。 启动一个线程使用start()还是run()? start()使线程所代表的虚拟处理机处于可运行状态,这意味着它可以由JVM调度并执行,但并不意味着线程就会立即执行。此时线程处于就绪状态。 run()线程体,包含要执行线程的内容,当线程得到CPU的时间片,就会开始执行相应线程的此方法。 使用start()开辟线程,使用run()执行线程。 为什么要有多线程? 线程的出现是为了更好的利用CPU,提高程序运行效率。 说一说你开发过程中常见到的runtime exception ClassCastException IndexOutOfBoundsException NullPointerException SystemException 线程池的实现原理 使用线程池对线程进行统一分配,调优,监控可以降低资源消耗,提高相应速度,提高线程的可管理性。 J2EE服务器会在启动时建立若干线程池连接,并一直维持不少于此数目的池连接,当客户端程序需要连接时,池连接程序会返回一个未使用的池连接并标记为忙。如果当前没有空闲连接,池驱动程序就新建一定数量的连接,新建连接的数量由配置参数决定,当使用的池连接调用完成后,池驱动程序将池连接标记为空闲,其他调用就可以使用这个连接。 forward和redirect forward转发是服务器请求资源,服务器直接访问目标地址的URL,将URL的响应内容读取过来,然后将这些内容再发送给浏览器,浏览器因此并不知道服务器发送的内容是从哪里来的,所以它的地址栏还是原来的地址。 redirect重定向是服务端根据业务逻辑,发送一个验证码,告知浏览器去请求某个地址,一般来说,浏览器会用刚才请求的参数重新请求,所以session、request参数都可以获取到。 Set集合中的元素不能重复,那么怎样区分重复与否呢?使用==还是equals()?它们有何区别? Set里的元素不能重复,那么可以使用iterator()方法区分是否重复。 equals()是判断两个Set是否相等。属于深度比较,为的是当两个分离的对象的内容和类型相匹配的话返回ture。而”==”是比较两个对象的引用是否指向同一个内存地址,也就是判断对象是否分离。 hashCode()通常被设计用于提高性能。它和equals()的区别就在于当两个对象相等(equals()),那么它们就一定拥有同样的哈希值,但如果两个对象的哈希值相等,则不一定代表这两个对象就一定相等。 Java中异常机制的简单原理和应用 当Java程序违反了java的语义规则时,虚拟机就会将发生的错误表示为一个异常。违反语义包括了两种情况。 Java类库内置的语义检查。如果数组下标越界则会引发IndexOutBoundsException;访问null对象时会引发NullPointerException。另一种是程序员扩展的语义检查,自定义异常并自由选择在何时使用throw关键字引发异常。所有自定义的异常都必须继承java.lang.Thowable。 XML文档定义有几种形式?它们有何本质区别?解析XML文档有几种方式? 两种形式:dtd和schema dtd(data type definition) 数据类型定义,用于描述XML文档的文档结构,是早期的XML文档定义形式。 schema 本身基于XML编写,在类型和语法的限定能力上比dtd强,处理也方便,因此正逐渐代替dtd成为新的模式定义语言。 本质区别:schema本身是xml,可以被xml解析器解析。(这也是从DTD上发展schema的根本原因) 解析方式:DOM、SAX、STAX等 DOM 处理大型文件时性能下降厉害,这个问题是由DOM的树结构造成的,这种结构占用的内存较多,而且DOM必须在解析文件之前把整个文档都装进内存,便于对XML的随机访问。 SAX 事件驱动型的XML解析方式。它按顺序读取XML文件,而不需要一次全部装载整个文件。当遇到像文件开头,文档结束或者标签开头与标签结束时会触发一个事件,用户通过在其回调事件中写入处理代码来处理XML文件,适合对XML的顺序访问。 STAX Streaming API for XML(StAX) Servlet Public void init(ServletConfig config); Public ServletConfig getServletConfig(); Public String getServletInfo(); Public void service(ServletRequest request, ServletResponse response); Public void destroy(); - init()方法在servlet生命周期中仅执行一次,在服务器装载servlet时执行。缺省的init()通常是符合要求的,不过也可以根据需要override,比如管理服务器端资源,一次性装入Gif图像,初始化数据库连接等。由于缺省的init()中设置了servlet的初始化参数,并使用了ServletConfig对象参数来启动配置,所以覆盖init()时,需要调用super.init()以确保仍然执行这些任务。 - service()是servlet的核心方法,在调用service()之前,应确保已完成了init()。对于HttpServlert,每当用户请求一个HttpServlet对象,该对象的service()就会被调用,HttpServlet缺省的service()中的服务功能就是调用与HTTP请求的方法对应的do功能,所以对于HttpServlet,一般都重写doPost()或者doGet()。 - destroy()在servlet的生命周期中也仅执行一次,在服务器停止并卸载servlet时执行,将servlet作为服务器进程的一部分进行关闭。缺省的destroy()是符合要求的,但也可以override。比如在卸载servlet时将统计的数字保存在文件中,比如关闭数据库连接。 - getServletConfig()返回一个servletConfig对象。该对象用来返回初始化参数和servletContext。servletContext接口提供有关servlet的环境信息。 - getServletInfo()提供有关servlet的信息,比如作者、版本、版权。 #throw和throws >throw语句用来明确地抛出一个异常 >throws用来表明一个成员函数可能抛出的各种异常 #排序有哪几种方法?请列举并口述用java实现快速排序。 >排序的方法有 * 插入排序(直接插入排序,希尔排序) * 交换排序(冒泡排序,快速排序) * 选择排序(直接选择排序,堆排序) * 归并排序 * 分配排序(箱排序,基数排序) >快速排序的伪代码 从a[0:n-1]中选择一个元素作为middle,该元素为支点。 将余下的元素分割为left和right两段。使left中元素都小于等于支点,而right中的元素都大于等于支点。 递归地使用快速排序方法对left进行排序,然后是right 所得出的结果为left+middle+right; #MVC的各个部分都有那些技术实现?怎么实现的? - Model 代表着业务逻辑,通过JavaBean实现 - View 是应用的表现层,用于用户交互,使用JSP页面技术实现 - Controller 应用程序处理过程控制,一般是Servlet >优点:开发效率高;程序灵活性和扩展性好;代码重用度高;便于人员分工。 >缺点:代码复杂度增加;代码数量增加;不适合开发小型程序。 #java中有几种方法可以实现一个线程?用什么关键字修饰同步方法?Stop()和suspend()为何不推荐使用? >有两种方法,分别是继承Thread类和实现Runnable接口。 >使用关键字synchronized修饰同步方法 >反对使用stop()是因为不安全。它会接触由线程获取的所有锁定,而且如果对象处于一种不连贯的状态,那么其他线程能在那种状态下检查和修改他们,结果很难检查出真正的问题所在.suspend()方法容易发生死锁。调用suspend()的时候,目标线程会停下来,但却仍然持有在这之前获取的锁定,此时,其他线程都不能访问锁定的资源,除非被”挂起”的线程恢复运行。对任何线程来说,如果它们都想恢复目标线程,同时又试图使用任何一个锁定的资源,就会造成死锁。所以不应该使用suspend(),而应在自己的Thread类中置入一个标志,指出线程应该活动还是挂起。若标志指出线程应该挂起,便使用wait()命令其进入等待状态,若标志指出线程应当恢复,则使用一个notify()重新启动线程。 #java中有几种类型的流?JDK为每种类型的流提供了一些抽象类以供继承,请说出他们分别是哪些类? >字节流、字符流。字节流继承InputStream OutputStream 字符流继承于InputStreamReader OutputStreamWriter >在java.io包中还有许多其他的流,主要是为了提高性能和使用方便 #内部类可以引用他包含类的成员吗?有什么限制? >一个内部类对象可以访问创建它的外部类对象的内容。 >内部类如果不是static,那么它可以访问创建它的外部类对象的所有属性。如果是static,即为nested class,那么它只可以访问创建它的外部类对象的所有static属性。 >一般类只有public或者package等访问修饰符。而内部类可以实现static、protected、private等访问修饰符。 >当从内部类继承的时候内部类是不会被覆盖的,它们是完全独立的实体,每个都在自己的命名空间内,如果从内部类中明确地继承,就可以覆盖原来内部类的方法。 #进程和线程的区别 + 进程 是相对于操作系统而言的。例如你一边听歌一边玩游戏,我们就会说此时系统内有两个进程在运行,专业的话说叫做多个程序几乎在同一时间执行多个任务。 + 线程 相对某一程序而言。例如你一边听歌一边看歌曲排行榜,还可以下载歌曲,这三件事情互相不会干扰,就可以说这一音乐程序至少有三个线程在运行,专业的表述为一个程序在同一时间内执行多个任务。 #你能说出TCP/IP的七层协议吗? >应用层,、表示层、会话层、传输层、网络层、数据链路层、物理层。 #在connection类中提供了3个控制事务的方法,说说它们。 - setAutoCommit(boolean bln) 保持数据的完整性。一个系统的更新操作可能要涉及多张表,需要多个SQL语句进行操作,循环连续的进行插入操作,如果在开始时设置了”conn.setAutoCommit(false);”,然后再进行”conn.commit()”。这样即使插入的时候报错,修改的内容也不会提交到数据库,而如果没有手动进行setAutoCommit,那么出错的时候就会造成,前几条数据插入成功而后几条数据插入失败的情况,这就是脏数据。 - commit() 提交事务,用于把事务所做的修改都保存到数据库中,它把上一个commit或者rollback命令之后的全部事务都保存到数据库中。 - rollback() 撤销事务,在事务运行的过程中发生了某种故障,事务不能继续执行,系统将事务中对数据库的所有已经完成的操作全部撤销,回滚到事务开始的状态,这里的操作特指数据库更新操作,并且回滚后,事务进入提交状态,因为回滚是回滚到事务开始时的状态。 #EL表达式的隐含对象 * applicationScope 应用程序范围内的scoped变量组成的集合 * cookie 所有cookie组成的集合 * header HTTP请求头部,字符串 * headerValues HTTP请求头部,字符串集合 * pageContext 当前页面的javax.servlet.jsp.PageContext对象 * initParam 全部应用程序参数名组成的集合 * pageScope 页面范围内所有对象的集合 * param 所有请求参数字符串组成的集合 * paramValues 所有作为字符串集合的请求参数 * requestScope 所有请求范围的对象的集合 * sessionScope 所有会话范围的对象集合 #简述Statement和PreparedStatement的区别 >无论多少次地使用同一SQL命令PreparedStatement都只对它解析和编译一次,当使用Statement对象时,每次执行一个SQL命令的时候都会对它解析和编译。因此使用PreparedStatement要比使用Statement速度要快。 #java中包的用途 * 允许将类文件组织起来,便于查找合适的类 * 包可以包含其他的,形成有层次的包空间 * 包有助于避免命名冲突 #请简述一下什么是流? >流是指一连串流动的字符,以先进先出的方式发送和接收数据的通道。流分为输入流和输出流,相对于内存而言,数据输入到内存就是输入流,反之就是输出流。 #java.io.reader和java.io.inputStream的区别? >两者共同组成了java输入类。Reader用于读入16位字符,即Unicode编码的字符;而InputStream用于读入ASCLL字符和二进制数据。 #请说出ArrayList和Vector的区别? - 同步性 数组序列是线程不安全也不同步的,而矢量队列则完全相反。 - 数据增长 需要增长时,数组序列增长原来的一半,而矢量队列增长一倍。 #super关键字是干什么的?为什么使用它?它的访问范围? >super用于解决如何直接访问或初始化从父类继承来的成员。 >在写子类无参数构造方法时,不用显式调用父类无参数构造方法,系统会自动提供,但在写子类带参数的构造方法时,应该在第一句写super(参数)来初始化父类成员变量 >访问范围包括父类属性、一般方法和构造方法 #Cookie和Session的区别与联系? - Session的概念 Session 是存放在服务器端的,类似于Session结构来存放用户数据。当浏览器第一次发送请求时,服务器自动生成一个Session和Session ID用来标识这个Session,并将通过相应发送到浏览器。当浏览器第二次发送请求,会将前一次服务器响应中的Session ID放在请求中一并发送到服务器上,服务器从请求中提取Session ID并和保存的所有Session ID进行对比,找到这个用户对应的Session。一般浏览器提供了两种方式来保存Session,还有一种是程序员使用HTML隐藏域的方式自定义实现。 使用Cookie实现保存,这是最常见的方法,例如”记住我的登录状态”这一功能就是通过这种方式实现的。服务器通过设置Cookie的方式将Session ID发送到浏览器。如果我们不设置过期时间,那么Cookie将不会保存在硬盘上,会随着浏览器的关闭而消失,Session ID也就不复存在了。如果我们设置这个时间为若干天后,那么这个Cookie会保存在客户端硬盘中,即使浏览器关闭,这个值仍然存在,下次访问相应的网站时同样会发送到服务器上去。 使用URL附加信息的方式,这也是有时候我们会在JSP网站上看到”xxx.jsp?JSESSIONID=x”的原因。这种方式和使用Cookie的方式中不设置过期时间是一样的。 第三种方式是通过在页面表单里增加隐藏域的方式,这种方式实际上跟URL附加信息的方式一样,只不过前者使用GET方式发送数据,后者使用POST方式发送数据,但是明显后者比前者麻烦。 - 会话技术 会话指的是用户登录网站后的一系列操作,例如浏览商品->添加到购物车->提交订单->付款。会话跟踪时WEB程序中常用的技术,用户跟踪用户的整个会话,常用的会话跟踪技术就是Session和Cookie。Session在服务端记录信息并确认用户身份,Cookie在客户端记录信息并确认用户身份。 - 区别 Cookie存储在浏览器客户端,Session存储在服务端,简单说,当你登录一个网站的时候,如果web服务器端使用的是session,那么所有的数据都保存在服务器上面,客户端每次请求服务器的时候会发送当前会话的session id,服务器根据当前session id判断相应用户数据标志,以确定用户是否登录或者具有某种权限。由于数据时存储在服务器上面,所以无法伪造,当时如果你能获取某个登录用户的session id,用特殊的浏览器伪造该用户的请求也是能够成功的。session id 是服务器和客户端链接时随机分配的,一般来说不会重复,但如果存在大量并发的请求,也不是没有重复的可能性。 - 联系 Cookie是Session的一种,但Cookie不会占用服务器资源,是存储在客户端内存或者一个cookie的文本文件中;而Session则会占用服务器资源,从这点上看,应该尽量使用Cookie而不是Session。 如果用户禁用cookie,那么可以采用url重写技术来进行页面处理,调用session中大量有用的方法从session中获取数据后置入页面。 - 应用场景 Cookie的典型应用时下次直接登录和在线商城的购物车的设计,当然这其中也会有一些安全和性能的问题存在。 由于Cookie的不安全性,所以一般会在Session上保存重要的信息。 #JSP的九大内置对象及其作用 >内置对象指的是可以不加声明和创建就可以在JSP脚本中使用的成员变量. >产生的时机:一个JSP页面对应一个Servlet类,每个Servlet有三个方法。init()初始化JSP;destory()销毁JSP;service()对用户请求产生相应的方法。Request和response是service()的形参,application、page、out、pageContext、session这些对象都是在service()中生成的实例。 * javax.servlet.httpServletRequest 客户端的请求信息被封装在request对象中,主要用于接受通过HTTP协议传送到服务器的数据,包括头信息,系统信息,请求方式以及参数等,作用域为一次请求。 * javax.servlet.httpServletResponse 代表对客户端的相应,主要是将JSP容器处理过的对象传回客户端,response对象只在JSP页面有效。 * Session Session是由服务器自动创建的与用户请求相关的对象,服务器为每个用户都生成一个session对象,用户保存用户的信息,跟踪用户的操作状态。它内部使用Map类来保存数据,即key/value,value可以是复杂的对象类型,而不仅仅局限于字符串类型。 * application Application对象可以将信息保存到服务器直到服务器关闭为止,可以认为是系统中的全局变量,是ServletContext类的实例。 * out 此对象用于在web浏览器内输出信息,并且管理应用服务器上的输出缓冲区,是JspWriter的实例。 * pageContext 此对象提供了对JSP页面内所有对象以及命名空间的访问,它的本类名也叫做pageContext。 * config 获取服务器的配置信息 * page 它是java.lang.Object的实例,代表着JSP本身,本质上包含当前Servlet接口引用的变量,可以看做Java编程中的this * exception 显示异常信息,只有在包含isErrorPage=”true”的页面上才可以使用。JAVA程序可以使用try/catch处理异常信息,但在JSP页面中出现异常就会生成exception对象,并把该对象传送到在page指令中设定的错误页面中,程序员在错误页面中处理exception对象即可。跟JAVA一样,JSP中exception对象也是由系统提供的继承机构,它实际上是java.lang.Throwable的对象。 #说一说你常用的Linux命令 * ls 显示文件或目录 -l 列出文件详细信息(list) -a 列出当前目录下所有的文件及目录,包括隐藏文件(all) * mkdir 创建目录 - p 创建目录,如果没有父目录则创建父目录(parent) * cd 切换目录 * touch 创建空文件 * echo 创建带有内容的文件 * cat 查看文件内容 * cp 拷贝 * mv 移动或者重命名 * rm 删除文件 -r 递归删除,删除文件时一并删除子目录及文件 -f 强制删除 * find 在文件系统中搜索某文件 * wc 统计文本中行数、字数、字符数 * grep 在文本文件中查找某个字符串 * rmdir 删除空目录 * tree 显示目录为树形结构,需要安装tree包 * pwd 显示当前目录 * in 创建链接文件 * more、less 分页显示文本文件内容 * head、tail 显示文件头、尾内容 * Ctrl+alt+F1 命令行全屏模式 ------系统管理命令------ * stat 显示指定文件的详细信息,比ls更详细 * who 显示在线登录用户 * whoami 显示当前操作用户 * hostname 显示主机名 * uname 显示系统信息 * top 动态显示当前耗费资源最多的进程信息 * ps 显示瞬时进程的运行状态,ps aux:以BSD格式显示进程;ps ef:以标准格式显示进程 * kill 杀死进程,一般使用ps或top命令查看进程的id,然后使用kill命令杀死对应进程。 * du 查看目录大小 -h 带有单位地显示目录信息 * df 查看磁盘大小 -h 带单位显示磁盘信息 * ifconfig 查看网络情况 * ping 测试网络连通 * netstat 显示网络状态信息 * man 帮助命令,使用-加上其他命令来查看对应参数的使用 * clear 清屏 * alias 对命令重命名 * sudo 允许系统管理员让普通用户执行一些或者root命令的工具 -b 在后台执行指令 -h 显示帮助 -H 将HOME环境变量设置为新身份的HOME环境变量 -k 结束密码的有效期,使用sudo的时候先输入密码,默认为5分钟有效期限 -l 列出目前用户可执行与无法执行的指令 -p 改变询问密码的提示符号 -s<shell> 执行指定的shell -u<用户> 以指定的用户作为新的身份,若无此参数,则默认使用root为新的身份 -v 延长密码有效期限5分钟 -V 显示版本信息 ------打包压缩相关命令------ * tar 打包压缩 -c 归档文件 -x 压缩文件 -v 显示压缩或解压缩过程(view) -f 使用档名 -z gzip压缩文件 -j bzip2压缩文件 例如 tar -cvf /home/java.tar home/java 只打包不压缩 tar -zcvf /home/java.tar home/java 打包并使用gzip压缩 ------打包压缩相关命令------ * shutdown -r 关机重启 -h 关机不重启 now 立即关机 * halt 关机 * reboot 重启 ------VIM相关命令------ Vim中有三种模式,命令模式、插入模式和编辑模式,使用ESC或i或:来切换模式。命令模式下 :q 退出 :q! 强制退出 :wq 保存并退出 :set number 显示行号 :set nonumber 隐藏行号 /java 在文档中查找java这个字符串,按n跳下一个,shift+n上一个 yyp 复制光标所在行,并粘贴 ------文件权限管理------ R 读 数值表示为4 W 写 数值表示为2 X 可执行 数值表示为1 更改权限命令语法 sudo chmod[u=所属用户/g=所属组/o=其他用户/a所有用户][+=增加权限/-=减少权限][r/w/x] 目录/文件名 #Java运行时区域 程序计数器:记录当前指令所在单元地址,也就是程序执行.class文件某行。由于存储的只是一个行数number,所以区域较小。在多线程环境中,每个线程拥有一个程序计数器,分别记录着各自程序的执行程序所在行数。 JVM栈:存放执行的方法,方法中的局部变量和对象的引用(对象的实例存放在堆中)。由于拥有着先进后出的特性,所以可以看做一个桶。对桶中数据的操作成为压栈和弹栈。 本地方法栈:存放执行的本地方法,即使用native关键字修饰的方法。当程序执行到本地方法时,程序计数器不会记录,而是使用undefined替代(undefined和null的主要区别在于null表示此处不应该有值,而undefined表示此处有值但是还没有定义) Java堆:存放类的实例和数组。分为新生代(young generation)和老年代(old generation),这样划分主要是为了方便垃圾回收器的工作,垃圾回收器会频繁地扫描新生代中的对象并进行垃圾回收,没有进行垃圾回收的对象就被移到了老年代中。 P:为了更加方便垃圾回收器的工作,JVM在新生代中又进行划分(eden和survicor)~~ 方法区:又被称为非堆,存放类的基本信息以及常量(final)和静态(static)变量,这些数据被定义为永久代,垃圾回收器不会回收这些数据。 P1:此方法区跟java中的方法没有任何关系~ P2:JDK文档中说方法区是JAVA堆逻辑上的一部分。 P3:在JDK8中取消了永久代而是使用了metespace替代 运行时常量池:存放字面量(例如int number = 10 中的10就是一个字面量)和符号引用(例如类与引用名的全限定名,List<Dept> deptList = new ArrayList<Dept>();中的deptList实际是一个java.lang.List) P1:常量池的出现是为了避免频繁的创建和销毁对象而影响到系统性能,其实现了对于对象的共享。例如字符串常量池就是在编译期间就把所有字符串文字放到一个常量池中。 P2:字符串常量池在JDK7时被移到了Java堆中(String name = “老王”中name作为引用存放到字符串常量池中,”老王”作为实例存放到堆中)。 P3:程序计数器、JVM栈和本地方法栈是线程私有的,Java堆、方法区和运行时常量池是线程共享的,因此一个多线程程序出现BUG,那么一定是线程共享中的区域出现了问题。 P4:Java规范中指出,除了程序计数器之外其他区域都有可能会发生OutOfMemoryError(内存溢出)异常。除了程序计数器和JVM栈其他区域都有可能会发生StackOverflowError(栈溢出)异常。使用JConsole(java自带)可以监控当前程序的内存和系统资源使用情况。 #常用的SQL语句 # stuscore 表中数据结构 stuid name subject score 1 张三 数学 91 1 张三 英语 89 1 张三 语文 87 2 李四 语文 89 2 李四 英语 28 2 李四 数学 99 3 王五 语文 66 3 王五 数学 24 3 王五 英语 32 4 朱六 数学 88 >计算每个人的总成绩并排名,要求显示字段:名字和总成绩 思路:根据名字分组 group by 根据成绩排名 order by SELECT name,SUM(score) FROM stuscore GROUP BY name ORDER BY SUM(score) >计算每个人的总成绩并排名,要求显示字段:名字、学号和总成绩 思路:DISTINCT 去重关键字 使用子查询先查询学号和总成绩 SELECT DISTINCT t1.name, subject,MAX(score) FROM stuscore t1, (SELECT stuid,SUM(score) AS allscore FROM stuscore GROUP BY stuid) t2 WHERE t1.stuid=t2.stuid ORDER BY t2.allscore DESC >计算每个人单科的最高成绩,要求显示字段:学号、姓名、课程、最高成绩 思路:有两种写法 #写法一 SELECT stuid,name,subject,MAX(score) FROM stuscore GROUP BY stuid #写法二 SELECT t1.stuid,t1.name,t1.subject,t1.score FROM stuscore t1, (SELECT stuid,MAX(score) AS maxscore FROM stuscore GROUP BY stuid) t2 WHERE t1.stuid=t2.stuid AND t1.score=t2.maxscore >计算每个人的平均成绩,要求显示字段:学号、成绩、平均成绩 思路:使用AVG()函数求出平均成绩,然后根据name分组 SELECT stuid,name,AVG(score) FROM stuscore GROUP BY name >列出各门课程成绩最好的学生,要求显示字段:学号、姓名、科目、成绩 #写法一,这种写法会出现问题 SELECT stuid,name,subject,MAX(score) FROM stuscore GROUP BY subject #写法二 SELECT s1.stuid,s1.name,s1.subject,s2.max_score FROM stuscore s1, (SELECT subject,MAX(score) AS max_score FROM stuscore GROUP BY subject) s2 WHERE s1.subject=s2.subject AND s1.score=s2.max_score >列出成绩最好的两位学生,要求显示字段:学号、姓名、成绩 思路:使用DESC将查询结果降序,然后使用limit截取列数 SELECT stuid,name,SUM(score) AS sumscore FROM stuscore GROUP BY name ORDER BY sumscore DESC LIMIT 2 #写法二,在SQL Server中的top关键字 SELECT top 2 * FROM stuscore ORDER BY sumscore DESC >列出数学成绩最好的学生 SELECT name,subject,score FROM stuscore WHERE subject=’数学’ ORDER BY score DESC >求出某位学生的数学成绩排名 思路:使用rownum临时变量输出mysql的排序后的行号 SELECT s.rowNo FROM (SELECT (@rowNum:=@rowNum+1) AS rowNo,name,subject,score FROM stuscore, (SELECT (@rowNum :=0)) b WHERE subject=’数学’ ORDER BY stuscore.’score’ DESC) s WHERE name=’张三’ >统计学科成绩优、良、及格的个数 SELECT subject, (SELECT COUNT(*) FROM stuscore WHERE score>80 AND score <=100) AS 优, (SELECT COUNT(*) FROM stusocre WHERE score>60 AND score <80) AS 良, (SELECT COUNT(*) FROM stuscore WHERE score<60) AS 不及格 FROM stuscore GROUP BY subject >使用SQL语句输出以下格式的数据 # 学号 姓名 语文 数学 英语 总分 平均分 SELECT stuid AS 学号,name AS 姓名, SUM(CASE WHEN subject=’语文’ THEN score ELSE 0 END) AS 语文, SUM(CASE WHEN subject=’数学’ THEN score ELSE 0 END) AS 数学, SUM(CASE WHEN subject=’英语’ THEN score ELSE 0 END) AS 英语, SUM(score) AS 总分,(SUM(score)/COUNT(*)) AS 平均分 FROM stuscore GROUP BY stuid,name >使用一条SQL语句查询出每门课都大于80的学生姓名 思路:使用HAVING()筛选成组后的各种数据,真实表中没有此数据,这些数据是通过一些函数生存。需要注意的是where子句在聚合前先筛选记录,作用于group by 和 having子句之前 SELECT name FROM stusocre GROUP BY name HAVING MIN(score)>=80 AND COUNT(subject)>=3 >修改表结构,学历 #添加列信息 Alter table stuscore add 学历 varchar(6); #删除列信息 Alter table stuscore drop column 学历; >修改表数据 朱六 #将数学成绩改为90 UPDATE stuscore SET score=90 WHERE name LIKE ‘朱六’; #删除表数据似乎不能使用like进行delete DELETE FROM stuscore WHERE stuid=4; >连接查询 # 当用户查看的数据来自于多张表的时候,连接查询会将多张表按照某个指定的条件进行记录的拼接。最终的结果是记录数可能会变化,但字段数一定会增加。 SELECT s1.*,s2.* FROM student AS s1 left join stuscore AS s2 ON s1.student_id = s2.stuscore_id #能介绍一下redis吗?在项目中你是怎么使用它的? >redis是最常用的非关系型数据库(Not-Only SQL)中的键值存储数据库(key-value),除了键值存储数据库之外还有文档型数据库(MongoDB)、图形(Graph)数据库(InfoGrid)、列存储数据库(HBase)。 对数据库高并发读写(High performance)的需求;对海量数据的高效率存储访问(Huge Storage)的需求;对数据库的高可扩展性(High Scalability)和高可用性( High Availability)的需求,带动了NOSQL的发展。 >redis是用C语言开发的一个开源的高性能键值对(key-value)数据库,类似于memcached(比之出色的地方在redis的value的最大限制是1GB,而memcached只有1MB),它通过异步的方式将整个数据库加载到内存中然后进行操作,因为是纯内存操作,所以性能很好。不仅仅是出色的性能,它还通过提供多种键值数据类型来适应不同场景下的存储需求。 - 字符串类型 redis没有采用C语言对字符串的处理方式,而是自定义了一个数据结构SDS(imple dynamic string),简单动态字符串。打开redis源码包,在src下的sds.h文件下查看sds的源码如下: struct sdshdr { // 字符串长度 unsigned int len; // buf数组中未使用的字节数量 unsigned int free; // 用于保存字符串 char buf[]; }; >C语言对字符串的存储是使用字符数组,遇到'\0'字符则认为字符串结束,而redis的字符串可以存储任何类型的数据,因为任何类型数据都可以表示成二进制,sds结构中的char buf[]就是存储了二进制数据。并且redis的字符串是二进制安全的,什么是二进制安全?简单理解就是存入什么数据取出的还是什么数据。redis中的sds不像c语言处理字符串那样遇到'\0'字符则认证字符串结束,它不会对存储进去的二进制数据进行处理,存入什么数据取出还是什么数据。 >应用:自增主键,例如电商项目中的订单号和商品编号都是采用String的递增数字特性生成,使用INCR(此命令用于将key中存储的数字值增1)命令完成。 定义商品编号key:items:id 192.168.101.3:7003> INCR items:id (integer) 2 192.168.101.3:7003> INCR items:id (integer) 3 散列类型 hash 如果有一个对象User以JSON序列化(String)的形式存储在redis,它的存储过程是User->JSON->Redis。该User对象有id、name、age等属性。如果在业务中只需要修改name属性,其他属性不做修改时该怎么做?如果采用传统的存储过程时必然会导致资源的的浪费,使用hash可以解决此问题。 hash会怎么做?它会提供字段与字段值的映射,并且规定字段值只能是字符串不能是散列或者集合类型。使用HSET(此命令不区分插入和更新操作,当执行插入操作时HSET命令返回1,当执行更新操作时返回0)命令对字段值做修改: HSET user name laowang 应用:商品信息,包括商品id、商品名称、商品描述、商品库存、商品好评 商品信息在redis中为item:1001 获取命令 HGET items:1001 id "3" HGETALL items:1001 1) "id" 2) "3" 3) "name" 4) "apple" 5) "price" 6) "999.9" 列表类型 -arrayList && linkedList ArrayList使用数组方式存储数据,所以根据索引查询数据速度快,而新增或者删除元素时需要设计到位移操作,所以比较慢。LinkedList使用双向链接(AB互相指向)方式存储数据,每个元素都记录前后元素的指针,所以插入、删除数据时只是更改前后元素的指针指向即可,速度非常快,然后通过下标查询元素时需要从头开始索引,所以比较慢,但是如果查询前几个元素或后几个元素速度比较快。 -List 列表类型可以存储一个有序的字符串列表,常用的操作是向列表两端添加元素,或者获得列表的某一个片段。列表类型内部是使用双向链表(double linked list)实现的,所以向列表两端添加元素的时间复杂度为0(1)(算法中的时间复杂度,它和空间复杂度被合称为算法的复杂度,是衡量算法重要指标),获取越接近两端的元素速度就越快。这意味着即使是一个有几千万个元素的列表,获取头部或尾部的10条记录也是极快的。 应用,商品评论列表 思路:在redis中创建商品评论列表,当用户发布商品评论时,将评论信息转成json存储到list中,用户在页面查询评论列表,从redis中取出json数据展示到页面。 定义商品评论列表key: 商品编号为1001的商品评论key:items: comment:1001 LPUSH items:comment:1001 '{"id":1,"name":"色情买家举报了!!!","date":20180510}' 集合类型 -set 集合的含义是每个元素的顺序不同,且没有顺序。集合类型的常用操作是向集合中加入或删除元素、判断某个元素是否存在等,由于集合类型的Redis内部是使用值为空的散列表实现,所有这些操作的时间复杂度都为0(1)。 Redis还提供了多个集合之间的交集、并集、差集的运算。 有序集合类型 - 在集合类型的基础上有序集合类型为集合中的每个元素都关联一个分数,这使得我们不仅可以完成插入、删除和判断元素是否存在在集合中,还能够获得分数最高或最低的前N个元素、获取指定分数范围内的元素等与分数有关的操作。 在某些方面有序集合和列表类型有些相似。 1、二者都是有序的。 2、二者都可以获得某一范围的元素。 但是,二者有着很大区别: 1、列表类型是通过链表实现的,获取靠近两端的数据速度极快,而当元素增多后,访问中间数据的速度会变慢。 2、有序集合类型使用散列表实现,所有即使读取位于中间部分的数据也很快。 3、列表中不能简单的调整某个元素的位置,但是有序集合可以(通过更改分数实现) 4、有序集合要比列表类型更耗内存。 应用:商品销售排行榜 根据商品销售量对商品进行排行显示,定义sorted set集合,商品销售量为元素的分数。 定义商品销售排行榜key:items:sellsort 写入商品销售量: 商品编号1001的销量是9,商品编号1002的销量是10 ZADD items:sellsort 9 1001 10 1002 商品编号1001的销量加1 ZINCRBY items:sellsort 1 1001 商品销量前10名: ZRANGE items:sellsort 0 9 withscores redis的主要缺点在于数据库容量受到物理内存的限制不能用作海量数据的高性能读写(意思就是要考虑那些低内存的用户电脑),因此redis最合适的使用场景是那些较小数据量的高性能操作和运算上,例如: 缓存(数据查询、短连接、新闻内容、商品内容等等)(最多使用) 分布式集群架构中的session分离。 聊天室的在线好友列表。 任务队列(秒杀、抢购、12306等等) 应用排行榜。 网站访问统计。 数据过期处理(可以精确到毫秒) redis不仅仅只能用命令的形式操作,主流的后端语言都有对应的客户端支持,java官方推荐使用jedis和redisson。jedis托管在github上,你可以通过https://github.com/xetorthio/jedis访问和下载jedis客户端。 Redis的高性能是由于其将所有数据都存储在了内存中,为了使Redis在重启之后仍能保证数据不丢失,需要将数据从内存中同步到硬盘中,这一过程就是持久化。Redis支持两种方式的持久化,一种是RDB方式,一种是AOF方式。可以单独使用其中一种或将二者结合使用。 RDB方式的持久化是通过快照(snapshotting)完成的,当符合一定条件时Redis会自动将内存中的数据进行快照并持久化到硬盘。RDB是Redis默认采用的持久化方式。Redis启动后会读取RDB快照文件,将数据从硬盘载入到内存。根据数据量大小与结构和服务器性能不同,这个时间也不同。通常将记录一千万个字符串类型键、大小为1GB的快照文件载入到内存中需要花费20~30秒钟。 P:通过RDB方式实现持久化,一旦Redis异常退出,就会丢失最后一次快照以后更改的所有数据。这就需要开发者根据具体的应用场合,通过组合设置自动快照条件的方式来将可能发生的数据损失控制在能够接受的范围。如果数据很重要以至于无法承受任何损失,则可以考虑使用AOF方式进行持久化。 默认情况下Redis没有开启AOF(append only file)方式的持久化,可以通过appendonly参数开启:appendonly yes。开启AOF持久化后每执行一条会更改Redis中的数据的命令,Redis就会将该命令写入硬盘中的AOF文件。AOF文件的保存位置和RDB文件的位置相同,都是通过dir参数设置的,默认的文件名是appendonly.aof,可以通过appendfilename参数修改:appendfilename appendonly.aof 为了保证redis不会因为重启等原因而导致数据丢失,redis提供了持久化的解决方案,redis服务重新启动后会将硬盘中的数据恢复到内存中,但是此过程中如果redis服务器的硬盘损坏的话可能就会导致数据丢失。为了更好的保证数据的完整性,避免这种单点故障,可以使用redis提供了主从复制机制。主redis(master)中的数据有两个副本(replication)即从redis1(slave)和从redis2(slave),即使一台redis服务器宕机其它两台redis服务也可以继续提供服务 redis中常见的性能问题和解决方案 master写内存快照(snapshotting),sava命令调度rdbSava函数会阻塞主线程的工作,当快照比较大时对性能影响非常大,会间断性暂停服务,所以master最好不要写内存快照。 master AOF持久化,如果不重写AOF文件,这个持久化方式对性能的影响是最小的,但是AOF文件会不断增大,AOF文件过大会影响master重启的恢复速度。master最好不要做任何持久化工作,包括内存快照和AOF日志文件,特别是不要启用内存快照做持久化,如果数据比较关键,某个Slave开启AOF备份数据,策略为每秒同步一次。 master调用BGREWRITEAOF(redis中的一个命令,作用是异步执行一个AOF文件重写操作。重写会创建一个当前AOF文件的体积优化版本,即使BGREWRITEAOF执行失败,也不会有任何数据丢失,旧的AOF文件在BGREWRITEAOF操作成功之前不会被修改。从redis2.4开始,AOF重写由redis自行触发,BGREWRITEAOF仅用于手动触发重写操作。)重写AOP文件,在AOP重写的时候会大量的占用CPU和内存资源,导致服务load过高,出现短暂暂停现象。 redis主从复制的性能问题,为了主从复制的速度和连接的稳定性,Slave和Master最好在同一个局域网下。 MySQL中有2000W数据,redis中只存了20W数据,那么如何保证reids中的数据都是热点数据。 redis内存数据集大小上升到一定大小的时候,就会施行数据淘汰策略(回收策略),redis提供了6种数据淘汰策略。 volatile-lru:从已设置过期时间的数据集(server.db[i].expires)中挑选最近最少使用的数据淘汰。volatile-ttl:从已设置过期时间的数据集(server.db[i].expires)中挑选将要过期的数据淘汰。volatile-random:从已设置过期时间的数据集(server.db[i].expires)中任何选择数据淘汰。allkeys-lru:从数据集(server.db(i).dict)中挑选最近最少使用的数据淘汰。allkeys-random:从数据集(server.db(i).dict)中任何选择数据淘汰。no-enviction(驱逐):禁止驱逐数据。 什么是spring框架,它有哪些模块,使用它有什么好处。 Spring框架是一个为Java应用程序的开发提供了综合、广泛的基础性支持的java平台,也是一个实现IOC和AOP的容器框架,设计理念就是简化开发。 spring框架集成了许多模块,常用的有spring ioc、spring aop,spring mvc、spring boot、spring security。 使用spring的好处 降低开发组件之间的耦合度,实现软件各层的解耦。 spring提供DI spring通过AOP技术完成了对事务的管理,使得开发人员不再需要手工控制事务,也不需要处理复杂的事务传播。同时提供的AOP技术可以很容易实现比如权限拦截、运行期监控、日志管理等功能 在Hibernate中管理事务 public void save(){ Session session = sessionFactory.getCurrentSession(); Session.beginTransaction(); Info info = new Info(“百度”); Info.setContent(“一家良心企业”); session.save(); session.getTransaction().commit(); } 在JDBC中管理事务 Connection conn = null; try{ conn.setAutoCommit(false); Statement stmt = conn.createStatement(); stmt.executeUpdate(update person where name=”老王”) conn.commit(); } catch(Exception e){ } final {conn.close()} 在spring中管理事务 @Transactional public void save(){ sessionFactory.getCurrentSession.svae(info); } 提供了很多辅助类,比如JdbcTemplate、HibernateTemplate,用于加快应用的开发 spring容器提供了单例支持(spring配置文件中定义的bean默认为单例模式),开发人员不需要编写代码来实现单例。 spring对于主流的框架,比如MyBatis、Hibernate提供了集成支持。 相对于其他集成框架,比如说EJB,spring IoC更加轻量级,使其在有限的内存和CPU资源下可以进行应用程序的开发和发布 请你谈一谈Spring的IOC和AOP? IOC是一种设计模式的实现,有两层实现。 对象的创建都不再由程序员控制,而是交由Spring控制,称之为控制反转。 对象的依赖关系由Spring的配置文件描述,并且这种关系只有在使用的时候才会建立,称之为依赖注入。 spring中的org.springfremework.beans包和org.springfreamework.context包构成了spring框架的IoC容器的基础,org.springframework.beans.factory.BeanFactory是spring IoC容器的具体实现,用于包装和管理各种bean,因此该接口是spring IoC的核心接口。ApplicationContext接口对BeanFactory进行了扩展,提供了message resource用于国际化的机制、事务传播和应用层的特别配置,比如针对WEB应用的WebApplicationContext。 AOP是一种编程思想,叫做面向切面,是OOP的延续和补充。P:这种在运行时,动态地将代码切入到类的指定方法,指定位置上的编程思想就是面向切面的编程。 在Spring中的具体实现是将系统中的非核心业务基于代理机制做提取,进行单独处理。比如事务,比如日志,比如安全授权等。 spring框架中大量使用了设计模式,请列举几个 代理模式 Spring AOP就是采用动态代理实现的,spring中有两种动态代理方式,jdk代理和cglib代理。 单例模式 Spring配置文件中的bean默认为单例 模版方法 Spring提供了许多模板类用于解决代码的重复问题,例如RestTemplate、JmsTemplate、JpaTemplate 前端控制器 Spring 提供给了DispatcherServlet来对请求进行分发 视图帮助 Spring提供了一系列的JSP标签,高效宏来辅助视图 工厂模式 使用BeanFactory创建对象实例

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

Spring小知识

两大核心功能:IOC、AOPIOC:动态注入,让一个对象的创建不用new了,可以自动的生产,实现原理利用java里的反射,反射就是在运行时动态的去创建、调用对象,Spring就是在运行时,跟xml Spring的配置文件来动态的创建对象,和调用对象里的方法的 。 AOP:面向切面编程,可以为某一类对象 进行监督和控制(也就是 在调用这类对象的具体方法的前后去调用你指定的 模块)从而达到对一个模块扩充的功能。这些都是通过 配置类达到的。

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

node知识学习

一、什么是node? node是js的运行环境,可以让js脱离前端单独运行 二、node的特点 1、单线程 无论是多少事情,都是一个线程去完成 单线程的优点:没有了多线程创建线程和销毁线程的开销,调度多线程也是需要消耗资源的。多线程,有多少事情就有多少线程去完成。 单线程的特点:无法利用多核cup,一旦陈谷被恶意的行为挂起,那么整个程序崩溃。 2、非堵塞I/O,在i/o进行的时候,线程不等待。阻塞I/O: 在i/o进行的时候,线程等待。 I:input O:output 读取文件、连接数据库读取数据库、操作光盘驱动器等等都叫做I/O。它们比较起内存和cpu的运行速度来说,是特别慢的。也就是说如果线程让硬盘读取一个比较大的文件。并且等待读取完毕并交给内存之后再去做别的事情。那么也就是说线程在等待读取(I/O)完成 3 事件驱动 事件驱动与非阻塞I/O是连着的一个事情。非阻塞I/O确实可以让线程在I/O进行的时候去做其它的事情,但是有个问题。线程去做了其它的事情,万一这个时候I/O完成了呢?怎么知道I/O什么时候完成?I/O完成的时候会触发一个事件,这个事件驱动着线程回来继续做下面的事情。 三、模块 3.1 内置核心模块 ——http http模块是用来搭建服务器的。 IncomingMessage : request OutgoingMessage : response METHODS : 这是一个数组里面装着所有的http请求方式 STATUS_CODES :是一个对象,对象的每个key都是一个状态码,对象的value是该状态码的含义 Server :是一个方法,用于将其它的服务转化成http服务 createServer : 是一个方法,用于创建服务 3.2 文件系统——file system Fs模块是用来操作文件的。所有的相关操作都是fs的方法。 创建文件并追加内容 3.3 url模块 Parse方法:将一个url路径,转成一个对象,对象有各种属性对应的就是不同的部分。 http://www.icketang.com/html/shouye/index.html?username=wanglaowu&password=123#123 上面的url字符串经过url模块的parse方法处理完会转变成以下对象 { Protocol:http, Host:www.icketang.com, Hostname:www.icketang.com, Port:null, Pathname:html/shouye/index.html, Search:?username=wanglaowu&password=123, Query: username=wanglaowu&password=123, Hash:#123, Href:http://www.icketang.com/html/shouye/index.html?username=wanglaowu&password=123#123 } parse方法还有第二个参数,是一个布尔值。默认为false。 如果为true,那么将会把返回的对象中的query选项转为一个对象。 url.format(urlObj) format这个方法是将传入的url对象编程一个url字符串并返回参数:urlObj指一个url对象 url解析get方法 Url模块是专门处理前端提交过来的请求地址的。 如何处理get请求: 1判断请求的方式 处理 如何处理post请求: 1判断请求的方式 if(req.method===”post”){ //code... } 2给req绑定data事件 if(req.method===”post”){ var str=“”; req.on(“data”,function(data_chunk){ //这个事件是post每发送一次数据,就会触发一次,回调函数中的参数是data_chunk表示的是这一次所 传递的数据。 str += data_chunk; }) req.on(“end”,function(){ //这个事件是post发送数据完毕之后才最终触发一次。所以说先触发1次或者多次data事件,再触发1次end事件。后续代码要写在end事件中 }) } 3.4 文件上传 formidable 3.5 express Express是第三方模块,用来快速开发一个服务器。 express中间件 Express内置的唯一中间件就是静态资源中间件。 req是前端传递过来的请求。 Req.query表示的是get请求携带的数据 包含在路由每个查询字符串参数的属性的对象。如果没有查询字符串,它是空的对象,{}。 Req.params表示的是从pathname上获得的数据 包含映射到指定的路线“参数”属性的对象。例如,如果你有路线/user/:name,那么“名”属性可作为req.params.name。这个对象默认{}。 Req.body 表示的是post请求携带的数据 (必须得先应用中间件:body-parser); 包含请求主体提交的键值对。默认情况下它是undefined。除非你使用了body-parser 例如:app.use(body_parser.urlencoded({extended:false})); Body-parser中间件: Ejs模板 Express允许我们像使用php那样(或者说是underscore的模板)使用ejs模板。 Ejs模板必须是一个文件,文件的拓展名是ejs => index.ejs 内部的内容还是大体上是html只不过有一部分是<%=variable%>组成的。当渲染的时候,会从字典中与variable进行匹配。并替换。 Ejs模板不需要引入app.js主程序文件。但是必须要在express中声明,而且还要放到node_modules中,这样express就能够找到ejs模块了: app.set(“view engine”,”ejs”); App.set表示要设置什么东西,第一个参数就是要设置的内容。第二个参数是对第一个参数更详细的说明. 声明完了之后,就可以在某个路由的响应中使用res.render()进行渲染ejs模板了。 条件:第一个参数是要渲染的模板文件。(该文件必须要存在与主程序同级目录下的views文件夹中) 第二个参数是渲染该模板文件的字典。 4.自定义模块 在NodeJs中,每一个js文件天生就是一个模块。 每个模块都能够向外暴露一些东西。 核心模块暴露的内容是十分重要的,比如:http模块负责搭建服务器。Fs模块负责操作文件等 自定义模块,随便定义。 模块化开发有什么好处呢? 每个模块只负责提供功能。不会将变量注册到全局作用域下。 我们自己定义了一个js文件。可以通过require函数将它引入到其它的js文件中。 方法是: var app = require(“./app.js”); 此时,必须在同级目录下有app.js这个文件 另一个方法是:将app.js放在同级目录下的node_modules文件夹中(或者上级、上上级、一直到根目录) 此时可以这么写了: var app = require(“app.js”); 此时的查找顺序是只会查找node_modules。 向外暴露有三种方式:

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

Python知识梳理

这是个人学习笔记,非教程,内容会有些混乱 极简教程 数据类型 我们可以使用type()函数类获取对象的类型,Python3中内置数据类型包括:None,int,float,complex,str,list,dict,tuple,set,frozenset,range等,Python2中还有long类型,Python中并没有内置数组类型。 dict,list,set这些是可变类型(用户自定义类型也可变),可以改变类型对象的值;数值和字符串类型则是不可变的。 str与js一样,python中字符串即可用单引号也可用双引号表示 numbersPython3中数值类型有:int和float两种 list字面量表示:[1,1.0,False,'list'] 列表推导式,创建列表的一种简易方法: tuple字面量表示:(1,1.0,False,'tuple') range list、tuple、range均属于序列类型(Sequence Types) dict set/frozenset集合是不包含重复元素的数据集,frozenset是不可变的,set是可变的,可以使用字面量构建一个集合{1,2,2,4,5}会输出{1,2,4,5} 类型转换 Python中类型转换只需调用相关函数即可 函数 # 函数定义模板 def func_name([self,][args]): pass def say_hello(): print('hello python!') # python3.5之后,定义函数时可以添加类型说明 # 这里只是提供一个说明文档而非强制类型约束 def type_instruction(num:int)->int: return num 定义多返回值函数 # 多返回值函数,返回一个tuple对象 def multi_returns(): return 0,1 内置函数 Python中有许多内置函数: dir我们可以使用dir()函数来查看对象都含有哪些成员: map filter reduce不是内置函数,但也很有用 lambda Python中使用lambda关键字即可创建lambda表达式: *args 与 **kvargs *args和**kvargs都用于函数中接收多个参数,这里args和kvargs只是约定俗成的写法,可以换成其它的名称,但*和**则是必须的。*args和**kvargs的区别是,*args用于接受普通参数,**kvargs用于接受键值对参数。 三元运算符 面向对象 Python中一切皆对象(这句话理解起来并不是那么容易),包括函数(C#,JAVA中函数不能独立存在)。这里贴一篇以前写的文章:Python中的类、对象、继承 Python按引用传递对象,对于不可变对象在修改时会产生新的对象;而对于可变对象,所有的修改都会反映在原有对象上。 魔术方法是Python对象模型的重要部分。 可以动态的给对象/类型添加属性,若给类型添加属性,则该属性在已产生的实例上也是可见的: 异常与错误 Python中异常与错误类间关系如下:自定义异常只需继承Exception或各种Error类即可 异常处理 try: raise IOError('使用raise语句抛出异常') except IOError as err: print(err) else: print('未发生异常则执行') finally: pass 捕获多个异常类型: try: raise IOError() except (IOError,TypeError): pass with语句 with...as...语句等价于try...finally...,与C#中的using语句类似 命名规范 module_name, package_name, ClassName, method_name, ExceptionName, function_name, GLOBAL_VAR_NAME, instance_var_name, function_parameter_name, local_var_name. 应该避免的名称 单字符名称, 除了计数器和迭代器. 包/模块名中的连字符(-) 双下划线开头并结尾的名称(Python保留, 例如__init__) 命名约定 所谓”内部(Internal)”表示仅模块内可用, 或者, 在类内是保护或私有的. 用单下划线(_)开头表示模块变量或函数是protected的(使用import * from时不会包含). 用双下划线(__)开头的实例变量或方法表示类内私有. 将相关的类和顶级函数放在同一个模块里. 不像Java, 没必要限制一个类一个模块. 对类名使用大写字母开头的单词(如CapWords, 即Pascal风格), 但是模块名应该用小写加下划线的方式(如lower_with_under.py). 尽管已经有很多现存的模块使用类似于CapWords.py这样的命名, 但现在已经不鼓励这样做, 因为如果模块名碰巧和类名一致, 这会让人困扰. Python之父Guido推荐的规范 Type Public Internal Modules lower_with_under _lower_with_under Packages lower_with_under Classes CapWords _CapWords Exceptions CapWords Functions lower_with_under() _lower_with_under() Global/Class Constants CAPS_WITH_UNDER _CAPS_WITH_UNDER Global/Class Variables lower_with_under _lower_with_under Instance Variables lower_with_under _lower_with_under (protected) or __lower_with_under (private) Method Names lower_with_under() _lower_with_under() (protected) or __lower_with_under() (private) Function/Method Parameters lower_with_under Local Variables lower_with_under 包与模块 模块包含Python语句或定义的文件就是一个模块,文件名就是模块名。在一个模块中,模块名是全局变量__name__的值。 包包含__init__.py文件的文件夹即可视为一个包,包用于管理模块,可以防止模块命名冲突。如:A.C和B.C,分别表示A包中的C模块和B包中的C模块。 导入模块:import a、import a as alias、from a import *、from a import b,c Python解释器会先从内置模块中寻找导入的模块,然后从sys.path中指定的模块搜索路径寻找模块 测试 编写一个文件操作类,文件名为file_operator.py: # coding=utf-8 import codecs class FileOperator: def save_file(self, file_path, content, encoding="utf-8"): with codecs.open(file_path, "w", encoding) as f: f.write(content) 编写测试用例,文件名为test_file_operator.py: # coding=utf-8 import unittest class TestFileOperator(unittest.TestCase): def test_save_file(self): content = "file content \r\n 文本内容" opt = file.FileOperator() opt.save_file("1.txt", content) if __name__ == "__main__": unittest.main() 工具推荐 iPython VS Code PyCharm 小结 以上是自己近期学习Python的一些总结,全文的主要关注点在Python语言本身。掌握以上内容后,便可以用Python写些脚本,辅以其他第三方包或框架就可以干更多更复杂的事了。如,爬虫、数据分析、后端开发以及现在比较热的人工智能(其实,我是不建议追热点的)。 用了一段时间的Python后,会觉着Python挺有意思的。 最后附上一张,个人总结的语言学习套路: 推荐阅读 人生苦短,为什么我要用Python?Python风格规范Python语言规范[[Python]内存管理](https://chenrudan.github.io/blog/2016/04/23/pythonmemorycontrol.html)Python进阶Python 入门指南Python 3.7.0 documentation

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

基础知识

1. # 这是单行注释 2. """ 这是多行注释 """ IPO input process output python提供了两套索引体系 第一种叫正向递增序号,从0开始,0是第一个元素 arr[0:10] 第二种叫反向递减序号,从-1开始,-1是倒数第一个元素,逐渐反向递减 arr[-5:-1] input()函数,从控制台读取一行,可带参数input("请输入:") 定义一个变量接收返回值 temp = input() print()函数,输出 eval() 评估函数 去掉参数最外侧引号并执行余下的函数 8. if TempStr[-1] in ['F', 'f']: C = (eval(TempStr[0:-1]) - 32) / 1.8 print("转换后的温度是{:.2f}C".format(C)) # {:.2f}是一个占位符, :.2f表示将结果保留两位小数 elif TempStr[-1] in ['C', 'c']: F = 1.8 * eval(TempStr[0:-1]) + 32 print("转换后的温度是{:.2f}F".format(F)) else: print("输入的格式错误") type(eval(N)) == int 判断是不是某种类型 arr[-1]表示取最后一个元素,arr[0,-1] 截取第一个到倒数第二个子串,不包含最后一个 arr[0,arr.len()]

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

android关键知识

1、handler 与Looper 与MessageQueue 、Message关系 handler:是处理主线程(ui线程)处理耗时操作的线程,通过post message到MessageQueue队列中。使用handler须要实现 handlerMessage方法,通过更新主线程ui Looper:每一个Looper相应一个MessageQueue,在handler之前Looper.prepare()会初始化looper和MessageQueue。最后Looper.loop方法会去循环分发message到指定的handler,改api方法中有一句msg.target.dispatchMessage(msg); 这就是looper和handler之间的调用 2、hander与 AsyncTask的优缺点 AsyncTask实现的原理和适用的优缺点 AsyncTask,是android提供的轻量级的异步类,能够直接继承AsyncTask,在类中实现异步操作,并提供接口反馈当前异步运行的程度(能够通过接口实现UI进度更新),最后反馈运行的结果给UI主线程. 使用的长处: 简单,快捷 过程可控 使用的缺点: 在使用多个异步操作和并须要进行Ui变更时,就变得复杂起来. Handler异步实现的原理和适用的优缺点 在Handler 异步实现时,涉及到 Handler, Looper, Message,Thread四个对象,实现异步的流程是主线程启动Thread(子线程)执行并生成Message-Looper获取Message并传递给HandlerHandler逐个获取Looper中的Message,并进行UI变更。 使用的长处: 结构清晰,功能定义明白 对于多个后台任务时。简单,清晰 使用的缺点: 在单个后台异步处理时,显得代码过多,结构过于复杂(相对性) 3、android里面几种常见的存储方式 a、Content provider 1) ContentProvider为存储和读取数据提供了统一的接口 2) 使用ContentProvider,应用程序能够实现数据共享 3) android内置的很多数据都是使用ContentProvider形式,供开发人员调用的(如视频,音频。图片,通讯录等) 首先在Androidmanifest.xml中注冊provider权限,然后通过getContentResolver() 然后得到contentResolver()对象 能够对该应用进行类似数据库操作一样的增删改成,须要的參数是uri 和參数值,查询一般得到游标Cursor 通过遍历游标获取属性值 b、SharedPreferences 实际上SharedPreferences处理的就是一个key-value(键值对)。SharedPreferences经常使用来存储一些轻量级的数据. 通过getSharedPreferences()得到改SharedPreferences对象 然后得到edit对象用来put值到改对象中。最后须要edit.commit()来将改对象存储到文件里,最后是以文件形式保存在data/data的指定路径下 c、sqlite存储 SQLite是一种轻量级的小型数据库,尽管比較小,可是功能相对照较完好,一些常见的数据库基本功能也具有,在如今的嵌入式系统中使用该数据库的比較多。由于它占用系统资源非常少 须要继承SQLiteOpenHelper 然后helper.getWritableDatabase() 得到SQLiteDatabase 对象,该对象能够对数据进行增删改查操作,提供了key value形式的CURD方法 d、io流存储 e、webview网络存储 4。listview你是怎么优化的。 用viewHolder和convertview优化内存,降低view的实例化个数,当item1被滑出屏幕时。这时不须要创建新的item1的view实例,android里面提供了Recycler(重复循环器)构件,并且viewHolder是静态类,最快的方式是定义一个ViewHolder,将convetView的tag设置为ViewHolder,不为空时又一次使用就可以。 4.1,listview图片载入优化 1.decodeStream最大的秘密在于其直接调用JNI>>nativeDecodeAsset()来完毕decode。无需再使用java层的createBitmap,从而节省了java层的空间,而且设置图片的压缩比例,从而缩小内存使用 InputStream is = this.getResources().openRawResource(R.drawable.pic1);BitmapFactory.Options options=new BitmapFactory.Options();options.inJustDecodeBounds = false;options.inSampleSize = 10; //width。hight设为原来的十分一Bitmap btp =BitmapFactory.decodeStream(is,null,options);,2.回收图片缓存 if(!bmp.isRecycle() ){bmp.recycle() //回收图片所占的内存system.gc() //提醒系统及时回收} 5,view的刷新,之前说过 View 能够调用invalidate()和postInvalidate()这两个方法刷新 6,IPC及原理 7,Android多线程 8。Android为什么要设计4大组件,他们之间的联系。不设计行不行(主要是为了实现MVC模式。然而java中最难的模式也是这个,非常少有产品能将这个模式做得非常好【Technicolor的面试官问的这个】) 9,service的周期。activity的周期,谈下你对Android内部应用的了解,比方他做电话,以及联系人等等应用。框架层有非常多东西还是多看看。熟悉Android怎么做的,无论你做应用程开发还是应用框架层开发非常有优点。 版权声明:本文博客原创文章。博客,未经同意,不得转载。 本文转自mfrbuaa博客园博客,原文链接:http://www.cnblogs.com/mfrbuaa/p/4750555.html,如需转载请自行联系原作者

资源下载

更多资源
腾讯云软件源

腾讯云软件源

为解决软件依赖安装时官方源访问速度慢的问题,腾讯云为一些软件搭建了缓存服务。您可以通过使用腾讯云软件源站来提升依赖包的安装速度。为了方便用户自由搭建服务架构,目前腾讯云软件源站支持公网访问和内网访问。

Nacos

Nacos

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

Spring

Spring

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

Rocky Linux

Rocky Linux

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

用户登录
用户注册