少年阿宾

那些青春的岁月

  BlogJava :: 首页 :: 联系 :: 聚合  :: 管理
  500 Posts :: 0 Stories :: 135 Comments :: 0 Trackbacks

#

1、冒泡排序:
冒泡排序(BubbleSort)的基本概念是:依次比较相邻的两个数,将小数放在前面,大数放在后面。即在第一趟:首先比较第1个和第2个数,将小数放前,大数放后。然后比较第2个数和第3个数,将小数放前,大数放后,如此继续,直至比较最后两个数,将小数放前,大数放后。至此第一趟结束,将最大的数放到了最后。在第二趟:仍从第一对数开始比较(因为可能由于第2个数和第3个数的交换,使得第1个数不再小于第2个数),将小数放前,大数放后,一直比较到倒数第二个数(倒数第一的位置上已经是最大的),第二趟结束,在倒数第二的位置上得到一个新的最大数(其实在整个数列中是第二大的数)。如此下去,重复以上过程,直至最终完成排序。

具体代码例一:

package com.abin.lee.algorithm.bubble;

public class BubbleSort {
 public static void main(String[] args) {
  int[] start={5,2,1,3,6,4};
  int[] end=sort(start);
  for(int i=0;i<end.length;i++){
   System.out.println("end["+i+"]="+end[i]);
  }
 }
 
 public static int[] sort(int[] input){
  int temp=0;

  //最多做n-1趟排序
  for(int i=0;i<input.length-1;i++){
    //对当前无序区间score[0......length-i-1]进行排序(j的范围很关键,这个范围是在逐步缩小的)
   for(int j=0;j<input.length-i-1;j++){
    //把大的值交换到后面
    if(input[j]>input[j+1]){
     temp=input[j];
     input[j]=input[j+1];
     input[j+1]=temp;
    }
    StringBuffer stb=new StringBuffer();
    for(int k=0;k<input.length;k++){
     stb.append("input["+k+"]="+input[k]+" ");
    }
    System.out.println("i="+i+",j="+j+" = "+stb.toString());
   }
  }
  return input;
 }

 

}


2、选择排序:
选择排序(Straight Select Sorting) 也是一种简单的排序方法,它的基本思想是:第一次从R[0]~R[n-1]中选取最小值,与R[0]交换,第二次从R{1}~R[n-1]中选取最小值,与R[1]交换,....,   第i次从R[i-1]~R[n-1]中选取最小值,与R[i-1]交换,.....,第n-1次从R[n-2]~R[n-1]中选取最小值,与R[n-2]交换,总共通过n-1次,得到一个按排序码从小到大排列的有序序列.
具体代码:

package com.abin.lee.algorithm.select;

public class SelectSort {
 public static void main(String[] args) {
  int[] start={5,2,3,1,6,4};
  start=sort(start);
  for(int i=0;i<start.length;i++){
   System.out.println("start["+i+"]="+start[i]);
  }
 }
 public static int[] sort(int[] input){
  int temp=0;
  for(int i=0;i<input.length;i++){
   for(int j=i+1;j<input.length;j++){
    if(input[i]>input[j]){
     temp=input[i];
     input[i]=input[j];
     input[j]=temp;
    }
    StringBuffer stb=new StringBuffer();
    for(int k=0;k<input.length;k++){
     stb.append("input["+k+"]="+input[k]+" ");
    }
    System.out.println("i="+i+",j="+j+" = "+stb.toString());
   }
  }
  return input;
 }
}




3、请输入一个数字,比如4,输出为:
1
2 3
4 5 6
7 8 9 10

代码如下:

package com.abin.lee.photo;

public class TestInputNumber {
 public static void main(String[] args) {
  int n=4;
  output(n);
 }
 public static void output(int n){
  int temp=1;
  for(int i=1;i<=n;i++){
   for(int j=0;j<i;j++){
    System.out.print(temp+" ");
    temp++;
   }
   System.out.println("");
  }
  
 }
}


4.二叉树算法

package com.abin.lee.algorithm.binary;

public class BinaryNode {
 public int data;//根节点
 BinaryNode left;//左节点
 BinaryNode right;//右节点
 
 public BinaryNode(int data,BinaryNode left,BinaryNode right) {
  this.data=data;
  this.left=left;
  this.right=right;
 }
 
 public int getData() {
  return data;
 }
 public void setData(int data) {
  this.data = data;
 }
 public BinaryNode getLeft() {
  return left;
 }
 public void setLeft(BinaryNode left) {
  this.left = left;
 }
 public BinaryNode getRight() {
  return right;
 }
 public void setRight(BinaryNode right) {
  this.right = right;
 }
}




package com.abin.lee.algorithm.binary;

public class BinaryTree {
 //前序遍历
 public static void preOrder(BinaryNode root){
  if(null!=root){
   System.out.print(root.data+"-");
   preOrder(root.left);
   preOrder(root.right);
  }
 }
 //中序遍历
 public static void inOrder(BinaryNode root){
  if(null!=root){
   inOrder(root.left);
   System.out.print(root.data+"--");
   inOrder(root.right);
  }
 }
 //后序遍历
 public static void postOrder(BinaryNode root){
  if(null!=root){
   postOrder(root.left);
   postOrder(root.right);
   System.out.print(root.data+"---");
  }
 }
 
 public static void main(String[] args) {
  BinaryNode one=new BinaryNode(1,null,null);
  BinaryNode three=new BinaryNode(3,null,null);
  BinaryNode two=new BinaryNode(2,three,one);
  BinaryNode four=new BinaryNode(4,one,two);
  BinaryNode five=new BinaryNode(5,four,one);
  System.out.println("preOrder");
  preOrder(five);
  System.out.println();
  System.out.println("inOrder");
  inOrder(five);
  System.out.println();
  System.out.println("postOrder");
  postOrder(five);
  System.out.println();
  
 }

}


输出结果:
preOrder
5-4-1-2-3-1-1-
inOrder
1--4--3--2--1--5--1--
postOrder
1---3---1---2---4---1---5---




5、java插入排序

插入式排序法——插入排序法

插入排序(Insertion Sortion)的基本思想是:把n个待排序的元素看成一个有序表和一个无序表,开始有序表只包含一个元素,无序表中包含n-1个元素,排序过程中每次从无序表中取出第一个元素,把它的排序码依次与有序表元素的排序码进行比较,将它插入到有序表中的适当位置,使之成为新的有序表。


public class InjectionSort  //定义一个 InjectionSort 类
public static void injectionSort(int[] number) //传数组
for(int j = 1;j<number.length;j++)//循环
int tmp = number[j]; //循环把数组第二个值放到tmp里
int i = j-1//给i 赋值
while(tmp<number[i]) //tmp值和数组第一个值比较谁小
number[i+1] = number[i]; //如果小于就把第一个值赋值给第二个
i--;
if(i == -1)//如果i值=-1
break; //退出循环
number[i+1] = tmp //因为比较数组里的前一个比后一个这样就换交了实现了把小的放在前面
这是第一次,因为循环是一个数组,后边的就一次往下循环,最后就把数组里的顺序从小到大排序了
public static void main(String[] args){
int[] num = {5,46,26,67,2,35};//定义数组num
injectionSort(num);//调用方法
for(int i = 0;i<num.length;i++){
System.out.println(num[i]);//显示排序后的数组,一行显示一个值

简单说就是数组里第二个和第一个比谁小,把小的放到第一个里,大的放到第二个里,然后第二个再和第三个比,小的还是放在前,一直比到这个数组结束,这样就实现了从小到大,希望我说的够详细


插入排序代码while循环:
package com.abin.lee.algorithm.insert;
public class InsertSort {
public static void main(String[] args) {
int[] input = { 1, 3, 5, 7, 9, 2, 4, 6, 8, 0 };
input=sort(input);
for (int i = 0; i < input.length; i++) {
System.out.print(input[i] + "  ");
}
}
public static int[] sort(int[] input) {
for (int i = 1; i < input.length; i++) {
int insertVal = input[i];
// insertValue准备和前一个数比较
int index = i - 1;
while (index >= 0 && insertVal < input[index]) {
// 将把input[index]向后移动
input[index + 1] = input[index];
// 让index向前移动一位
index--;
}
// 将insertValue插入到适当位置
input[index + 1] = insertVal;
//下面这个循环是为了打印一下中间的循环看看是不是插入排序的正确算法
StringBuffer stb=new StringBuffer();
for(int k=0;k<input.length;k++){
stb.append(input[k]+" ");
}
System.out.println("i="+i+" = "+stb.toString());
}
return input;
}
}


插入排序for循环代码:

package com.abin.lee.algorithm.insert;
public class DoInsertSort {
public static void main(String[] args) {
int[] input={5,4,6,3,7,2,8,1,0,9};
input=sort(input);
for(int i=0;i<input.length;i++){
System.out.print("input["+i+"]="+input[i]+" ");
}
}
public static int[] sort(int[] input){
for(int i=1;i<input.length;i++){
int temp=input[i];
int j;
for(j=i;j>0;j--){
if(temp<input[j-1]){
input[j]=input[j-1];
}else{
break;
}
}
input[j]=temp;
//下面这个循环是为了打印一下中间的循环看看是不是插入排序的正确算法
StringBuffer stb=new StringBuffer();
for(int k=0;k<input.length;k++){
stb.append(input[k]+" ");
}
System.out.println("i="+i+" = "+stb.toString());
}
return input;
}
}


 

二分查找又称折半查找,它是一种效率较高的查找方法。

折半查找的算法思想是将数列按有序化(递增或递减)排列,查找过程中采用跳跃式方式查找,即先以有序数列的中点位置为比较对象,如果要找的元素值小于该中点元素,则将待查序列缩小为左半部分,否则为右半部分。通过一次比较,将查找区间缩小一半。 折半查找是一种高效的查找方法。它可以明显减少比较次数,提高查找效率。但是,折半查找的先决条件是查找表中的数据元素必须有序。

package com.abin.algorithm.template.half;

public class BinarySearch {
public static void main(String[] args) {
int[] src=new int[]{1,3,5,7,9,11};
int result=binarySearch(src, 3);
System.out.println("result="+result);
int status=binarySearch(src, 9 ,0 ,src.length);
System.out.println("status="+status);
}
//循环实现
public static int binarySearch(int[] src,int key){
int low=0;
int high=src.length-1;
while(low<=high){
int middle=(low+high)/2;
if(key==src[middle]){
return middle;
}else if(key<src[middle]){
high=middle-1;
}else{
low=middle+1;
}
}
return -1;
}
//递归实现
public static int binarySearch(int[] src,int key,int low,int high){
int middle=(low+high)/2;
if(src[middle]==key){
return middle;
}else if(low>=high){
return -1;
}else if(src[middle]>key){
return binarySearch(src, key, low, middle-1);
}else if(src[middle]<key){
return binarySearch(src, key, middle+1, high);
}
return -1;
}

}


posted @ 2013-09-05 16:27 abin 阅读(574) | 评论 (0)编辑 收藏

<style type="text/css">
div.remark
{
white-space:nowrap; 
width:6em; 
overflow:hidden;
text-overflow:ellipsis;
    }
</style>
<div class="remark">${refundApply.remarks }</div> 
posted @ 2013-09-04 16:14 abin 阅读(1208) | 评论 (4)编辑 收藏

repcached实现memcached的复制功能:
repcached是日本人开发的实现memcached复制功能,它是一个单 master单 slave的方案,但它的 master/slave都是可读写的,而且可以相互同步,如果 master坏掉, slave侦测到连接断了,它会自动 listen而成为 master;而如果 slave坏掉, master也会侦测到连接断,它就会重新 listen等待新的 slave加入
安装:
先安装memcached(我安装的1.2.8)
有两种方式:
方式一、下载对应的repcached版本
#wget http://downloads.sourceforge.net/repcached/memcached-1.2.8-repcached-2.2.tar.gz
#tar zxf memcached-1.2.8-repcached-2.2.tar.gz
#cd memcached-1.2.8-repcached-2.2
方式二、下载对应patch版本
#wget http://downloads.sourceforge.net/repcached/repcached-2.2-1.2.8.patch.gz
#gzip -cd ../repcached-2.2-1.2.8.patch.gz | patch -p1
#./configure --enable-replication
# make
# make install
启动:
启动master
#memcached -v -l 192.168.50.240 -p 11211 -uroot
replication: listen (master监听)
启动salve
#memcached -v -l 192.168.50.241 -p 11213 -uroot -x 127.0.0.1 -X 11212
replication: connect (peer=192.168.50.240:11212)
replication: marugoto copying
replication: start
启动正常后,masteraccept测试:
操作master
#telnet 192.168.50.240 11211
#set key1 0 0 3
111
查看slave
#telnet 192.168.50.241 11213
#get key1
如果正常表示,配置成功
应用:
可以实现cache冗余
注意:如果master down机,slave接管并成为master,这时down机的master只能启用slave,他们之间互换角色,才能保持复制功能。换句话说,master没有抢占功能。
posted @ 2013-08-24 17:15 abin 阅读(709) | 评论 (0)编辑 收藏

一、Memcache内存分配机制

        关于这个机制网上有很多解释的,我个人的总结如下。

  1. Page为内存分配的最小单位。

    Memcached的内存分配以page为单位,默认情况下一个page是1M,可以通过-I参数在启动时指定。如果需要申请内存时,memcached会划分出一个新的page并分配给需要的slab区

  2.  

  3.  

  4. 域。page一旦被分配在重启前不会被回收或者重新分配(page ressign已经从1.2.8版移除了) 

  5. Slabs划分数据空间。

    Memcached并不是将所有大小的数据都放在一起的,而是预先将数据空间划分为一系列slabs,每个slab只负责一定范围内的数据存储。如下图,每个slab只存储大于其上一个slab的size并小于或者等于自己最大size的数据。例如:slab 3只存储大小介于137 到 224 bytes的数据。如果一个数据大小为230byte将被分配到slab 4中。从下图可以看出,每个slab负责的空间其实是不等的,memcached默认情况下下一个slab的最大值为前一个的1.25倍,这个可以通过修改-f参数来修改增长比例。 

  6.   

  7. Chunk才是存放缓存数据的单位。

    Chunk是一系列固定的内存空间,这个大小就是管理它的slab的最大存放大小。例如:slab 1的所有chunk都是104byte,而slab 4的所有chunk都是280byte。chunk是memcached实际存放缓存数据的地方,因为chunk的大小固定为slab能够存放的最大值,所以所有分配给当前slab的数据都可以被chunk存下。如果时间的数据大小小于chunk的大小,空余的空间将会被闲置,这个是为了防止内存碎片而设计的。例如下图,chunk size是224byte,而存储的数据只有200byte,剩下的24byte将被闲置。 

  8.  


  9.  

  10. Slab的内存分配。

    Memcached在启动时通过-m指定最大使用内存,但是这个不会一启动就占用,是随着需要逐步分配给各slab的。
             如果一个新的缓存数据要被存放,memcached首先选择一个合适的slab,然后查看该slab是否还有空闲的chunk,如果有则直接存放进去;如果没有则要进行申请。slab申请内存时以page为单位,所以在放入第一个数据,无论大小为多少,都会有1M大小的page被分配给该slab。申请到page后,slab会将这个page的内存按chunk的大小进行切分,这样就变成了一个chunk的数组,在从这个chunk数组中选择一个用于存储数据。如下图,slab 1和slab 2都分配了一个page,并按各自的大小切分成chunk数组。 

  11.  


  12.  

  13. Memcached内存分配策略。

    综合上面的介绍,memcached的内存分配策略就是:按slab需求分配page,各slab按需使用chunk存储。
    这里有几个特点要注意,

    1. Memcached分配出去的page不会被回收或者重新分配
    2. Memcached申请的内存不会被释放
    3. slab空闲的chunk不会借给任何其他slab使用
       每一个slab=1M   切分的chunk个数=1M/最小的chunk大小
      下一个chunk=上一个chunk大小*增长因子


 

      知道了这些以后,就可以理解为什么总内存没有被全部占用的情况下,memcached却出现了丢失缓存数据的问题了。
*******************
当存储的值item大于1M的时候:

按照官方解释,当大于1M时,按现有的 slab allocation内存分配管理机制,memcache的存取效率会下降很多,就失去了使用memcache的意义,之所以用memcache,一大原因就是它比数据库速度快,如果失去了速度优势,就没意思了。
 支持大于1M的方法 官方也给出了:一个是还是使用slab allocation 机制修改源代码中 POWER_BLOCK  的值,然后重新编译。另一个方法是使用低效的 malloc/free 分配机制。 
 如果某个常用slab满了  而且又没开启LRU,会出现命中低的情况·

 1M/最小的chunk=存储的个数
然后第二个chunk=第一个chunk*1.25
这样1M被不断的分
切到最后1M只能存一个chunk

  1M 用完会申请一个新的 1M

但是 不能超过你的最大内存数
超过了 就开始回收
也就是LRU
 当memcache每次在get的时候会检测key所对应的value过期时间  那么当检测到此item过期了 value会被清除  key呢 保留 还是也会被清除 ?
不会被清除,只会返回空
直到lru覆盖这个过期值
那就是当我程序弃用了大量的key时  cmd_get时 这些key 还会被扫描到?
不会
只是还存在内存里  占着内存
posted @ 2013-08-23 17:06 abin 阅读(883) | 评论 (0)编辑 收藏

有些符号在URL中是不能直接传递的,如果要在URL中传递这些特殊符号,那么就要使用他们的编码了。下表中列出了一些URL特殊符号及编码

十六进制值

 

1 + URL 中+号表示空格 %2B
2 空格 URL中的空格可以用+号或者编码 %20
3 / 分隔目录和子目录 %2F
4 ? 分隔实际的 URL 和参数 %3F
5 % 指定特殊字符 %25
6 # 表示书签 %23
7 & URL 中指定的参数间的分隔符 %26
8 = URL 中指定参数的值 %3D

 
  解决的方法:

  replace() 方法如果直接用str.replace("-","!") 只会替换第一个匹配的字符.

  而str.replace(/\-/g,"!")则可以替换掉全部匹配的字符(g为全局标志)。

  replace()

  js中替换字符变量如下:

  data2=data2.replace(/\%/g,"%25");

  data2=data2.replace(/\#/g,"%23");

  data2=data2.replace(/\&/g,"%26");

posted @ 2013-08-22 20:23 abin 阅读(541) | 评论 (0)编辑 收藏

如何用jquery获取<input id="test" name="test" type="text"/>中输入的值?
$("#test").val()
$("input[name='test']").val()
$("input[type='text']").val()
$("input[type='text']").attr("value")
posted @ 2013-08-22 10:55 abin 阅读(71501) | 评论 (0)编辑 收藏

1.struts的toke原理
      Struts本身有一套完善的防止重复提交表单的Token(令牌)机制,但笔者目前的项目自写的framework没有用到Struts,故也得自写防止用户因为后退或者刷新来重复提交表单内容的Token机制。不难,容易实现。实现原理:一致性。jsp生成表单时,在表单中插入一个隐藏<input>字段,该字段就是保存在页面端的token字符串,同时把该字符串存入session中。等到用户提交表单时,会一并提交该隐藏的token字符串。在服务器端,查看下是否在session中含有与该token字符串相等的字符串。如果有,那么表明是第一次提交该表单,然后删除存放于session端的token字符串,再做正常业务逻辑流程;如果没有,那么表示该表单被重复提交,做非正常流程处理,可以警告提示也可以什么也不做。
2.
posted @ 2013-08-21 13:43 abin 阅读(1222) | 评论 (2)编辑 收藏

行级锁:
select * from abin1 t where t.id=21 for update;

表级锁:
lock table abin1 IN EXCLUSIVE MODE (nowait);
posted @ 2013-08-20 22:38 abin 阅读(607) | 评论 (0)编辑 收藏

memcached

 Memcached 是一个高性能的分布式内存对象缓存系统,用于动态Web应用以减轻数据库负载。它通过在内存中缓存数据和对象来减少读取数据库的次数,从而提供动态、数据库驱动网站的速度。Memcached基于一个存储键/值对的hashmap。其守护进程(daemon )是用C写的,但是客户端可以用任何语言来编写,并通过memcached协议与守护进程通信。但是它并不提供冗余(例如,复制其hashmap条目);当某个服务器S停止运行或崩溃了,所有存放在S上的键/值对都将丢失。

Memcached官方:http://danga.com/memcached/

关于Memcached的介绍请参考:Memcached深度分析

下载Windows的Server端

下载地址:http://code.jellycan.com/memcached/

windows服务端下载地址:
http://code.jellycan.com/files/memcached-1.2.6-win32-bin.zip
windows服务端安装:
http://www.cnblogs.com/xd502djj/archive/2012/09/25/2701800.html
http://www.cnblogs.com/wucg/archive/2011/03/01/1968185.html
ehcache集群的相关文章:
http://www.cnblogs.com/yangy608/archive/2011/10/07/2200669.html
http://www.cnblogs.com/hoojo/archive/2012/07/19/2599534.html
http://www.open-open.com/lib/view/open1345651870876.html

以图为例
Cache A、Cache B,Cache C为三台Memcached服务器
根据三台Memcached的IP和端口,计算出他们的Hash值,然后分布在整个圆环上
每两台Memcached服务器的Hash值之间为一个区间
Key1、Key2、Key3、Key4
为要存储在Memcached里的4个Key
根据4个Key计算出他们的Hash值,同样也落在这个圆环上
在这个环形空间中,如果沿着顺时针方向从对象的 key 值出发,直到遇见一个 cache ,那么就将该对象存储在这个 cache 上,因为对象和 cache 的 hash 值是固定的,因此这个 cache 必然是唯一和确定的。
根据上面的方法,对象 key1 将被存储到 cache A 上; key2 和 key3 对应到 cache C ; key4 对应到 cache B;
同一个key不是三台服务器上面都有映射, 只会映射到其中一台服务器上面

集群中其中一个Memcached节点宕机,会导致存在着上面的Key全部失效而重新对这些key进行hash
对其他活着的Memcached节点上的key没有影响

如果是集群
Set和Get时触发操作的是否为同一个配置
如果是多个应用服务器触发Set、Get操作,每一个的Memcached节点配置顺序是否相同
可以通过telnet的方式,去Memcached节点上Get一下响应的Key,看是否真的过期

你分析一下你的slab构成,看看每个slab分配了多少page页,加起来是不是跟总分配内存一样,如果是一样的表示你的内存已经分配完了,每个slab只能使用已分配的大小,不能再增涨。再分析一下存这个value的slab的大小,如果比较小,且hits量很大,就会出现你这样的情况,刚存没多久的数据没到过期就会被挤掉。

失效就几种可能:
1,cache满了,刚插进去就被lru剔出来
2,失效时间设置不对,导致数据一插进去就失效(不能超过30天)

 使用了64的操作系统,能分配2GB以上的内存。32位操作系统中,每个进程最多只能使用2GB内存。可以启动多个分配2GB以下内存的进程,但这样一台服务器上的TCP连接数就会成倍增加,管理上也变得复杂,所以尽量统一使用了64位操作系统。
另外,最好分配内存为3GB,是因为内存分配量超过这个值,就有可能导致内存交换(swap),memcached的内存存储“slab”, memcached启动时指定的内存分配量是memcached用于保存数据的量,没有包括“slab”本身占用的内存、以及为了保存数据而设置的管理空间。因此,memcached进程的实际内存分配量要比指定的容量要大。
如果在memcached中的数据大部分都比较小。这样,进程的大小要比指定的容量大很多。因此,改变内存分配量进行验证,确认了3GB的大小不会引发swap。

 64位操作系统不受限制(小于你的物理内存大小即可),不过得注意Memcache软件本身是有内存消耗的(相比可以忽略),但这点还是注意一下。
posted @ 2013-08-09 17:34 abin 阅读(574) | 评论 (0)编辑 收藏

 <script type="text/javascript" >
  var EventUtil = {
       addHandler: function (element, type, handler) {
           if (element.addEventListener) {
               element.addEventListener(type, handler, false);
           } else if (element.attachEvent) {
               element.attachEvent("on" + type, handler);
           } else {
               element["on" + type] = handler;
           }
       }
   };
   EventUtil.addHandler(document, "DOMContentLoaded", function (event) {
    setTimeout(function(){
     var imgs=document.getElementsByTagName("img");
     for (var i =0; i<=imgs.length;i++){
      var img=imgs[i];
      var height,width;
      height=img.naturalHeight;
      width=img.naturalWidth;
      if((height==0&&width==0)){
       img.src="";
       img.parentNode.parentNode.hidden=true;
       var nid=img.getAttribute('nid');
       document.getElementById('divNoneImg'+nid).style.display="block";
      }
     }
    }, 2000);
   });

 </script>

posted @ 2013-07-31 14:33 abin 阅读(444) | 评论 (0)编辑 收藏

仅列出标题
共50页: First 上一页 10 11 12 13 14 15 16 17 18 下一页 Last