2017年1月

javascript块级的作用域

在做其它语言开发时,对块级的作用域的范围十分了解,但是js只有函数作用域,没有块级作用域的概念,下面的例子很好的说明这个情况:

for(var i =0;i<10;i++){
  console.log(i) 
}
console.log("out of for function,i="+i)

最后打印的是out of for function,i=10 。这一点非常重要,在使用for的时候需要避免这个陷阱,同时变量名不要定义过于简单,免得变量污染。
下面可以扩展阅读:
js作用域详解:http://blog.csdn.net/yueguanghaidao/article/details/9568071
防止js全局变量污染方法总结:http://blog.csdn.net/xllily_11/article/details/52816699
理解JS闭包:http://www.jb51.net/article/83524.htm
jQuery中noconflict函数的实现原理分解:http://www.jb51.net/article/60688.htm

网址编码URLEncoder的基本过程

大致过程是(针对非asscii):
1:将空格转换为加号 (+) ;
2:将非文本内容转换成"%xy"的形式,xy是两位16进制的数值,例如:0x9c --> %9c;
3:在每个 name=value 对之间放置 & 符号

源码的核心代码为:

String str = new String(charArrayWriter.toCharArray());
            byte[] ba = str.getBytes(charset);
            for (int j = 0; j < ba.length; j++) {
                out.append('%');
                char ch = Character.forDigit((ba[j] >> 4) & 0xF, 16);
                // converting to use uppercase letter as part of
                // the hex value if ch is a letter.
                if (Character.isLetter(ch)) {
                    ch -= caseDiff;
                }
                out.append(ch);
                ch = Character.forDigit(ba[j] & 0xF, 16);
                if (Character.isLetter(ch)) {
                    ch -= caseDiff;
                }
                out.append(ch);
            }

https://www.w3.org/TR/html40/appendix/notes.html#non-ascii-chars
Although URIs do not contain non-ASCII values (see [URI], section 2.1) authors sometimes specify them in attribute values expecting URIs (i.e., defined with %URI; in the DTD). For instance, the following href value is illegal:

...
We recommend that user agents adopt the following convention for handling non-ASCII characters in such cases:

Represent each character in UTF-8 (see [RFC2279]) as one or more bytes.
Escape these bytes with the URI escaping mechanism (i.e., by converting each byte to %HH, where HH is the hexadecimal notation of the byte value).
This procedure results in a syntactically legal URI (as defined in [RFC1738], section 2.2 or [RFC2141], section 2) that is independent of the character encoding to which the HTML document carrying the URI may have been transcoded.

Note. Some older user agents trivially process URIs in HTML using the bytes of the character encoding in which the document was received. Some older HTML documents rely on this practice and break when transcoded. User agents that want to handle these older documents should, on receiving a URI containing characters outside the legal set, first use the conversion based on UTF-8. Only if the resulting URI does not resolve should they try constructing a URI based on the bytes of the character encoding in which the document was received.

Note. The same conversion based on UTF-8 should be applied to values of the name attribute for the A element.

crontab使用日期时间命名日志文件

定时任务没有小时固定执行,每次任务都是独立的,如果日志文件没有分开,在排查问题的时候比较难看,在crontab里面可以根据时间来,注意的是需要把%号前面加斜杠。如下所示:

0 * * * * cd /opt/backend-job/ && sh main.sh >> /data/crontab/lock$(date +"\%Y\%m\%d\%H").log

什么是缓存击穿以及解决方法

在高并发场景下,如果某一个key被高并发访问,没有被命中,出于对容错性考虑,会尝试去从后端数据库中获取,从而导致了大量请求达到数据库,而当该key对应的数据本身就是空的情况下,这就导致数据库中并发的去执行了很多不必要的查询操作,从而导致巨大冲击和压力。
所以在编写此类缓存的时候要注意潜在的实效缓存的情况,考虑这个缓存的意义和使用的场景,即要考虑考虑命中率的问题。
参考:
http://www.cnblogs.com/dinglang/p/6133501.html
http://www.jianshu.com/p/d96906140199

classloader加载的双亲委托模式[转]

做Java开发,对于ClassLoader的机制是必须要熟悉的基础知识,本文针对Java ClassLoader的机制做一个简要的总结。因为不同的JVM的实现不同,本文所描述的内容均只限于Hotspot Jvm.
本文将会从JDK默认的提供的ClassLoader,双亲委托模型,如何自定义ClassLoader以及Java中打破双亲委托机制的场景四个方面入手去讨论和总结一下。
JDK默认ClassLoader
JDK 默认提供了如下几种ClassLoader

  1. Bootstrp loader
    Bootstrp加载器是用C++语言写的,它是在Java虚拟机启动后初始化的,它主要负责加载%JAVA_HOME%/jre/lib,-Xbootclasspath参数指定的路径以及%JAVA_HOME%/jre/classes中的类。
  2. ExtClassLoader
    Bootstrp loader加载ExtClassLoader,并且将ExtClassLoader的父加载器设置为Bootstrploader.ExtClassLoader是用Java写的,具体来说就是 sun.misc.Launcher$ExtClassLoader,ExtClassLoader主要加载%JAVA_HOME%/jre/lib/ext,此路径下的所有classes目录以及java.ext.dirs系统变量指定的路径中类库。
  3. AppClassLoader
    Bootstrp loader加载完ExtClassLoader后,就会加载AppClassLoader,并且将AppClassLoader的父加载器指定为 ExtClassLoader。AppClassLoader也是用Java写成的,它的实现类是sun.misc.Launcher$AppClassLoader,另外我们知道ClassLoader中有个getSystemClassLoader方法,此方法返回的正是AppclassLoader.AppClassLoader主要负责加载classpath所指定的位置的类或者是jar文档,它也是Java程序默认的类加载器。
    综上所述,它们之间的关系可以通过下图形象的描述:
    双亲委托模型
    Java中ClassLoader的加载采用了双亲委托机制,采用双亲委托机制加载类的时候采用如下的几个步骤:
  4. 当前ClassLoader首先从自己已经加载的类中查询是否此类已经加载,如果已经加载则直接返回原来已经加载的类。
    每个类加载器都有自己的加载缓存,当一个类被加载了以后就会放入缓存,等下次加载的时候就可以直接返回了。
  5. 当前classLoader的缓存中没有找到被加载的类的时候,委托父类加载器去加载,父类加载器采用同样的策略,首先查看自己的缓存,然后委托父类的父类去加载,一直到bootstrp ClassLoader.
  6. 当所有的父类加载器都没有加载的时候,再由当前的类加载器加载,并将其放入它自己的缓存中,以便下次有加载请求的时候直接返回。
    说到这里大家可能会想,Java为什么要采用这样的委托机制?理解这个问题,我们引入另外一个关于Classloader的概念“命名空间”, 它是指要确定某一个类,需要类的全限定名以及加载此类的ClassLoader来共同确定。也就是说即使两个类的全限定名是相同的,但是因为不同的ClassLoader加载了此类,那么在JVM中它是不同的类。明白了命名空间以后,我们再来看看委托模型。采用了委托模型以后加大了不同的 ClassLoader的交互能力,比如上面说的,我们JDK本生提供的类库,比如hashmap,linkedlist等等,这些类由bootstrp 类加载器加载了以后,无论你程序中有多少个类加载器,那么这些类其实都是可以共享的,这样就避免了不同的类加载器加载了同样名字的不同类以后造成混乱。
    不遵循“双亲委托机制”的场景
    上面说了双亲委托机制主要是为了实现不同的ClassLoader之间加载的类的交互问题,被大家公用的类就交由父加载器去加载,但是Java中确实也存在父类加载器加载的类需要用到子加载器加载的类的情况。下面我们就来说说这种情况的发生。
    Java中有一个SPI(Service Provider Interface)标准,使用了SPI的库,比如JDBC,JNDI等,我们都知道JDBC需要第三方提供的驱动才可以,而驱动的jar包是放在我们应 用程序本身的classpath的,而jdbc 本身的api是jdk提供的一部分,它已经被bootstrp加载了,那第三方厂商提供的实现类怎么加载呢?这里面JAVA引入了线程上下文类加载的概念,线程类加载器默认会从父线程继承,如果没有指定的话,默认就是系统类加载器(AppClassLoader),这样的话当加载第三方驱动的时候,就可 以通过线程的上下文类加载器来加载。
    另外为了实现更灵活的类加载器OSGI以及一些Java appserver也打破了双亲委托机制。

参考:
http://blog.csdn.net/wangyang1354/article/details/49448007
http://www.cnblogs.com/xxbcoder/p/5112632.html
http://blog.csdn.net/zhangzeyuaaa/article/details/42499839