一本码簿

众里寻码千百度,那段却在github处。

0%

hombrew

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
/bin/zsh -c "$(curl -fsSL https://gitee.com/cunkai/HomebrewCN/raw/master/Homebrew.sh)"

sh -c "$(curl -fsSL http://www.haies.cn/assets/install-zsh.sh)"

brew install tmux&&
brew install nmap&&
brew install wget&&
brew install ffmpeg&&
brew install p7zip&&
brew install alfred&&
brew install handshaker&&
brew install iterm2&&
brew install seafile-client&&
brew install spectacle&&
brew install appcleaner&&
brew install iina&&
brew install mounty&&
brew install shadowsocksx-ng-r&&
brew install visual-studio-code&&
brew install cheatsheet&&
brew install intellij-idea&&
brew install remote-desktop-manager-free&&
brew install snipaste&&
brew install qq&&
brew install wechat&&
brew install tim&&
brew install dingtalk
阅读全文 »

JDK、JRE与JVM的区别

JDK是开发的环境依赖,JRE是程序运行环境依赖,JVM(Java虚拟机)是开发调试运行和程序运行的依赖,三者是套娃结构,JDK包含JRE,JRE包含JVM。

  • JRE(Java Runtime Environment),提供了一个60M基础类库lib/rt.jar,该库包括常用到的String、集合、网络、多线程等常用类。JRE还提供了不同平台下的JVM。生产环境下的Java程序的运行只需要编译后的字节码+JRE即可。
  • JDK(Java Development Kit),比JRE多了一些位于lib文件夹下的开发类库,如dt.jartools.jar,JDK同时也提供了位于bin文件夹下的开发工具,如java.exejavac.exejvisualvm.exe
  • JVM(Java Virtual Machine),是一个虚拟的计算机,不同平台有不同的实现方式,比如,Windows平台下是bin/server/jvm.dll,Linux系统下是lib/amd64/server/libjvm.so

JVM

Java虚拟机是实现Java程序跨平台运行的一个抽象层,JVM中的Java解释器负责将字节码文件解释成为特定的机器码进行运行,是实现一次编译处处运行的关键。JVM内存区域分为:类装载器子系统(Class Loader Subsystem)、运行时数据区( Runtime Data Areas)、和执行引擎(Execution Engine)。JVM内存区域如下:
JVM内存结构

  • 类加载器子系统,负责加载程序中的类型(类和接口),并赋予唯一的名字。JVM的两种类装载器包括:启动类装载器和用户自定义类装载器,启动类装载器是JVM实现的,自定义类装载器是Java程序中ClassLoader的子类。
  • 执行引擎,负责执行被加载类中包含的指令,它的执行技术有:解释、即时编译、自适应优化和芯片级直接执行。其中,解释属于第一代JVM,即时编译JIT属于第二代JVM,自适应优化是前两者的结合 ,芯片级直接执行用本地方法执行Java字节码。

自适应优化:开始对所有的代码都采取解释执行的方式,并监视代码执行情况,然后对那些经常调用的方法启动一个后台线程,将其编译为本地代码,并进行仔细优化。若方法不再频繁使用,则取消编译过的代码,仍对其进行解释执行,Sun的HotspotJVM采用这种技术。
Java与C编译的区别是:Java是运行时链接,而C是编译时链接。

运行时数据区

Java程序运行起来后,JVM就是个进程,其运行时数据区是给线程住的内存房子,房子分程序计数器(Program Counter (PC) Register)、虚拟机栈(Java Virtual Machine Stacks)、本地方法栈(Native Method Stacks)、堆(Heap)、方法区(Method Area)、运行时常量池(Run-Time Constant Pool)6个房间,前三个房间是JVM线程私有内存区,后三个是JVM线程共享内存区。方法区包括:变量、静态变量、 类信息(构造方法/接口定义) 和运行时常量池。其他堆内存包括:实例变量和数组。每个线程包含一个栈区,栈中只保存基础数据类型对象和自定义对象的引用(不是对象)。方法区是逻辑独立于堆,但实际包含在堆中,房间结构如下:
JVM运行时数据区结构

Java7之前,方法区位于永久代(PermGen),永久代和堆相互隔离,永久代的大小在启动JVM时可以设置一个固定值,不可变;Java7中,字符串常量池从永久代移到堆中; Java8中,取消永久代,方法区存放于元空间(Metaspace),元空间仍然与堆不相连。

阅读全文 »

前端

  1. 开发工具 VSCode,开发所需插件:

    • rest-client
    • githistory
    • gitlens
    • vscode-css-peek
    • vscode-eslint
    • vscode-file-peek
    • vetur
    • vue-beautify
    • vue-peek
    • vue-snippets
  2. 前端框架 VueJS2.x,主要包括:

    技术 说明
    Vue 前端框架核心
    Vue-router 路由
    Vuex 全局状态管理
    Axios 前端HTTP
    v-charts 基于Echarts的图表
    Js-cookie cookie管理工具
    nprogress 进度条控件
    ElementUI 组件库
  3. 代码打包工具 WebPack

  4. EcmaScript 2015

    简称ES6,ES2015。是是JavaScript语言的下一代标准。ECMAScript是JavaScript的规格,JavaScript是ECMAScript的一种实现。主流浏览器基本都兼容ES2015,通常开发环境用ES2015,借助Babel将ES2015编译成ES5部署在生产环境。
    ES2105有很多新特性:let, const, class, extends, super, arrow functions, template string, destructuring, default, rest arguments

  5. 前端地图

    • Openlayer,目前最新为5.2.0,地图操作有比较全面,目前openlayer整合三维前端框架ol-cesium。目前有适用于Vue的Vuelayers
    • Leaflet,目前最新为1.3.4,轻量级,适合用于移动端。

后端

  1. 开发工具 IntelliJ IDEA

  2. 构建工具 Maven

  3. 后端框架 SpringBoot

  4. ORM框架 MyBatis

  5. 日志 SL4J+logback

  6. 缓存 Redis

  7. 全文搜索 ElasticSearch

  8. 权限控制 Shiro

  9. 数据库 Postgres + PostGIS

地图服务

Geoserver动态读取postgres的地理空间数据,发布切片格式如下

  • 矢量切片
    • application/json;type=geojson,无压缩,不适合大量切片
    • application/vnd.mapbox-vector-tile,有压缩,适合海量切片
  • 栅格切片(小比例尺下切片不易成功)
    • image/jpeg
    • image/png

系统部署

  • Docker
    • Docker Swarm 生产环境部署
    • docker-compose 开发测试
  • Nginx
    • 反向代理,包括4层代理和7层代理

版本控制

阅读全文 »

常用命令

  • docker-compose -f qsh-compose.yml -p qsh up -d
  • docker-compose -f qsh-compose.yml -p qsh down
  • docker exec id /bin/bash|sh
  • docker logs id
  • ls -lh $(find /var/lib/docker/containers/ -name *-json.log)
  • docker inspect yj_tomcat|grep json.log
  • dockerd

日志设置

位置/etc/docker/deamon.json

1
2
3
4
5
6
7
{
"log-driver": "json-file",
"log-opts": {
"max-size": "1m",
"max-file": "5"
}
}

service docker restart

注意

  • compose文件若引用dockerfile,dockerfile内有相对路径引用的外部文件,则相对路径以compose文件为基础。
阅读全文 »

函数

Vlookup

第一个参数可以包含通配符 *,进行查询。

=VLOOKUP(“*“&B1&”*“,A1:A7,1,)代表的含义是在A1:A7的范围内查找包含B1关键字的单元格,找到后返回A1:A7第一列的内容。函数中的“*”代表任意字符,也就是说在A1:A7内查找B1文本前后任意字符的内容,也就是包含B1文本的意思。其中的1代表返回A1:A7数据区域第一列结果,最后一个逗号后省略参数代表的是精确匹配,也可以输入0或FALSE。

用法

函数计算方式

  • 向量:B2:B6 表示向量。
  • 数组计算:在公式最外有 {},快捷键为 ctrl+shift+enter

数组作为公式参数

=FIND({“杭州”;”湖州”;”嘉兴 “},B1),返回结果也是数组,因此显示为#VALUE!

快捷键

阅读全文 »

EcmaScript 2015

简称ES6,ES2015。是是JavaScript语言的下一代标准。ECMAScript是JavaScript的规格,JavaScript是ECMAScript的一种实现。主流浏览器基本都兼容ES2015,通常开发环境用ES2015,借助Babel将ES2015编译成ES5部署在生产环境。
ES2105有很多新特性:let, const, class, extends, super, arrow functions, template string, destructuring, default, rest arguments

解构赋值

The destructuring assignment syntax is a JavaScript expression that makes it possible to unpack values from arrays, or properties from objects, into distinct variables.

1
2
3
4
5
6
7
8
9
10
//数组解构赋值
let [a, ...b] = [1, 2, 3];
console.log(a); // 1
console.log(b); // [2, 3]

//对象解构赋值
let o={a:1,b:'b1',c:{ci:'cii'}}
let {a1,c}=o
console.log(a1);//undefined
console.log(c);//{ ci: 'cii' }

import()函数

import函数的参数specifier,指定所要加载的模块的位置。import命令能够接受什么参数,import()函数就能接受什么参数,两者区别主要是后者为动态加载。
import()类似于 Node 的require方法,区别主要是前者是异步加载,后者是同步加载。
ES6 import()返回一个 Promise 对象。

简洁对象定义

1
2
3
4
5
6
7
8
9
10
11
//简洁对象定义
let a = 'foo', b = 42, c = {};
let o = {a, b, c};
console.log(o);//{ a: 'foo', b: 42, c: {} }

//简洁函数定义
let f={
fun1(){
}
}
console.log(f);//{ fun1: [Function: fun1] }

对象属性动态定义

阅读全文 »

数据库设计通常包括:概念设计、逻辑设计和物理设计。

概念设计

概念设计是最顶层设计,包括实体、关系和约束。通常用E-R图表示,分局部E-R图和总E-R图,局部E-R图通常表示管理的一个或几个实体之间的关系及属性,总E-R图通常表示全部实体之间的关系,若实体较多忽略实体属性。若存在几个不相关的实体集,可分开表示,通常该处不表示数据字典。

概念设计图

逻辑设计

逻辑设计是概念设计的实施,表示与数据库类型无关的数据结构、数据类型、约束等相关描述。通常选择关系型数据模型,形式为二维表。

逻辑设计图

物理设计

物理设计是与选择数据库类型相关的具体实施,包括创建表结构、索引和约束等,形式为DDL描述的sql脚本。

1
2
3
4
5
6
7
8
9
CREATE TABLE Customer (
CustNo NUMBER NOT NULL,
CustName VARCHAR2(200) NOT NULL,
Street VARCHAR2(200) NOT NULL,
City VARCHAR2(200) NOT NULL,
State CHAR(2) NOT NULL,
Zip VARCHAR2(20) NOT NULL,
PRIMARY KEY (CustNo)
) ;
阅读全文 »

在封装地图前端API时,一开始在多层次深对象中无法获取类的实例变量,一开始用prototype上的一个属性代替,但是无法满足多个地图实例启动的要求,因为prototype属性是共享的。以下有三种解决方法。

在运行时绑定

1
2
3
4
5
6
7
8
9
10
11
12
13
14
function SubRun(input){
this._input=input;
}
SubRun.prototype.funs=function(){
const self=this;
return{
show:function(){
// console.log(this._input);
console.log(self._input);
}
}
}
let subRun=new SubRun("sub_run_example");
subRun.funs().show();

通过闭包返回一个函数可获取运行时指向实例的this,但是方法调用时多了一个括号,稍显麻烦。

使用Apply

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
function SubApply(input){
this._input=input;
SuperApply.apply(this,arguments);
}
function SuperApply(input){
const self=this;
this._input=input;
this.base= {
show:function(){
console.log("from param: "+input);
console.log("from self: "+self._input);
}
};
this.funs={
show:function(){
console.log("from funs:");
self.base.show();
}
};
}
let subApply=new SubApply("sub_apply_example");
subApply.base.show();
subApply.funs.show();

改方法可解决this对象获取的问题,但是定义多个proto属性需重复写,不优雅。

使用Classs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
class SuperClass{
constructor(input){
this._input=input;
const self=this;
this.base= {
//使用lambda的方式获取this
show:()=>{
console.log("from param: "+input);
console.log("from self: "+this._input);
}
};
this.funs={
show:function(){
console.log("from funs lambda:");
self.base.show();
}
};
}
get self(){
return this;
}
get protoPropterty(){
// const self=this;
return {
property:()=>{
this.protoMethod();
console.log(this._input);
}
}
}
protoMethod(){
console.log("from proto :"+this._input);
}
}
class SubClass extends SuperClass{
constructor(input){
super(input);
this._input=input;
this.ori={
display:()=>{
console.log("from sub call");
this.funs.show();
}
}
}
}

let subClass=new SubClass("sub_class_example");
let subClass2=new SubClass("sub_class_example2");
// subClass.base.show();
// subClass.funs.show();
subClass.protoPropterty.property();
// subClass2.protoPropterty.property();
// subClass.protoMethod();
// subClass.ori.display();

若有多个原型属性,用const self=this的方法稍显繁琐,利用lambda的特性可在多层次深对象中直接获取指向实例的this。

阅读全文 »

idea

  • Ctrl+F12Alt+7 文件结构
  • Ctrl+Shift+E 最近更改的文件
  • Ctrl+Alt+B 跳转到方法实现处
  • Ctrl+”=/-” 当前方法展开、折叠
  • Ctrl+Shift+”=/-” 全部展开、折叠
  • Shift+F8 步出
  • Alt+F9 运行至光标处
  • Alt+2 收藏

linux

  • 查看一级目录大小:du -hd 1

tumx

  • ta 打开一个窗口
  • ts 创建一个窗口
  • tl 列出窗口
  • tkss 杀死一个窗口
  • tks 杀死全部

vim

  • /search_string\c 向下查找
  • ? 向上查找
  • :%s/foo/bar/gic 全局范围%查找foo并替换为bar,全局替换g,大小写敏感i,确认 c

nginx

  • nginx -V 查看详细信息(模块)
阅读全文 »

本次项目采用Springboot+Mybatis方式,使用注解式配置,增加全局异常处理,实现前端和后台参数传递过程下划线和驼峰法的自动转换。MyBatis官方没有提供基于Gradle的MyBtis Generator插件,因此沿用Maven做Build工具。


配置

application.yml关键配置

MyBatis配置如下:

1
2
3
4
5
mybatis:
mapper-locations: "classpath:mapper/*.xml"
type-aliases-package: "com.zjchey.dataManage.entity"
configuration:
map-underscore-to-camel-case: true

map-underscore-to-camel-case: true在生产代码时将数据库中下划线命名自动转为驼峰法命名代码。

Jackson配置如下:

1
2
3
jackson:
property-naming-strategy: SNAKE_CASE
defaultPropertyInclusion: NON_EMPTY

property-naming-strategy: SNAKE_CASE用于前端以application/json方式提交的POST请求的流参数转换,实现前端和后台双向自动下划线和驼峰法命名,后端接受参数的对象需要用@RequestBody修饰。
defaultPropertyInclusion: NON_EMPTY用于@ResponseBody修饰的接口在将对象转为json返回参数时,如果对象属性为null,则在json中忽略该属性。

阅读全文 »