wangyuheng's Blog

time for change

转载请注明出处WangYuheng’s Blog

现象

在eclipse中搜索时,搜索完之后有时候会弹出错误对话框,错误摘录如下

Resource is out of sync with the file system......

原因

由于eclipse中文件不同步引起的。

在eclipse中,工程文件是由eclipse自动扫描添加的,如果在外部修改了工程目录中的文件但又关闭了自动刷新功能,则会引起文件不同步,从而搜索时出现Resource is out of sync with the file system问题(其它功能可能也会如此)。此外,在外部没有修改eclipse工程中的文件也有可能引起该问题。

解决方法

有两种解决方法

  1. 手动刷新。即在eclipse的工程目录中,右键refresh(或者按下F5)。
  2. 配置eclipse的选项
    • eclipse启动时,刷新workspace,即勾选 window—>preferences—>general—>startup and shutdown—>refresh workspace on startup
    • window—>preferences—>general—>workspace中:勾选选项:refresh using native hooks or polling和refresh on access;

转载请注明出处WangYuheng’s Blog

现象

java程序报错

java.sql.SQLException: Lock wait timeout exceeded; try restarting transaction

原因

业务中update语句需要通过子查询where条件,子查询的select中需要调用外部表的参数作为条件。
随着数据量的增加,sql语句执行过慢,请求过于频繁,导致死锁。

解决方法

  • 不建议增加线程锁,可通过适当的增加索引,优化sql语句执行速度。
  • 尽量避免子查询,exists替代in
  • 亦可先执行select查询,保存在结果集中,再进行批量update操作。
  • 将两个操作增加事务标签。
  • 如果sql语句无法优化,可能是由错误的业务逻辑导致。

转载请注明出处WangYuheng’s Blog

前因

一直在找样式模板,始终不太满意,看到了http://ant.design 封装了一系列的react模块控件,样式和动画效果也不错,觉得这就是自己想要的,兴冲冲的上手。但在使用过程中遇到了一些小坑,本文意在让和我一样的小白用户能够顺利开始使用Ant Design

环境准备

安装nodejs

一些脚手架工具都是基于nodejs环境开发,所以需要现在本机安装nodejs环境。可在 nodejs官网 下载对应系统的nodejs安装文件。现在nodejs有两个分支

  1. 长期支持版LTS(推荐)
  2. 最新版

本文基于最新的LTS版本v4.5.0 LTS

升级npm

npm是nodejs附带的一个包管理工具,需要使用npm安装antd,但是附带的npm版本可能过低,导致出现依赖问题。所以安装完nodejs之后,就将npm升级到最新版本

npm -v
npm install -g npm
npm -v

切换镜像仓库

如果npm下载速度过慢,可以用淘宝封装的npm镜像仓库替换

npm install -g cnpm --registry=https://registry.npm.taobao.org

安装完成后就可以使用cnpm命令替换npm

安装antd

安装的坑一般都在环境准备上,antd的安装及使用过程在官网有着详细介绍 http://ant.design/docs/react/getting-started

以下为简单的记录自己的安装过程。

安装脚手架

npm install antd-init -g

创建项目

mkdir antd-demo && cd antd-demo
antd-init --type plain-react

执行antd-init时,需要下载依赖,可能需要一段时间等待

启动项目

npm start

启动后,可以通过 http://localhost:8989 查看效果。在修改antd-demo中的文件后,不需要刷新,即可查看效果。

感悟

很喜欢react的模块化思想,antd提供的样式组件及动画,给个人的开发工作提供了极大的便利。通过查看Ant Design中对组件的封装过程,也是一个学习和理解react的过程。

转载请注明出处WangYuheng’s Blog

传统的表单提交方式,在提交之后,会跳转到一个新页面。
采用ajax的方式,可以在页面不发生跳转的前提条件下,与服务器进行数据通信(提交表单,并获取服务器端的返回数据),从而实现局部刷新。
不仅仅是提高了性能,更重要的是,提供了一种强大的灵活性。

Asynchronous javascript and XML

尽管名称中的x表示了xml,其实现在更通用的一种方式是通过json格式进行数据通信。
原因是json格式更加小巧,且支持更好。js自带。

转载请注明出处WangYuheng’s Blog

问题描述

js插件挡住了页面元素,希望自定义js插件显示的布局位置。

code

<script>引入js插件时传递layout布局参数。

1. 通过url参数方式获取

js可以获取url中的参数

1
2
3
4
5
6
7
8
9
if(location.href.indexOf("?")>-1) {
var params = location.href.substr(location.href.indexOf("?")+1).split("&");
for (var i=0;i<params.length;i++){
var kv = params[i].split("=");
var key = kv[0];
var value = kv[1];
console.log("key="+key+" value="+value);
}
}

同理,可以先获取script标签中的src属性,再通过上面的方法,获取layout参数

1
<script src="listen.js?layout=right"></script>

在js插件文件中通过如下代码获取

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
var layout="right";
var scripts = document.getElementsByTagName("script");
for (var i=0; i< scripts.length;i++) {
var script = scripts[i];
if (script && script.getAttribute("src") && script.getAttribute("src").indexOf("listen.js")>-1) {
var url = script.getAttribute("src");
var params = url.substr(url.indexOf("?")+1).split("&");
for (var i=0;i<params.length;i++){
var kv = params[i].split("=");
var key = kv[0];
var value = kv[1];
if("layout" == key) {
layout = value;
}
}
}

}
console.log(layout);

2. 通过自定义属性获取

通过上面的方法,可以想到既然能获取src属性,那么也可以自定义布局属性,并通过getAttribute()方法获取。

1
<script src="listen.js" layout="right"></script>

在js插件文件中通过如下代码获取

1
2
3
4
5
6
7
8
9
var layout="right";
var scripts = document.getElementsByTagName("script");
for (var i=0; i< scripts.length;i++) {
var script = scripts[i];
if (script && script.getAttribute("src") && script.getAttribute("src").indexOf("listen.js")>-1 && script.getAttribute("layout")) {
layout = script.getAttribute("layout");
}
}
console.log(layout);

结论

通过从代码上来看,第二种方法更简单,而问过几个朋友,都更喜欢第二种配置方式,所以在这里推荐使用自定义属性获取属性。

1
2
<script src="listen.js?layout=right"></script>
<script src="listen.js" layout="right"></script>

转载请注明出处WangYuheng’s Blog

Listen

初心

个人网站,会让朋友随便点点,试用一下,并提一些建议。如果通过聊天工具,比较麻烦,不方便整理。
打算开发一个意见反馈的js插件,加载到页面之中,可以让用户第一时间输入意见,并在页面中能看到意见列表,及解决状态。

设计

由3部分构成

  1. 前台输入页面
  2. 数据中心
  3. 意见解决页面

前台输入页面

面向网站浏览用户,负责意见输入、采集工作。
采用js插件的形式,方便集成到不同的web页面中。
通过js控制HTML元素,设置样式,布局在页面的某个角落,不影响原页面。
通过json格式与数据中心进行通信,利用原生ajax形式,不依赖任何第三方库。

数据中心

存储意见数据。
根据域名区分不同租户。
通过restful,以json格式传递数据。
可跨域访问。

意见解决页面

可查看不同租户下意见。
解决或者输入不解决原因。
通过json格式与数据中心进行通信。

实现

前台输入页面

var Listen = {
    submitUrl: '',
    listUrl: '',
    submit: function(){},
    list: function(){}
}

转载请注明出处WangYuheng’s Blog

[问题]

Iterator remove()时抛出异常 java.lang.IllegalStateException

List<String> list = new ArrayList<String>();
list.add("a");
list.add("b");
list.add("c");
list.add("d");
Iterator<String> it = list.iterator();
int i =3;
while(it.hasNext()) {
//                it.next();
    if (i-->1) {
        it.remove();
    }
}
System.out.println(list.size());

[原因]

没有调用next() 方法

[怎么发现的]

跟踪代码,查看Iterator.class源码,在源码注释中看到

/**
 * 
 * Removes from the underlying collection the last element returned by the
 * iterator (optional operation).  This method can be called only once per
 * call to <tt>next</tt>.  The behavior of an iterator is unspecified if
 * the underlying collection is modified while the iteration is in
 * progress in any way other than by calling this method.
 *
 * @exception UnsupportedOperationException if the <tt>remove</tt>
 *          operation is not supported by this Iterator.
 
 * @exception IllegalStateException if the <tt>next</tt> method has not
 *          yet been called, or the <tt>remove</tt> method has already
 *          been called after the last call to the <tt>next</tt>
 *          method.
 */
void remove();

[修复]

先调用next()方法,再调用remove()方法

[我导致的]

是的

[解决Bug的时间]

3分钟

[教训]

需要熟悉Iterator使用方法及设计原理

转载请注明出处WangYuheng’s Blog

[问题]

编写js插件,利用innerHTML=innerHTML+plugin_content 渲染插件内容后,原网站绑定事件失效。

[原因]

jquery html元素绑定后,重新渲染页面后,没有重新绑定,所以失效。

[怎么发现的]

引用插件后,页面上的click事件无效。

[修复]

修改插件的渲染方式为 createElement元素后,通过appendChild添加到页面上。

[我导致的]

是的

[解决Bug的时间]

5分钟

[教训]

编写插件时,不能影响已有元素,不能侵入和耦合。了解页面的重绘。

转载请注明出处WangYuheng’s Blog

工作几年,发现并不了解log日志,只会简单的log.info(),并不知道如何配置以及更多的用法,每次遇到线上问题时,都是连蒙带猜,或者临时再加log。
这次下定决心,学习一下log,并在之后的项目中,保持良好的log习惯。

本次学习以log4j为主。在2015年8月,官方宣布停止对log4j 1.x版本的维护,并推荐只用log4j 2。但本文仍基于现有大多数项目所使用的1.x版本,并会在日后专门写一篇文章比较1.x 和2.x。

简介

log4j = log for java,是apache维护的一个强大的java日志记录模块。

优势

  1. log4j是一个通用接口,可以在不改变语法的前提下,在多种程序语言中使用。
  2. 通过配置文件,在不改变程序的前提下,变更日志。
  3. 指定输出目录和输出格式。
  4. 通过级别控制,使log记录更灵活。

配置

引入包

通过maven引入log4j包,版本为1.2.16

<dependencies>
        <!-- Logging -->
    <dependency>
        <groupId>log4j</groupId>
        <artifactId>log4j</artifactId>
        <version>1.2.16</version>
    </dependency>
</dependencies>

代码配置

个人习惯,在学习一个东西之前,能让我用最少的代码运行一遍,并看到效果。

0%