完美

[学习|工作|博客|交流平台|完美起航]

作者头像zyw3272018.12.01 20:14 

spring中使用RestTemplate下载与上传文件

使用RestTemplate下载文件 String url = "需要下载的文件地址"; HttpHeaders header = new HttpHeaders(); List<MediaType> list = new ArrayList<MediaType>(); // 指定下载文件类型 list.add(MediaType.APPLICATION_OCTET_STREAM); header.setAccept(list); HttpEntity<byte[]> request = new HttpEntity<byte[]>(params, header); ResponseEntity<byte[]> response = this.restTemplate.exchange(url, HttpMethod.POST, request, byte[].class); // 取得文件字节 byte[] result = response.getBody(); 使用RestTemplate上传文件 String url = "接收文件的地址"; HttpHeaders headers = new HttpHeaders(); // 设置请求头 headers.setContentType(MediaType.MULTIPART_FORM_DATA); // file为通过表单上传的文件,如果是服务器上的文件,直接通过new File创建即可。 byte[] bytes = file.getBytes(); File fileToSave = new File(file.getOriginalFilename()); // 将表单上传的文件写入新创建文件中 FileCopyUtils.copy(bytes, fileToSave); // 建立需要上传的资源对象 FileSystemResource resource = new FileSystemResource(fileToSave); MultiValueMap<String, Object> param = new LinkedMultiValueMap<>(); // 指定上传文件所对应的字段及资源 param.add("file", resource); HttpEntity<MultiValueMap<String, Object>> httpEntity = new HttpEntity<>(param, headers); // Result为上传返回结果映射类 HttpEntity<Result> responseEntity = restTemplate.exchange(url, HttpMethod.POST, httpEntity, Result.class); // 上传文件返回的结果 responseEntity.getBody(); 使用poi导出excel字节到浏览器 HSSFWorkbook workbook = new HSSFWorkbook(); HSSFSheet sheet = workbook.createSheet(&q

java 199 0

作者头像zyw3272018.10.10 13:30 

互联网公司面试必问的Redis题目

  Redis是一个非常火的非关系型数据库,火到什么程度呢?只要是一个互联网公司都会使用到。Redis相关的问题可以说是面试必问的,下面我从个人当面试官的经验,总结几个必须要掌握的知识点。 介绍:Redis 是一个开源的使用 ANSI C 语言编写、遵守 BSD 协议、支持网络、可基于内存亦可持久化的日志型、Key-Value 数据库,并提供多种语言的 API的非关系型数据库。 传统数据库遵循 ACID 规则。而 Nosql(Not Only SQL 的缩写,是对不同于传统的关系型数据库的数据库管理系统的统称) 一般为分布式而分布式一般遵循 CAP 定理。 Github源码:https://github.com/antirez/redis Redis 官网:redis.io/ Redis支持的数据类型? String字符串: 格式: set key value string类型是二进制安全的。意思是redis的string可以包含任何数据。比如jpg图片或者序列化的对象 。 string类型是Redis最基本的数据类型,一个键最大能存储512MB。 Hash(哈希) 格式: hmset name key1 value1 key2 value2 Redis hash 是一个键值(key=>value)对集合。 Redis hash是一个string类型的field和value的映射表,hash特别适合用于存储对象。 List(列表) Redis 列表是简单的字符串列表,按照插入顺序排序。你可以添加一个元素到列表的头部(左边)或者尾部(右边) 格式: lpush name value 在 key 对应 list 的头部添加字符串元素 格式: rpush name value 在 key 对应 list 的尾部添加字符串元素 格式: lrem name index key 对应 list 中删除 count 个和 value 相同的元素 格式: llen name 返回 key 对应 list 的长度 Set(集合) 格式: sadd name value Redis的Set是string类型的无序集合。 集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是O(1)。 zset(sorted set:有序集合) 格式: zadd name score value Redis zset 和 set 一样也是string类型元素的集合,且不允许重复的成员。 不同的是每个元素都会关联一个double类型的分数。redis正是通过分数来为集合中的成员进行从小到大的排序。 zset的成员是唯一的,但分数(score)却可以重复。 什么是Redis持久化?Redis有哪几种持久化方式?优缺点是什么? 持久化就是把内存的数据写到磁盘中去,防止服务宕机了内存数据丢失。 Redis 提供了两种持久化方式:RDB(默认) 和AOF RDB: rdb是Redis DataBase缩写 功能核心函数rdbSave(生成RDB文件)和rdbLoad(从文件加载内存)两个函数 AOF: Aof是Append-only file缩写 每当执行服务器(定时)任务或者函数时flushAppendOnlyFile 函数都会被调用, 这个函数执行以下两个工作 aof写入保存: WRITE:根据条件,将 aof_buf 中的缓存写入到 A

Redis 210 0

作者头像zyw3272018.07.20 17:44 

使用sts eclipse创建spring boot项目

使用sts_eclipse创建spring boot项目sts下载地址https://spring.io/tools/sts/all安装sts创建sts创建string boot项目,创建spring stater project项目,如下图点击next,如图点击next,如图勾选需要的组件,DevTools用户热加载,开发时可使用,web用于web项目。点击finish完成项目创建,maven自动下载相关依赖。目录结构如下:src/main/java用于存放项目主要代码src/main/resources用于存放资源文件,application.properties为默认配置文件src/test/java存放单元测试代码target目录存放打包后的文件spring boot入口文件代码packagespring.boot; importorg.springframework.boot.SpringApplication; importorg.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication publicclassSpringbootApplication{ publicstaticvoidmain(String[]args){ SpringApplication.run(SpringbootApplication.class,args); } }spring boot项目启动方式在入口文件右击run as java Application使用maven打包spring boot项目#在项目根目录下执行 mvnpackage打包生成的jar包在target目录下。sts 打包右击项目选择run as maven install,如图命令方式spring boot项目部署使用java -jar命令执行打包后的jar包#linux下运行jar包 java-jarspringboot.jar #linux下后台运行jar包项目 nohupjava-jarspringboot.jar&

spring boot 688 4

作者头像zyw3272018.06.20 16:56 

flex弹性布局(一)

flex弹性布局 Flex是Flexible Box的缩写,意为”弹性布局”,用来为盒状模型提供最大的灵活性。 任何一个容器都可以指定为Flex布局。 .flex{ display: flex; display: -webkit-flex; /* Safari */ border: none; } <div class="flex"> <div>12</div><div>13</div><div>14</div><div>15</div><div>16</div><div>17</div><div>18</div><div>19</div> </div> 效果如下: note: 设为Flex布局以后,子元素的float、clear和vertical-align属性将失效。 flex-direction row (默认值):主轴为水平方向,起点在左端。 /*水平从左至右排列*/ .flex-direction.row{ flex-direction: row; } <div class="flex flex-direction row"> <div>12</div><div>13</div><div>14</div><div>15</div><div>16</div><div>17</div><div>18</div><div>19</div> </div> 效果如下: row-reverse 主轴为水平方向,起点在右端。 /*效果类似于float:right, 但是row-reverse不是浮动,而元素的排列也不一样,原来左边的排列在右边*/ .flex-direction.row-reverse{ flex-direction: row-reverse; } <div class="flex flex-direction row-reverse"> <div>12</div><div>13</div><div>14</div><div>15</div><div>16</div><div>17</div><div>18</div><div>19</div> </div> 效果如下: column 主轴为垂直方向,起点在上沿。 /*垂直向下排列*/ .flex-direction.column{ flex-direction: column; width: 100px; } <div class="fle

flex 230 2

作者头像zyw3272018.05.31 14:18 

Node.js cluster模块相关笔记

cluster Node.js的单个实例在单个线程中运行。 要利用多核系统,用户有时会想启动一个Node.js进程集群来处理负载。 cluster模块可以轻松创建全部共享服务器端口的子进程。 const cluster = require('cluster'); const http = require('http'); const numCPUs = require('os').cpus().length; if (cluster.isMaster) { console.log(`Master ${process.pid} is running`); // Fork workers. for (let i = 0; i < numCPUs; i++) { cluster.fork(); } cluster.on('exit', (worker, code, signal) => { console.log(`worker ${worker.process.pid} died`); }); } else { // Workers can share any TCP connection // In this case it is an HTTP server http.createServer((req, res) => { res.writeHead(200); res.end('hello world\n'); }).listen(8000); console.log(`Worker ${process.pid} started`); } 运行Node.js,所有的工作进程将共享8000端口 $ node server.js Master 3596 is running Worker 4324 started Worker 4520 started Worker 6056 started Worker 5644 started 请注意,在Windows上,尚不可能在工作进程中设置命名管道服务。 cluster如何工作 使用child_process.fork()方法产生工作进程,以便它们可以通过IPC与父进程通信并来回传递服务器句柄。 cluster模块支持两种分配传入连接的方法。 第一种方法(除Windows以外的所有平台上的默认方法)都是循环法,即主进程在端口上进行侦听,接受新连接并以循环方式在工作进程之间进行分配,其中一些已构建智能避免过载工作进程。 第二种方法是主进程创建侦听套接字并将其发送给感兴趣的工作进程。工作进程然后直接接受传入连接。 理论上,第二种方法应该是最好的。然而,在实践中,由于操作系统调度器的变幻莫测,分配趋于非常不平衡。已经观察到负载超过70%的连接只有两个过程,总共有八个。 因为server.listen()将大部分工作交给了主进程,所以在正常的Node.js进程和集群工作进程之间的行为有三种情况: server.listen({fd:7})因为消息被传递给主进程,父进程中的文件描述符7将被监听,并且该句柄传递给工作进程,而不是监听工作进程的文件描述符7的引用。 server.listen(句柄)明确地监听句柄会导致工作进程使用提供的句柄,而不是与主进程通信。 server.listen(

Cluster 270 1

作者头像zyw3272018.05.25 14:43 

es6之Map对象保存键值对

Map 语法 new Map([iterable]) 参数 iterable Iterable 可以是一个数组或者其他 iterable 对象,其元素或为键值对,或为两个元素的数组。 每个键值对都会添加到新的 Map。null 会被当做 undefined。 描述 一个Map对象以插入顺序迭代其元素 — 一个 for...of 循环为每次迭代返回一个[key,value]数组。 键的相等(Key equality) 键的比较是基于 "SameValueZero" 算法:NaN 是与 NaN 相同的(虽然 NaN !== NaN),剩下所有其它的值是根据 === 运算符的结果判断是否相等。在目前的ECMAScript规范中,-0和+0被认为是相等的,尽管这在早期的草案中并不是这样。有关详细信息,请参阅浏览器兼容性 表中的“value equality for -0 and 0”。 Objects 和 maps 的比较 Object 和 Map 类似的是,它们都允许你按键存取一个值、删除键、检测一个键是否绑定了值。因此(并且也没有其他内建的替代方式了)过去我们一直都把对象当成 Map 使用。不过 Map 和 Object 有一些重要的区别,在下列情况里 Map 会是更好的选择: 一个对象的键只能是字符串或者 Symbols,但一个 Map 的键可以是任意值,包括函数、对象、基本类型。 你可以通过 size 属性直接获取一个 Map 的键值对个数,而 Object 的键值对个数只能手动计算。 Map 是可迭代的,而 Object 的迭代需要先获取它的键数组然后再进行迭代。 Object 都有自己的原型,所以原型链上的键名有可能和对象上的键名产生冲突。虽然 ES5 开始可以用 map = Object.create(null) 来创建一个没有原型的对象,但是这种用法不太常见。 Map 在涉及频繁增删键值对的场景下会有些性能优势。 属性 Map.length 属性 length 的值为 0 。 get Map[@@species] 本构造函数用于创建派生对象。 Map.prototype 表示 Map 构造器的原型。 允许添加属性从而应用于所有的 Map 对象。 Map 实例 所有的 Map 对象实例都会继承 Map.prototype。 属性 Map.prototype.constructor 返回一个函数,它创建了实例的原型。默认是Map函数。 Map.prototype.size 返回Map对象的键/值对的数量。 方法 Map.prototype.clear() 移除Map对象的所有键/值对 。 Map.prototype.delete(key) 移除任何与键相关联的值,并且返回该值,该值在之前会被Map.prototype.has(key)返回为true。之后再调用Map.prototype.has(key)会返回false。 Map.prototype.entries() 返回一个新的 Iterator 对象,它按插入顺序包含了Map对象中每个元素的 [key, value] 数组。 Map.prototype.forEach(callbackFn[, thisArg]) 按插入顺序,为 Map对象里的每一键值对调用一次callbackFn函数。

Map 192 3

作者头像zyw3272018.05.23 18:13 

TypeScript学习笔记(一)

TypeScript TypeScript是JavaScript类型的超集,它可以编译成纯JavaScript。 TypeScript可以在任何浏览器、任何计算机和任何操作系统上运行,并且是开源的。 安装 # 全局安装typescript npm install -g typescript 接口声明 // 声明一个接口 export default interface Sociality { makeFriend():Boolean doGame():void } 类的声明并导出 // 引入接口 import Sociality from './Sociality'; // 声明一个类,实现Sociality接口 export default class Person implements Sociality { // 声明私有变量name,string类型 private name:string // 声明私有变量age,number类型 private age:number // 声明私有变量sex,number类型 private sex: number // 构造函数 constructor(name:string, age:number, sex:number) { this.name = name; this.age = age; this.sex = sex; } // 公开的方法声明,返回值string public getName():string { return this.name; } // 公开的方法声明,返回值number public getAge():number { return this.age; } // 公开的方法声明 public getSex():number { return this.sex; } // 实现接口方法 makeFriend():boolean { return true; } // 实现接口方法 doGame():void { console.log('我们在做游戏'); } } 类的继承 // 引入Person类 import Person from './Person'; // extends关键字实现继承 export default class Girl extends Person { private high:number constructor(name:string, age: number) { super(name, age, 1); } public setHigh(high: number):void { this.high = high; } public getHigh():number { return this.high; } } 编译生成.d.ts文件 tsc -d Girl.ts #

TypeScript 235 1

作者头像zyw3272018.05.22 11:19 

npm包的制作与发布使用

制作npm包的步骤 注册npm账户 npm adduser 或者登陆npm官网注册 登陆npm账户 npm login 编写npm包 初始化package.json并配置 npm init { "name": "包名", "version": "版本号", "description": "描述", "main": "入口文件", "scripts": { "test": "配置测试" }, // 配置git仓库 "repository": { "type": "git", "url": "git仓库地址" }, "keywords": [ "关键字" ], "author": "", "license": "MIT", "dependencies": { } } 发布 npm publish # 指定标签beta npm publish --tag beta 删除 npm unpublish --force 包名 命令行工具包的制作 { "name": "工具名称", "version": "版本号", "description": "描述", "bin": { "命令名称": "命令入口文件" }, "author": "zengyuwen", "license": "MIT" } 代码编写 #!/usr/bin/env node // 获取命令行参数 const arguments = process.argv.splice(2); 代码示例 命令行工具 package.json { "name": "cli", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "bin": { "my-cli": "./index.js" }, "author": "", "license": "ISC" } index.js #!/usr/bin/env node // 获取命令行参数 const arguments = process.argv.splice(2); // 参数解析成数组 function parse(arguments) { return arguments.map(function(value) { if (/^-+/.test(value)) { return value.replace(/^-+/, ''); } return value; }); } // 参数解析成键值对 function parseObj(arguments) { let result = []; for (le

npm 266 1

作者头像zyw3272018.05.22 09:32 

React、Redux和redux-thunk的简单应用

react-redux、redux connect、Provider,createStore 用法 // redux/index.js const ADD = 'add'; const SUB = 'sub'; export function counter(state = 0, action) { switch(action.type) { case ADD: return state + 1; case SUB: return state - 1; default: return state; } } // action export function add() { return {type: ADD}; } // action export function sub() { return {type: SUB}; } // index.js 入口 import React from 'react'; import ReactDOM from 'react-dom'; import App from './App' import {counter} from './redux/index'; import {createStore} from 'redux'; import {Provider} from 'react-redux'; let store = createStore(counter); // 通过props传递store ReactDOM.render( <Provider store={store}> <div> <App /> </div> </Provider> , document.getElementById('root') ); // App.js import react from 'react' import {connect} from 'react-redux' import {add, sub} from './reduxs/index' class App extends react.Component { render() { return ( <div> <span>{this.props.num}</span> <button onClick={this.props.add}>add</button> <button onClick={this.props.sub}>sub</button> </div> ); } } const MapStateToProps = (state) => { return {num}; } const ActionCreator = {add,

React、Redux 236 1

作者头像zyw3272018.05.21 15:41 

JavaScript封装、继承和多态实现

封装(概念) 封装,也就是把客观事物封装成抽象的类,并且类可以把自己的数据和方法只让可信的类或者对象操作,对不可信的进行信息隐藏。封装是面向对象的特征之一,是对象和类概念的主要特性。 简单的说,一个类就是一个封装了数据以及操作这些数据的代码的逻辑实体。在一个对象内部,某些代码或某些数据可以是私有的,不能被外界访问。通过这种方式,对象对内部数据提供了不同级别的保护,以防止程序中无关的部分意外的改变或错误的使用了对象的私有部分。 继承(概念) 继承是指可以让某个类型的对象获得另一个类型的对象的属性的方法。它支持按级分类的概念。继承是指这样一种能力:它可以使用现有类的所有功能,并在无需重新编写原来的类的情况下对这些功能进行扩展。 通过继承创建的新类称为“子类”或“派生类”,被继承的类称为“基类”、“父类”或“超类”。继承的过程,就是从一般到特殊的过程。要实现继承,可以通过“继承”(Inheritance)和“组合”(Composition)来实现。继承概念的实现方式有二类:实现继承与接口继承。实现继承是指直接使用基类的属性和方法而无需额外编码的能力;接口继承是指仅使用属性和方法的名称、但是子类必须提供实现的能力; 多态 多态就是指一个类实例的相同方法在不同情形有不同表现形式。多态机制使具有不同内部结构的对象可以共享相同的外部接口。这意味着,虽然针对不同对象的具体操作不同,但通过一个公共的类,它们(那些操作)可以通过相同的方式予以调用。 封装 es5封装 function Person(name, sex, age) { if (!(this instanceof Person)) { return new Person(name, sex, age); } this.name = name; this.sex = sex || 'female'; this.age = age || 0; this.walk = function() { if (this.age 2 && this.age < 4) { return console.log('我会走路了'); } return console.log('走路'); } this.study = function (skill) { console.log('学习' + skill); } this.introduce = function () { console.log(`我是${this.name},我是一个${this.sex === 'male' ? "男" : "女"}孩,今年${this.age}岁了。`); } } // 调用方式 // new关键字创建实例 var p = new Person('小名', 'male', 10); // 直接调用创建 var p1 = Person('小红', 'female', 9); p.walk(); // 走路 p1.study('游泳'); // 学习游泳 p.introduce();// 我是小名,我是一个男孩,今年10岁了。 p1.introduce();// 我是小红,我是一个女孩,今年9岁了。 原型

封装、继承、多态 288 2

a6bfb44cbd5549740eb36647f36ef83a