React

1.React简介

React 起源于FackBook的内部项目,用于架设Instagram的网站。react拥有较高的性能,代码逻辑非常简单,越来越多的人开始关注和使用它。

特性:

1.声明式设计:React声明范式,可以轻松描述应用。

2.高效:React通过对DOM的模拟,最大限度地减少与DOM的交互。

3.灵活:React可以与已知的库或者框架很好的配合。

优点:

  1. 速度快:在UI渲染过程中,React通过在虚拟DOM中的微操作来实现对实际DOM的局部更新。

  2. 跨浏览器兼容:虚拟DOM帮助我们解决了跨浏览器问题,它为我们提供了标准化的API,甚至在IE8中都是没问题的。

  3. 模块化:为你程序编写独立的模块化UI组件,这样当某个或某些组件出现问题是,可以方便地进行隔离。

  4. 单向数据流:Flux是一个用于在JavaScript应用中创建单向数据层的架构,它随着React视图库的开发而被Facebook概念化。

  5. 同构、纯粹的javascript:因为搜索引擎的爬虫程序依赖的是服务端响应而不是JavaScript的执行,预渲染你的应用有助于搜索引擎优化。

    6.兼容性好:比如使用RequireJS来加载和打包,而Browserify和Webpack适用于构建大型应用。它们使得那些艰难的任务不再让人望而生畏。

缺点:

React本身只是一个V而已,并不是一个完整的框架,所以如果是大型项目想要一套完整的框架的话,基本都需要加上ReactRouter和Flux才能写大型应用。

2.Vue简介:

vue是一个构建数据驱动的web界面的库,准确来说不是一个框架,聚焦在V(view)视图层。

有以下特性:

1.轻量级框架

2.双向数据绑定

3.自定义指定

4.插件化

优点:

  1. 简单:官方文档很清晰,比 Angular 简单易学。

  2. 快速:异步批处理方式更新 DOM。

  3. 组合:用解耦的、可复用的组件组合你的应用程序。

  4. 紧凑:~18kb min+gzip,且无依赖。

  5. 强大:表达式 无需声明依赖的可推导属性 (computed properties)。

  6. 对模块友好:可以通过 NPM、Bower 或 Duo 安装,不强迫你所有的代码都遵循 Angular 的各种规定,使用场景更加灵活。

缺点:

  1. 新生儿:Vue.js是一个新的项目,没有angular那么成熟。

  2. 影响度不是很大:google了一下,有关于Vue.js多样性或者说丰富性少于其他一些有名的库。

  3. 不支持IE8

3.Angular 简介

angular是一款优秀的前端js框架,已经被用于Google多款产品当中。

特性:

1.良好的应用程序架构。

2.双向数据绑定。

3.指定。

4.HTML模板。

5.可嵌入,注入和测试。

优点:

  1. 模板功能强大丰富,自带了极其丰富的angular指令。

  2. 是一个比较完善的前端框架,包含服务,模板,数据双向绑定,模块化,路由,过滤器,依赖注入等所有功能;

  3. 自定义指令,自定义指令后可以在项目中多次使用。

  4. ng模块化比较大胆的引入了Java的一些东西(依赖注入),能够很容易的写出可复用的代码,对于敏捷开发的团队来说非常有帮助。

  5. angularjs是互联网巨人谷歌开发,这也意味着他有一个坚实的基础和社区支持。

缺点:

  1. angular 入门很容易 但深入后概念很多, 学习中较难理解.

  2. 文档例子非常少, 官方的文档基本只写了api, 一个例子都没有, 很多时候具体怎么用都是google来的, 或直接问misko,angular的作者.

  3. 对IE6/7 兼容不算特别好, 就是可以用jQuery自己手写代码解决一些.

  4. 指令的应用的最佳实践教程少, angular其实很灵活, 如果不看一些作者的使用原则,很容易写出 四不像的代码, 例如js中还是像jQuery的思想有很多dom操作.

  5. DI 依赖注入 如果代码压缩需要显示声明.

4.React JSX简介

jsx javascript的语法扩展。推荐在React 中使用JSX来描述用户界面。JSX咋看可能比较像是模板语言,但事实上它完全是在JavaScript内部实现的。

在jsx中使用表达式

可以任意的在Jsx当中使用JavaScript表达式,在JSX当中的表达式要包含在大括号里。

jsx本身其实也是一种表达式

在编译之后,jsx其实会被编译成普通的javascript对象。

jsx属性

可以使用引号来定义以字符串为值得属性。

jsx嵌套

如果jsx标签是闭合的,那么需要在结尾处 /> ,就好像xml/html一样。

警告:

因为 JSX 的特性更接近 JavaScript 而不是 HTML , 所以 React DOM 使用 camelCase 小驼峰命名 来定义属性的名称,而不是使用 HTML 的属性名称。

Jsx 防注入攻击

React Dom在渲染之前默认会过滤所传入的值。它可以确保你的应用不会被注入攻击。所有的内容在渲染之前都被转换成了字符串。这样可以有效地防止 XSS(跨站脚本) 攻击。

Jsx 代表Objects

babel 转义器会把Jsx转换成一个名为React.createElement()的方法调用。

React对象,读取DOC并保持数据内容一致

JSX 优势:

1.执行更快,在编译javascript后进行了优化。

2.类型安全,在编译过程中能发现错误。

3.使用jsx编写模板更加简单快速。

jsx推荐使用内联样式,camelStyle语法来设置内联样式

5.react demo 工程创建

如何使用react 命令搭建脚手架

安装全局的react的脚手架:npm install -g create-react-app /cnpm isntall -g create-react-app

安装react项目:创建项目文件夹 使用cmd命令 create-react-app project-name

启动项目命令:npm start

项目发布:npm run build

6.安装antd工程(antd 基于react开发ui框架)

全局安装antdesign命令: npm install antd-init -g

创建工程文件夹:antd-init

运行demo:npm start

7.react 进阶

react 采用声明式组件,高效而且灵活的用来构建用户界面的框架。

组件的好处:重复利用。

组件创建

props 属性传递 在组件属性中传递。

8.元素渲染

元素是构成react的最小单位i。

将元素渲染到DOM中

React开发应用中一般只会定义一个根节点。但是如果是在一个已有的项目中引入React的话,可能需要在不同的部分单独定义React根节点。

9.state &生命周期

react 的生命周期
img

属性:基本不会被更改

状态:可以被更改

this.setState(); 更改状态

10.事件处理

参数传递方式

1.箭头函数

2.传递事件 定义函数

React元素的事件处理和DOM元素很相似,但是语法是有所不同:

1 react 事件绑定属性的命名采用驼峰命名,而不是小写。

2 如果采用jsx的语法需要传入一个函数作为函数作为事件处理函数,而不是一个字符串json(DOM元素的写法)

11.列表&& key

渲染多个组件

可以通过使用{}在jsx内构建一个元素集合

key 用于识别DOM中的某些元素被增加或删除的时候帮助React识别哪些元素发生了变化。给数组中的每一个元素赋予一个确定的标识。

元素的key 只有放在其环绕数组的上下文中才有意义。

12.表单

HTML表单元素与React中的其他DOM元素有所不同,因为表单元素生来就保留一些内部状态。

13.如何引入css样式

import ‘css文件名’

两种方式:

1.内联

在js文件中引入css样式 import ‘./App.css’

在css文件中引入css样式 @import ‘绝对路径’

2.直接引用

14.如何使用for循环进行遍历

使用ES6中 的map 方法进行遍历 filter 方法遍历 foreach 遍历

15 状态提升

几个组件需要共用状态数据的情况,将共享数据进行状态提升到最近的父级组件当中进行管理。

Redux

快速入门-demo

简介:javascript 状态容器 可以存储数据的状态 统一管理和维护组件

使用原因: react 在一些问题上处理不好,如: 两个组件之间的通信—解决方案 提升state,通过父级进行分发。

react 的数据只能向下分发。

某个状态需要在任务状态下都要拿到的时候,如token。

Vue进阶:

vue的初始化的选项中用了data,methods,el,computed。

vue实例的data对象

数据绑定离不开data里面的数据,也是vue的核心属性,vue绑定数据到html标签的数据源泉,另外Vue框架会自动监视data里面的数据变化,自动更新到HTML标签上。本质原理是:Vue自动将data里面的数据进行递归抓取换成getter和setter,然后就可以自动转化成HTML标签,当然用getter和setter所以老的浏览器Vue支持的不够友好

data的数据类型:

1.类型是Object或者Function

2.如果是组件对象中,data必须是Function类型。

vue实例的computed

vue的计算属性会自动混入vue的实例中,所有的getter和setter的this上下文自动绑定为Vue实例,计算属性中定义的函数里面可以直接指向Vue实例的this;

methods

methods 将被混入到 Vue 实例中。可以直接通过 VM 实例访问这些方法,或者在指令表达式中使用。方法中的 this 自动绑定为 Vue 实例。

注意,不应该使用箭头函数来定义 method 函数 (例如 plus: () => this.a++)。理由是箭头函数绑定了父级作用域的上下文,所以 this 将不会按照期望指向 Vue 实例,this.a 将是 undefined。

watch

一个对象,键是需要观察的表达式,值是对应回调函数。值也可以是方法名,或者包含选项的对象。Vue 实例将会在实例化时调用 $watch(),遍历 watch 对象的每一个属性。

设置el的详解

限制:只在new创建的实例中遵守。

提供页面上已存在的DOM元素作为Vue实例的挂载目标,也就是说Vue绑定的元素去哪里找,可以是CSS选择器,也可以是HTMLElemenet实例。

在实例挂载之后,元素可以用vm.$el访问。

如果这个选项在实例化时有作用,实例将立即进入编译过程,否则,需要显示调用vm.$mount()手动开启编译。

Vue的生命周期

Vue实例有一个完整的生命周期,开始创建,初始化创建,编译模板,挂载DOM,渲染,更新,渲染,卸载等一系列的过程 生命周期就是指Vue实例从创建到销毁的过程就是生命周期。

vue的整个生命周期提供了一系列的js事件。

vue生命周期

ue提供的可以注册的钩子都在上图片的红色框标注。 他们是:

  • beforeCreate

在实例初始化之后,数据观测(data observer) 和 event/watcher 事件配置之前被调用。

  • created

实例已经创建完成之后被调用。在这一步,实例已完成以下的配置:数据观测(data observer),属性和方法的运算, watch/event 事件回调。然而,挂载阶段还没开始,$el 属性目前不可见。

  • beforeMount

在挂载开始之前被调用:相关的 render 函数首次被调用。

  • mounted

el 被新创建的 vm.$el 替换,并挂载到实例上去之后调用该钩子。如果 root 实例挂载了一个文档内元素,当 mounted 被调用时 vm.$el 也在文档内。

  • beforeUpdate

数据更新时调用,发生在虚拟 DOM 重新渲染和打补丁之前。 你可以在这个钩子中进一步地更改状态,这不会触发附加的重渲染过程。

  • updated

由于数据更改导致的虚拟 DOM 重新渲染和打补丁,在这之后会调用该钩子。

当这个钩子被调用时,组件 DOM 已经更新,所以你现在可以执行依赖于 DOM 的操作。然而在大多数情况下,你应该避免在此期间更改状态,因为这可能会导致更新无限循环。

该钩子在服务器端渲染期间不被调用。

  • beforeDestroy

实例销毁之前调用。在这一步,实例仍然完全可用。

  • destroyed

Vue 实例销毁后调用。调用后,Vue 实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁。 该钩子在服务器端渲染期间不被调用。

1
2


Vue实例的全局配置

官网

命令

Install作用

npm install -g npm

升级npm

nmp init或者npm init -y

初始化package.json文件,若都用默认参数则用 npm init -y

npm -v

查看npm版本

npm config set registry https://registry.npm.taobao.org

设置npm为淘宝镜像

npm config get registry

查看镜像

npm config edit

编辑npm 配置文件

npm help npm

打开本地的npm帮助文件,内容很详细

npm help config

查看config 命令的帮助文件,npm其他命令也可以用此方法看详细帮助

npm run start

运行package.json scripts节中名称为start的命令

例如:

{
// …
“scripts”: {
​ “start”: “node build.js”
}
}

npm view 模块名 versions

查看某个模块的所有版本,这个命令会联网,会有延迟。

(1)、npm install -g 模块名

(2)、npm install –save-dev 模块名

(3)、npm install –save 模块名

(4)、npm install

(1)全局安装

(2)自动把模块和版本号添加到dependencies部分,生产环境

(3)自动把模块和版本号添加到devdependencies部分,开发环境

(4)在带有package.json的文件夹中执行的作用是,按照package.json文件中的依赖包的配置安装所有依赖的包。

webpack 的学习

webpack可以打包,编译js,还可以预处理css,使用style-loader css-loader 对css打包,主要从以下几点进行讲述:

  • css的引入

  • 使用style-loader和css-loader打包css

  • 使用style-loader/url

  • 使用style-loader/useable

  • 使用style-loader的options配置

  • 使用css-loader的options配置

    loader的加载顺序是从右往左的。这里的编译顺序是先用css-loader将css代码编译,再交给style-loader插入到网页里面去。所以css-loader在右,style-loader在左。

全局安装:

npm install –global webpack

不推荐全局安装,因为全局安装将会锁定指定版本,并且在使用不同的webpack版本的项目中,可能会导致构建失败。

lodash一个一致性,模块化,高性能的javascript实用工具库

在安装一个要打包到生产环境的安装包时,你应该使用 npm install --save,如果你在安装一个用于开发环境的安装包(例如,linter, 测试库等),你应该使用 npm install --save-dev。请在 npm 文档 中查找更多信息。

npx npm包的一个执行器

ES5中的Import和Export

一个js文件代表一个模块,ES6 模块化使用到了import和export 在浏览器中导入和导出各个模块,

webpack 如何管理资源和图片?

webpack 打包思想:

webpack可以将网页所需要的js css 图片等资源整体打包压缩,用户只需要请求你打包后的文件,请求数量大大减少,节省浏览器响应时间,减少用户的等待时间。

webpack打包的思想:chunk思想;

webpack分析网页中的所需要的js文件,css文件,font文件,每个文件都是一块一块的,以及各自文件所依赖的文件,形成依赖树,然后 webpack根据文件类型,采用不同的loader进行处理加载, js文件用babel-loader将ES6转换,css根据post-loader做兼容处理,然后输入到html文件中。

简介:

今天突发奇想,虽然之前一直从事javaweb开发,一直想的是自己以后的工作方向也是java。其实现在想来自己在工作中前端和后端开发一半一半吧。而且这个个性化时代,页面的展示仿佛已经是重中之重了。但是现在的话自己没经历过一个完整的vue开发项目,所以只能从零开始学习了。

Vue简介:

Vue.js是当下很火的一个JavaScript MVVM库,它是以数据驱动和组件化的思想构建的。相比于Angular.js,Vue.js提供了更加简洁、更易于理解的API。

特点:

1.MVVM

2.组件化

npm —nodejs的包管理器

webpack — vue的组件都是通过.vue等自定义的组建都无法被用户端的各种浏览器解析,需要被翻译和打包生成.js文件。

vue-cli 用于生成模板的vue工程,脚手架。‘

vue-cli 脚手架的下载 npm install vue-cli -g

vue 模板下载 npm install –global vue-cli

npm install 下载依赖

npm run dev 启动项目

vue 项目目录:

目录/文件 说明
build 项目构建(webpack)相关代码
config 配置目录,包括端口号等。我们初学可以使用默认的。
node_modules npm 加载的项目依赖模块
src 这里是我们要开发的目录,基本上要做的事情都在这个目录里。里面包含了几个目录及文件:assets: 放置一些图片,如logo等。components: 目录里面放了一个组件文件,可以不用。App.vue: 项目入口文件,我们也可以直接将组件写这里,而不使用 components 目录。main.js: 项目的核心文件。
static 静态资源目录,如图片、字体等。
test 初始测试目录,可删除
.xxxx文件 这些是一些配置文件,包括语法配置,git配置等。
index.html 首页入口文件,你可以添加一些 meta 信息或统计代码啥的。
package.json 项目配置文件。
README.md 项目的说明文档,markdown 格式

img

axios简介:

axios 是基于Promise用于浏览器和nodejs的http客户端,本质上也是对原生XHR的封装,只不过它是对promise的实现版本,符合最新额ES6,本身具有的特性:

1.从浏览器中创建 XMLHttpRequest
2.支持 Promise API
3.客户端支持防止CSRF
4.提供了一些并发请求的接口(重要,方便了很多的操作)
5.从 node.js 创建 http 请求
6.拦截请求和响应
7.转换请求和响应数据
8.取消请求
9.自动转换JSON数据

:防止CSRF:就是让你的每个请求都带一个从cookie中拿到的key, 根据浏览器同源策略,假冒的网站是拿不到你cookie中得key的,这样,后台就可以轻松辨别出这个请求是否是用户在假冒网站上的误导输入,从而采取正确的策略

axios 既提供了并发封装,也没有fetch的各种问题,而且体积较小,是当前最应该选用的请求方式。

scope 配置项有5个属性,用于描述不同的作用域:

1.singleton

2.pototype

3.request

4.session

5.global-session

1.java中常用的集合类型

img

java 集合位于java.util 包中,所以当使用集合框架时需要进行import

2.集合接口

集合框架定义了一些接口。本节提供了每个接口的概述:

序号 接口描述
1 Collection 接口 Collection 是最基本的集合接口,一个 Collection 代表一组 Object,即 Collection 的元素, Java不提供直接继承自Collection的类,只提供继承于的子接口(如List和set)。Collection 接口存储一组不唯一,无序的对象。
2 List 接口 List接口是一个有序的 Collection,使用此接口能够精确的控制每个元素插入的位置,能够通过索引(元素在List中位置,类似于数组的下标)来访问List中的元素,第一个元素的索引为 0,而且允许有相同的元素。List 接口存储一组不唯一,有序(插入顺序)的对象。
3 Set Set 具有与 Collection 完全一样的接口,只是行为上不同,Set 不保存重复的元素。Set 接口存储一组唯一,无序的对象。
4 SortedSet 继承于Set保存有序的集合。
5 Map Map 接口存储一组键值对象,提供key(键)到value(值)的映射。
6 Map.Entry 描述在一个Map中的一个元素(键/值对)。是一个Map的内部类。
7 SortedMap 继承于 Map,使 Key 保持在升序排列。
8 Enumeration 这是一个传统的接口和定义的方法,通过它可以枚举(一次获得一个)对象集合中的元素。这个传统接口已被迭代器取代。

3.集合实现类

​ 标准集合类汇总于下表:

序号 类描述
1 AbstractCollection 实现了大部分的集合接口。
2 AbstractList 继承于AbstractCollection 并且实现了大部分List接口。
3 AbstractSequentialList 继承于 AbstractList ,提供了对数据元素的链式访问而不是随机访问。
4 LinkedList 该类实现了List接口,允许有null(空)元素。主要用于创建链表数据结构,该类没有同步方法,如果多个线程同时访问一个List,则必须自己实现访问同步,解决方法就是在创建List时候构造一个同步的List。例如:Listlist=Collections.synchronizedList(newLinkedList(...));LinkedList 查找效率低。
5 ArrayList 该类也是实现了List的接口,实现了可变大小的数组,随机访问和遍历元素时,提供更好的性能。该类也是非同步的,在多线程的情况下不要使用。ArrayList 增长当前长度的50%,插入删除效率低。
6 AbstractSet 继承于AbstractCollection 并且实现了大部分Set接口。
7 HashSet 该类实现了Set接口,不允许出现重复元素,不保证集合中元素的顺序,允许包含值为null的元素,但最多只能一个。
8 LinkedHashSet 具有可预知迭代顺序的 Set 接口的哈希表和链接列表实现。
9 TreeSet 该类实现了Set接口,可以实现排序等功能。
10 AbstractMap 实现了大部分的Map接口。
11 HashMap HashMap 是一个散列表,它存储的内容是键值对(key-value)映射。 该类实现了Map接口,根据键的HashCode值存储数据,具有很快的访问速度,最多允许一条记录的键为null,不支持线程同步。
12 TreeMap 继承了AbstractMap,并且使用一颗树。
13 WeakHashMap 继承AbstractMap类,使用弱密钥的哈希表。
14 LinkedHashMap 继承于HashMap,使用元素的自然顺序对元素进行排序.
15 IdentityHashMap 继承AbstractMap类,比较文档时使用引用相等。

在前面的教程中已经讨论通过java.util包中定义的类,如下所示:

序号 类描述
1 Vector 该类和ArrayList非常相似,但是该类是同步的,可以用在多线程的情况,该类允许设置默认的增长长度,默认扩容方式为原来的2倍。
2 Stack 栈是Vector的一个子类,它实现了一个标准的后进先出的栈。
3 Dictionary Dictionary 类是一个抽象类,用来存储键/值对,作用和Map类相似。
4 Hashtable Hashtable 是 Dictionary(字典) 类的子类,位于 java.util 包中。
5 Properties Properties 继承于 Hashtable,表示一个持久的属性集,属性列表中每个键及其对应值都是一个字符串。
6 BitSet 一个Bitset类创建一种特殊类型的数组来保存位值。BitSet中数组大小会随需要增加。

4.set 和list的区别

1.都是实现Collection 接口。

2.set 不允许元素重复,不允许元素为空;list可以重复元素。

  1. List和数组类似,可以动态增长,根据实际存储的数据的长度自动增长List的长度。查找元素效率高,插入删除效率低,因为会引起其他元素位置改变 <实现类有ArrayList,LinkedList,Vector>

5.Set的使用

set的两大实现类 TreeSet和HashSet

TreeSet 会将里面的元素默认排序。

HashSet :允许包含值为null的元素,但最多只能有一个null元素,不允许出现重复的元素。

6.LinkedList和ArrayList的区别:

ArrayList内部是使用可増长数组实现的,所以是用get和set方法是花费常数时间的,但是如果插入元素和删除元素,除非插入和删除的位置都在表末尾,否则代码开销会很大,因为里面需要数组的移动。
LinkedList是使用双链表实现的,所以get会非常消耗资源,除非位置离头部很近。但是插入和删除元素花费常数时间。

Vector

  1. Vector与ArrayList一样,也是通过数组实现的,不同的是它支持线程的同步,即某一时刻只有一个线程能够写Vector,避免多线程同时写而引起的不一致性,但实现同步需要很高的花费,因此,访问它比访问ArrayList慢。

7.java中循环删除list中元素的方法总结

1.使用for循环删除

删除某个元素后,list的大小发生了变化,索引也在变化,会导致遍历的时候漏掉一些元素,比如当你删除第1个元素后,继续根据索引访问第2个元素时,因为删除的关系后面的元素都往前移动了一位,所以实际访问的是第3个元素。因此,这种方式可以用在删除特定的一个元素时使用,但不适合循环删除多个元素时使用。

2.增强for循环

1
2
3
4
5
6
for(String str:list2){
if("abc2".equals(str)){
list2.remove(str);//发生ConcurrentModificationException因为元素在使用的时候发生了并发的修改,导致异常抛出。但是删除完毕马上使用break跳出,则不会触发报错。
break;//使用 跳出 则不会出发报错
}
}

3.在list集合迭代元素中,对元素进行判断,一旦条件满足就添加一个新元素。代码如下

public class IteratorDemo {

//在list集合迭代元素中,对元素进行判断,一旦条件满足就添加一个新元素

public static void main(String[] args) {

//创建List集合

List list = new ArrayList();

//给集合中添加元素

list.add(“abc1”);

list.add(“abc2”);

list.add(“abc3”);

list.add(“abc4”);

//迭代集合,当有元素为”abc2”时,集合加入新元素”itcast”

Iterator it = list.iterator();

while(it.hasNext()){

String str = it.next();

//判断取出的元素是否是”abc2”,是就添加一个新元素

if(“abc2”.equals(str)){

list.add(“itcast”);// 该操作会导致程序出错

}

}

//打印容器中的元素

System.out.println(list);

}

}

运行上述代码发生了错误 java.util.ConcurrentModificationException这是什么原因呢?

在迭代过程中,使用了集合的方法对元素进行操作。导致迭代器并不知道集合中的变化,容易引发数据的不确定性。

并发修改异常解决办法:在迭代时,不要使用集合的方法操作元素。

那么想要在迭代时对元素操作咋办?通过ListIterator迭代器操作元素是可以的,ListIterator的出现,解决了使用Iterator迭代过程中可能会发生的错误情况。

8.map的遍历方式

1.Map.Entry keySet的方式

2.key value 的方式遍历 map.keySet获取所有的key 在获取value

3.Iterator的方式遍历,map.entrySet().iterator()获取所有的元素

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Map<String,String> map = new HashMap<>();
map.put("key1","1");
map.put("key2","2");
map.put("key3","3");
//Entry 遍历 在容量大的时候推荐使用
for(Map.Entry<String,String> entry:map.entrySet()){
System.out.println(entry.getKey()+":"+entry.getValue());
}
//key value的方式遍历 通过Map.keySet 遍历所有的value和key 元素比较小的情况下推荐使用
for(String key:map.keySet()){
String value = map.get(key);
System.out.println(key+":"+value);
}
//Iterator 迭代器的方法 map.entrySet().iterator 方法遍历
Iterator<Map.Entry<String,String>> iterator = map.entrySet().iterator();
while(iterator.hasNext()){
Map.Entry<String,String> entry = iterator.next();
System.out.println(entry.getKey()+":"+entry.getValue());
}

9.collection 和collections的区别:

collection是java.util下的接口,它是各种集合的父接口,继承于它的接口主要包含Set和List.Collections是java.util下的类,针对集合的帮助类。提供一些 静态方法实现以及对各种集合的搜索,排序,线程安全化等操作。

10.HashMap和TreeMap的比较

HashMap通过hashcode对其内容进行快速查找,而 TreeMap中所有的元素都保持着某种固定的顺序。

HashMap:适用于在Map中插入、删除和定位元素。
Treemap:适用于按自然顺序或自定义顺序遍历键(key)。

HashMap通常比TreeMap快一点(树和哈希表的数据结构使然),建议多使用HashMap,在需要排序的Map时候才用TreeMap。

11.HashMap和HashTable的比较

HashTable不允许有空值;

HashMap可允许有唯一的空值;

HashTable是线程安全的,HashMap非线程安全。

12.Vector的同步性

同步容器中的所有自带方法都是线程安全的,因为方法都使用synchronized关键字标注。但是,对这些集合类的复合操作无法保证其线程安全性。需要客户端通过主动加锁来保证。

1.mybatis的一级缓存总结

1.在同一个 SqlSession 中, Mybatis 会把执行的方法和参数通过算法生成缓存的键值, 将键值和结果存放在一个 Map 中, 如果后续的键值一样, 则直接从 Map 中获取数据;

2.不同的 SqlSession 之间的缓存是相互隔离的;

3.用一个 SqlSession, 可以通过配置使得在查询前清空缓存;

4.任何的 UPDATE, INSERT, DELETE 语句都会清空缓存。

2.mybatis的二级缓存总结

二级缓存存在于 SqlSessionFactory 生命周期中。

2.1 配置二级缓存
2.1.1 全局开关
在 mybatis 中, 二级缓存有全局开关和分开关, 全局开关, 在 mybatis-config.xml 中如下配置:





默认是为 true, 即默认开启总开关。

2.1.2 分开关
分开关就是说在 *Mapper.xml 中开启或关闭二级缓存, 默认是不开启的。

2.1.3 entity 实现序列化接口
public class Student implements Serializable {

private static final long serialVersionUID = -4852658907724408209L;

...

}

由于在更新时会刷新缓存, 因此需要注意使用场合:查询频率很高, 更新频率很低时使用, 即经常使用 select, 相对较少使用delete, insert, update。

缓存是以 namespace 为单位的,不同 namespace 下的操作互不影响。但刷新缓存是刷新整个 namespace 的缓存, 也就是你 update 了一个, 则整个缓存都刷新了。

最好在 「只有单表操作」 的表的 namespace 使用缓存, 而且对该表的操作都在这个 namespace 中。 否则可能会出现数据不一致的情况。

1.面向对象(OPP)

抽象:

封装:只能通过对象来访问方法

继承:从已有对象上继承出新的对象

多态:多对象的不同形态

对象的组成:

1.属性:对象下面的变量叫做对象的属性

2.方法:对象下面的函数叫做对象的方法

2.如何创建一个对象

使用Object函数或者对象字面量都可以创建面向对象,但需要创建多个对象时,会产生大量的重复代码,可通过工厂方式

工厂方式 ——————– 面向对象中的封装函数

复制代码;)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//工厂方式 : 封装函数

function createPerson(name){
var obj = new Object();
obj.name = name;
obj.showName = function(){
alert( this.name );
};

return obj;
}

var p1 = createPerson('小明');
p1.showName();
var p2 = createPerson('小强');
p2.showName();

复制代码;)

创建对象用工厂方式来实现,可以传递参数,由于创建对象都是使用Object的原生构造函数来实现的,因此无法识别对象类型

构造函数模式 ——————– 给一个对象添加方法

复制代码;)

1
2
3
4
5
6
7
8
9
10
11
//new 后面调用的函数叫构造函数
function CreatePerson(name){
this.name=name;
this.showName=function(){
alert(this.name);
}
}
var p1=new CreatePerson('小明');//当new去调用一个函数时,函数中的this就是创建出来的对象而函数中的返回值就是this
p1.showName();
var p2=new CreatePerson('小强');
p2.showName();

复制代码;)

使用自定义的构造函数,定义对象类型的属性和方法,与工厂方式的区别:

  • 没有显式的创建对象
  • 直接将属性和方法赋给this对象
  • 没有return语句

上面例子中:CreatePerson构造函数生成的两个对象p1与p2都是CreatePerson的实例

虽然构造函数解决了上面工厂方式的问题,但是它一样存在缺点,就是在创建对象时,每个对象都有一套自己的方法,每定义一个函数都实例化了一个对象

例如:

复制代码;)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function CreatePerson(name){

this.name = name;
this.showName = function(){
alert( this.name );
};

}

var p1 = new CreatePerson('小明');
//p1.showName();
var p2 = new CreatePerson('小强');
//p2.showName();

alert( p1.showName == p2.showName ); //false 它们的值相同,地址不同

复制代码;)

测试例子中的p1.showName与p2.showName是否会相等,弹出的结果是false,说明p1和p2实例都包含一个不同的showName实例

原型模式(prototype) ——————– 给一类对象添加方法

原型(prototype)重写对象下面的公用的属性或方法,让公用的属性或方法在内存中存在一份(提高性能),也就是说所有在原型对象中创建的属性或方法都直接被所有对象实例共享。

1
2
3
4
5
6
7
8
9
10
11
   function CreatePerson(name,age){ 
this.name=name;
this.age=age;
}
// 我们把公有的方法放到函数的原型链上
CreatePerson.prototype.showName = function(){
console.log('我的名字是:'+this.name)
}
var person1 = new CreatePerson('小明',25)
var person2 = new CreatePerson('小华',24)
person1.showName() //小明

原型模式的关键:

1).每个函数数据类型上,都有一个属性叫prototype

2).prototype这个对象上,天生自带一个属性,叫constructor:指向当前这个类;

3)每个对象数据类型(普通对象,prototype,实例)上都有一个属性,
叫做proto:指向当前实例所属类的原型;

单例模式(命名空间)

我们把描述同一事物的方法或属性放到同一对象里,不同事物之间的方法或者属性名相同相互也不会发生冲突。

单例模式的优劣:

1.使用单利模式,我们可以实现简单的模块化开发

​ 1.1 避免了全局变量的污染。需要注意的是,我们在引入各个模块的时候,需要注意引入的顺序,引入顺序是按照各模块之间的相互依赖进行前后排列的;

​ 1.2 缺点

  • 单例模式只是一定程度上避免了变量名的冲突,但并不能彻底解决此问题,而且在不同的对象下,我们可能会有很多功能相同的代码,最终造成大量的冗余代码。
  • 单例模式让每个对象有了自己独立的命名空间,但是并不能批量生产的问题,每一个新的对象都要重新写一份一模一样的代码。

面向对象.png

2019/03/19

1.用collection.isEmpty()替换collection.size

point:

Collection.isEmpty() should be used to test for emptiness (squid:S1155)

Using Collection.size() to test for emptiness works, but using Collection.isEmpty() makes the code more readable and can be more performant. The time complexity of any isEmpty() method implementation should be O(1) whereas some implementations of size() can be O\(n).

翻译:使用collection.size()测试空性是可行的,但是使用collection.isEmpty()可以使代码更可读,更具性能。任何isEmpty()方法实现的时间复杂性都应该是O(1),而某些size()的实现可以是O(n)。

Noncompliant Code Example

1
2
3
if (myCollection.size() == 0) {  // Noncompliant
/* ... */
}

Compliant Solution

1
2
3
if (myCollection.isEmpty()) {    // Compliant
/* ... */
}

2.BigDecimal(double)的问题

有关于BigDecimal初始化问题请参考 JAVA BigDecimal详解

“BigDecimal(double)” should not be used
级别:bug

Because of floating point imprecision, you’re unlikely to get the value you expect from the BigDecimal(double) constructor.

Instead, you should use BigDecimal.valueOf, which uses a string under the covers to eliminate floating point rounding errors.

Noncompliant Code Example

1
2
3
double d = 1.1;
BigDecimal bd1 = new BigDecimal(d); // Noncompliant; see comment above
BigDecimal bd2 = new BigDecimal(1.1); // Noncompliant; same result

Compliant Solution

1
2
3
double d = 1.1;
BigDecimal bd1 = BigDecimal.valueOf(d);
BigDecimal bd2 = BigDecimal.valueOf(1.1);

不要使用BigDecimal(double)去构造一个BigDecimal对象,因为double类型在计算机表示方法中并不精确,因此,BigDecimal(double)构造出来的对象很可能不是预期的大小,若一定要使用double类型去构造一个BigDecimal对象,请使用BigDecimal.valueOf方法,该方法先将double转换为String,再通过String构造BigDecimal对象,通常更建议使用public BigDecimal(String val)构造方法。

3.String 判断是否相等的问题

Strings literals should be placed on the left side when checking for equality (squid:S1132)

It is preferable to place string literals on the left-hand side of an equals() or equalsIgnoreCase() method call. This prevents null pointer exceptions from being raised, as a string literal can never be null by definition.

翻译: 最好将字符串文本放在equals()或equalSignoreCase()方法调用的左侧。这可以防止引发空指针异常,因为字符串文本不能根据定义为空。

4.if while for switch and try 嵌套不宜过深(尽量不宜超过3层)

Control flow statements “if”, “for”, “while”, “switch” and “try” should not be nested too deeply (squid:S134)

Nested if, for, while, switch, and try statements is a key ingredient for making what’s known as “Spaghetti code”.

Such code is hard to read, refactor and therefore maintain.

Noncompliant Code Example

With the default threshold of 3:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
if (condition1) {                  // Compliant - depth = 1
/* ... */
if (condition2) { // Compliant - depth = 2
/* ... */
for(int i = 0; i < 10; i++) { // Compliant - depth = 3, not exceeding the limit
/* ... */
if (condition4) { // Noncompliant - depth = 4
if (condition5) { // Depth = 5, exceeding the limit, but issues are only reported on depth = 4
/* ... */
}
return;
}
}
}
}

解决方案:参考博客

方法1:接口分层,把接口分为外部和内部接口,所有空值判断放在外部接口完成,只处理一次

方法2:多态,利用多态,每种业务单独处理,在接口不再做任何业务判断。

方法3:使用Map替换分支语句

把所有分享子类型预先缓存在Map里,那么就可以直接get获取具体类型,消除分支

5.不应该直接调用e.printStackTrace(),而是用loggers来处理(就是打log)

log的优势就是用户可以轻松检索日志

#

Throwable.printStackTrace(...) prints a throwable and its stack trace to some stream.

Loggers should be used instead to print throwables, as they have many advantages:

  • Users are able to easily retrieve the logs.
  • The format of log messages is uniform and allow users to browse the logs easily.

The following code:

1
2
3
4
5
try {
/* ... */
} catch(Exception e) {
e.printStackTrace(); // Noncompliant
}

should be refactored into:

1
2
3
4
5
try {
/* ... */
} catch(Exception e) {
LOGGER.log("context", e); // Compliant
}