0%

PC 端调试 Android Web View 注意事项~

  • 必须翻墙, 因为他需要连接Google的两个域名, 暂不知道是干什么的。

相关域名:chrome-devtools-frontend.appspot.com, chrometophone.appspot.com,

也可以添加 hosts 来实现

1
2
172.217.14.116	chrome-devtools-frontend.appspot.com
172.217.14.116 chrometophone.appspot.com

使用容器安装Nexus3 仓库,真的非常方便

下载镜像

nexus3 的镜像名称为 sonatype/nexus3 我们直接用 docker 工具下载即可:

1
docker pull sonatype/nexus3

运行镜像

注意这里需要开启后面docker仓库的端口,不然连不上,不知道为啥教程都没说

阅读全文 »

最近刚使用上 opencv 做图像处理, 部署后发现每次调完业务代码 RES 都会上涨近 300M, 测试环境测了两天, RES 已经到 11G 了, 开始以为是内存泄露, 各种释放对象, 然而没卵用…

一. 开始排查

一开始以为是内存泄露了, 各种 google 查看怎么排查,
学到了不少, 之前都没怎么看过..

查看内存占用比较高的前20个 (不知道为啥只有17个), 而且最高的是个 [C 对象, 看了一下没看出来啥.

1
jmap -histo 32382 | head -20

阅读全文 »

Thymeleaf 调用java方法

创建对象调用:

1
<td th:text="${new java.text.DecimalFormat('#00%').format(student.scoringRate)} ">100%</td>

静态方法调用:

1
${T(java.lang.Math).abs(student.classRankChangeSum)}

调用springbean:

阅读全文 »

小技巧

当只传入一个变量时, 可以使用_parameter来指代它
这里的_parameter就代表传入的parameterType的值

1
2
3
4
5
6
<select id="queryWork" parameterType="int" resultType="int">
SELECT COUNT(isWork) FROM student
<if test="_parameter!=0">
where isWork=#{isWork};
</if>
</select>

传入对象中有Integ[]数组时, 通过 ${par[0]} 下标取值

添加 sql 日志

配置文件添加

阅读全文 »

E盘为 RamDisk虚拟磁盘。

剪切 idea 主要的工作目录

C:\Users\用户名.IntelliJIdea2019.2 文件夹到 E:\Users\用户名.IntelliJIdea2019.2

mklink 创建文件夹软链接

mklink /J C:\Users\用户名.IntelliJIdea2019.2 E:\Users\用户名.IntelliJIdea2019.2

注意 C 盘的 .IntelliJIdea2019.2 创建软连接时必须不存在, 所以第一步需要剪切, 或者复制后删除

阅读全文 »

#shell

  • systemctl start docker - 启动
  • service docker restart - 重启
  • docker version - 查看运行状态
  • /etc/docker/daemon.json - 镜像源文件
    1
    2
    3
    4
    `vim /etc/docker/daemon.json` 
    {
    "registry-mirrors": ["https://registry.docker-cn.com"]
    }

镜像相关

  • docker image ls - 列出已下载的镜像

  • docker image ls -f dangling=true - 查看虚悬镜像, 有的镜像更新后可能会出现既没有仓库名,也没有标签,均为 ,称为虚悬镜像,可用此命令查看

  • docker image prune - 一般来说,虚悬镜像已经失去了存在的价值,是可以随意删除的,可以用此命令删除。

  • docker rm $(docker ps -aq) - 删除所有镜像

  • docker rm -v - 删除镜像时同事删除其数据卷

  • docker rmi $(docker images -q) - 删除所有镜像

  • docker rmi -f 127.0.0.1:8082/weiba/nginx:weiba - 删除指定tag容器

  • docker save 镜像id > tomcat8-apr.tar - 导出镜像

  • docker load < tomcat8-apr.tar - 导入镜像

  • docker rmi docker images | grep "<none>" | awk '{print $3}' 删除所有none镜像

  • docker rmi -f docker images | grep "<none>" | awk '{print $3}' 强制删除所有none镜像

    1
    2
    3
    4
    5
    6
    7
    镜像和容器 导出和导入的区别
    镜像导入和容器导入的区别:
    1)容器导入 是将当前容器 变成一个新的镜像
    2)镜像导入 是复制的过程
    save 和 export区别:
    1)save 保存镜像所有的信息-包含历史
    2)export 只导出当前的信息
  • docker history 90457edaf6ff - 查看镜像/容器历史操作记录

容器相关

  • docker container rm trusting_newton - 清理指定的处于终止状态的容器

  • docker container prune - 清理所有处于终止状态的容器

  • docker container start xxx - 重新启动终止的容器

  • docker ps - 查看运行中的容器

  • docker container ls - 查看运行的容器状态

  • docker container ls -a - 查看所有已经创建的包括终止状态的容器

  • docker inspect web - 查看web容器的信息

  • docker stop 容器id&&docker container stop xxx - 停止指定容器, 在docker stop命令执行的时候,会先向容器中PID为1的进程发送系统信号SIGTERM,然后等待容器中的应用程序终止执行,如果等待时间达到设定的超时时间,或者默认的10秒,会继续发送SIGKILL的系统信号强行kill掉进程。

  • docker kill xxx&&docker container kill xxx - 立刻停止容器,该命令不会等待容器中的应用终止。

  • docker stop $(docker ps -aq) - 停止所有容器

  • docker restart 容器id - 重启指定容器

  • docker export b91d9ad83efa > tomcat80824.tar - 导入容器

  • docker import tomcat80824.tar - 导入容器

  • docker import http://example.com/exampleimage.tgz example/imagerepo - 从网络导入

    1
    注:用户既可以使用 docker load 来导入镜像存储文件到本地镜像库,也可以使用 docker import 来导入一个容器快照到本地镜像库。这两者的区别在于容器快照文件将丢弃所有的历史记录和元数据信息(即仅保存容器当时的快照状态),而镜像存储文件将保存完整记录,体积也要大。此外,从容器快照文件导入时可以重新指定标签等元数据信息。
阅读全文 »

最近公司发布会由于是异地举行,被部署搞的很伤,连续加了几天班,大多都是因为运行环境问题,所以这次会后,领导准备全面使用docker,将整体服务容器化,后期使用自动部署解决这个问题。我们现在使用的是Spring Cloud,比较容易迁移,自己也一直想看看docker,在deepin上测试一下。

安装Docker

根据deepin官方wiki安装即可: Deepin安装Docker教程

Docker 详细文档:Docker文档

Docker 仓库:https://store.docker.com/
要注意的地方:

  • 添加docker仓库的时候,注意更换版本代号,因为deepin是基于debian的,所以改成debian的即可。我的deepin15.8debian版为8.0,版本号改为jessie即可。
    相关命令:
阅读全文 »

写的非常详细,可以直接去原文看: Docker(1)底层实现

以下存档防止丢失~~

Docker底层实现

Docker并没有传统虚拟化的Hypervisor层,因为dokcer是基于容器技术的轻量级虚拟化,相对于传统的虚拟化,省去了Hypervisor层的开销,而且其虚拟化技术是基于内核的Cgroup和Namespace技术,处理逻辑与内核深度融合,所以在很多方面,docker的性能与物理机非常接近

在通信上,Docker并不会直接与内核交互,它是通过一个更底层的工具Libcontainer与内核交互的,__Libcontainer 是真正意义上的容器引擎,它通过clone系统调用直接创建容器,通过pivot_root系统调用进入容器,且通过直接操作cgroupfs文件实现对资源的管控__

Docker本身则侧重于处理更上层的业务

阅读全文 »

CommUtils.js

js 工具集合:

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
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353

/**
* 工具类
*/
"use strict";
var CommUtils = window.CommUtils = {
//字符串动态替换
// CommUtils.formatStr("{0}不能为{1}", "分数", "0" -> "分数不能为0"
formatStr : function(){
var args = Array.prototype.slice.apply(arguments);
var that = this;
if (args.length == 0) {
return null;
} else if (args.length == 1) {
return args[0];
} else {
var template = args[0];
args.splice(0,1);
if (typeof args[0] == 'object') {
$.each(args[0], function(key, value) {
template = template.replace(new RegExp("{" + key + "}", "g"), that.isEmpty(value) ? '' : value);
})
} else {
$.each(args, function(key, value) {
template = template.replace(eval("/({)" + key + "(})/g"), that.isEmpty(value) ? '' : value);
})
}
return template;
}
},
// layer tip 封装
// CommUtils.initTip(); // 先载入jq扩展
// $("#id").tip("提示信息", top, 12000)
initTip : function() {
$.fn.tip = function(content, direct, time) {
if (direct == undefined) direct = 'bottom';
direct = ['top', 'right', 'bottom', 'left'].indexOf(direct) + 1;
var index = layer.tips(content, this, {
tips : [direct, '#f5c564'],
time : time ? time : 2000,
anim : 6,
tipsMore : true
});
if (direct == 3) {
$('.layui-layer-tips[times="' + index + '"] .layui-layer-content').css('top', '-8px');
} else if (direct == 2) {
$('.layui-layer-tips[times="' + index + '"] .layui-layer-content').css('left', '-8px');
} else if (direct == 1) {
$('.layui-layer-tips[times="' + index + '"] .layui-layer-content').css('top', '8px');
} else if (direct == 4) {
$('.layui-layer-tips[times="' + index + '"] .layui-layer-content').css('left', '8px');
}
}
},
// layer 弹出层
openFrame : function(title, url, width, height) { //layer frame窗口
this.layerWindow = layer.open({
type: 2,
anim: -1,
resize: false,
title: title,
shadeClose: false,
maxmin: true,
shade: 0.6,
area: [width || '90%', height || '90%'],
content: url //iframe的url
});
},
// 对象判空并初始化
ifEmpty : function(obj, defaultValue) {
return this.isEmpty(obj) ? this.isEmpty(defaultValue) ? '' : defaultValue : obj;
},
// 对象判空
isEmpty : function(arg) {
if (arg == undefined || arg == null) {
return true;
}
if (typeof arg == 'string') {
return arg == '' ? true : false;
} else if (typeof arg == 'object') {
if (arg instanceof Array && arg.length == 0) {
return true;
} else {
return false;
}
} else if (typeof arg == 'number') {
return false;
} else{
return !!arg;
}
},
// 对象不为空
isNotEmpty: function(arg) {
return !this.isEmpty(arg);
},
// 计算文件大小
getFileSize : function(size){ //根据大小计算文件大小
var unit = ["B", "KB", "MB", "GB", "TB"];
var result = size,i = 0;
for (; i <= 4; i++) {
if (result > 1024) {
result = result / 1024;
result = result.toFixed(2);
} else {
break;
}
}
if (i > 4) { i= 4;}
return result + unit[i];
},
// 格式化时间
formatDate : function (date, fmt) { //author: meizz
var o = {
"M+": date.getMonth() + 1, //月份
"d+": date.getDate(), //日
"h+": date.getHours(), //小时
"m+": date.getMinutes(), //分
"s+": date.getSeconds(), //秒
"q+": Math.floor((date.getMonth() + 3) / 3), //季度
"S": date.getMilliseconds() //毫秒
};
if (/(y+)/.test(fmt)) fmt = fmt.replace(RegExp.$1, (date.getFullYear() + "").substr(4 - RegExp.$1.length));
for (var k in o)
if (new RegExp("(" + k + ")").test(fmt)) fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
return fmt;
},
// ajax 封装
ajax : function(url, param, success, method, async) { //异步请求
var _this = this;
if (async == undefined) {
async = true;
}
$.ajax({
url : url,
data : param,
type : method || "get",
async : async,
success : function(data) {
if (data.status == 1) {
success && success(data.data);
return ;
}
if (data.message) {
_this.tipBox(data.message);
} else {
_this.tipBox(i18n['systemErr']);
}
},
error : function(data) {
_this.tipBox(i18n['systemErr']);
}
});
},
// 对象深拷贝
clone : function(data){
if (data == null) return null;
var newData = null, _this = this;
if (typeof data == 'object') {
if (data.length != undefined) {
newData = [];
$.each(data, function(i, value) {
newData.push(_this.clone(value));
});
} else {
newData = {};
$.each(data, function(key, value) {
newData[key] = _this.clone(value);
});
}
} else {
newData = data;
}
return newData;
},
// map转list
mapTranList: function(mapTemp) {
var listTemp = [];
for(var key in mapTemp){
listTemp.push(mapTemp[key]);
}
return listTemp;
},
// jq 文件上传封装, verificationImageFileMap: 文件校验map, 重复文件不再上传
uploadFile: function(event, uploadFileUrl, verificationImageFileMap) {
var response = {
'successFiles' : [],
'errorFiles': []
};
var tempFileName = '';
for (var i = 0; i < event.target.files.length; i++) {
var formData = new FormData();
var file = event.target.files[i];
tempFileName = file.name;
var fileKey = tempFileName + file.size;
if (this.isEmpty(verificationImageFileMap) || this.isEmpty(verificationImageFileMap[fileKey])) {
formData.append('file', file);
formData.append("name", tempFileName);
$.ajax({
url : uploadFileUrl,
type : 'POST',
data : formData,
// 告诉jQuery不要去处理发送的数据
processData : false,
// 告诉jQuery不要去设置Content-Type请求头
contentType : false,
async: false,
beforeSend:function(){
},
success : function(responseStr) {
response.successFiles.push(responseStr);
},
error : function(responseStr) {
console.log("文件上传失败!" + responseStr);
response.errorFiles.push({
'fileName': tempFileName
});
}
});
}
}
e.target.value='';
return response;
},

/* layui 等待 */
showLoad: function (msg) {
return layer.msg(msg, {
icon: 16,
shade: [0.5, '#f5f5f5'],
scrollbar: false,
offset: 'auto',
time: 100000
});
},
closeLoad: function (index) {
layer.close(index);
},
showSuccess: function (msg) {
layer.msg(msg, {time: 1500, offset: 'auto', icon: 1});
},
showFail: function (msg) {
layer.msg(msg, {time: 1500, offset: 'auto', icon: 2});
},
closeLayer : function() {
if (!!this.layerWindow) {
layer.close(this.layerWindow);
} else {
var index= window.parent.layer.getFrameIndex(window.name)
window.parent.layer.close(index);
}
},
// 页面间传递数据 parent.postMessage(data);
onMessage : function(callback) { //监听发送到本窗口的消息
if (window.addEventListener){
window.addEventListener('message',function(event){
callback && callback(event);
}, false);
} else if(window.attachEvent) {
window.attachEvent("onmessage", function (event) {
callback && callback(event);
});
}
},
// 字符串处理
filterString: function(content, type) {
var _this = this;
// 过滤中文
if (type === 1) {
return content.replace(/[\u4e00-\u9fa5]/g,'')
} else if (type === 2) { // 数字转中文
if (isNaN(Number(node.points))) {
return;
}
return _this.numberToChinese(content);
}
},
// 数字转中文
numberToChinese : function(number) {
if (isNaN(Number(number))) {
console.error("this is not number!");
return number;
}
var chnNumChar = ["零","一","二","三","四","五","六","七","八","九"];
var chnUnitChar = ["","十","百","千","万","亿","万亿","亿亿"];
var strIns = '', chnStr = '';
var unitPos = 0;
var zero = true;
while(number > 0){
var v = number % 10;
if(v === 0){
if(!zero){
zero = true;
chnStr = chnNumChar[v] + chnStr;
}
}else{
zero = false;
strIns = chnNumChar[v];
// 10-19不要前缀
if (unitPos === 1 && v === 1) {
strIns = chnUnitChar[unitPos];
} else {
strIns += chnUnitChar[unitPos]
}
chnStr = strIns + chnStr;
}
unitPos++;
number = Math.floor(number / 10);
}
return chnStr;
},
// 修改编辑字符后光标移动至末尾
moveCursorEnd : function(obj) {
obj.focus(); //解决ff不获取焦点无法定位问题
var range = window.getSelection();//创建range
range.selectAllChildren(obj);//range 选择obj下所有子内容
range.collapseToEnd();//光标移至最后
}
};

// web localStorage 存储工具类
var StorageOperation = CommUtils.StorageOp = {
get : function (key) {
if (window.localStorage) {
var prefix = this.getPrefix();
var item = window.localStorage.getItem(prefix + key);
if (item == undefined || item == undefined || item.trim() == '') {
return null;
}
item = JSON.parse(item);
if (item.end < new Date().getMilliseconds()) {
window.localStorage.removeItem(prefix + key);
return null;
}
return item.data;
}
},
set : function(key, value, timeoutMills) {
if (CommUtils.isEmpty(timeoutMills)) {
timeoutMills = 604800000;
}
if (window.localStorage) {
var prefix = this.getPrefix();
var data = {
'end' : new Date().getMilliseconds() + timeoutMills,
'data' : value
}
window.localStorage.setItem(prefix + key, JSON.stringify(data));
}
},
getPrefix : function() {
return 'timeout_storage_';
}
}