ï»??xml version="1.0" encoding="utf-8" standalone="yes"?>91在线视频免费观看,美洲精品一卡2卡三卡4卡四卡,四虎精品成人免费网站http://www.aygfsteel.com/mstar/黑灵的没啥技术含量的技术博å®? -> http://zjumty.iteye.comzh-cnThu, 19 Jun 2025 07:21:55 GMTThu, 19 Jun 2025 07:21:55 GMT60在传输层上压¾~©WebService的请求和响应 http://www.aygfsteel.com/mstar/archive/2013/06/23/400884.html黑灵黑灵Sun, 23 Jun 2013 13:45:00 GMThttp://www.aygfsteel.com/mstar/archive/2013/06/23/400884.htmlhttp://www.aygfsteel.com/mstar/comments/400884.htmlhttp://www.aygfsteel.com/mstar/archive/2013/06/23/400884.html#Feedback1http://www.aygfsteel.com/mstar/comments/commentRss/400884.htmlhttp://www.aygfsteel.com/mstar/services/trackbacks/400884.html阅读全文

黑灵 2013-06-23 21:45 发表评论
]]>
在MongoDB里实现åó@环序列功èƒ?http://www.aygfsteel.com/mstar/archive/2013/04/26/398469.html黑灵黑灵Fri, 26 Apr 2013 14:57:00 GMThttp://www.aygfsteel.com/mstar/archive/2013/04/26/398469.htmlhttp://www.aygfsteel.com/mstar/comments/398469.htmlhttp://www.aygfsteel.com/mstar/archive/2013/04/26/398469.html#Feedback1http://www.aygfsteel.com/mstar/comments/commentRss/398469.htmlhttp://www.aygfsteel.com/mstar/services/trackbacks/398469.html

环境是这æ ïLš„åQšæœåŠ¡å™¨æ˜¯ç”¨Java做的åQ?数据库是MongoDB

 

需求是˜q™æ ·çš„:我们的系¾lŸé‡Œè¦ç”Ÿæˆä¸€ä¸ªå”¯ä¸€IDåQŒå‰é¢çš„部分有一定的格式åQŒåƈ和时间关联, ¾_„¡¡®åˆ°å¾®¿U’,考虑到同一微秒内有可能存在òq¶å‘情况åQ? 所以后面在加两位序列号åQ?¾pȝ»Ÿéœ€è¦å®šä¹‰äØ“1毫秒内的òq¶å‘ž®äºŽ100个,所以后面两位就够用了ã€? Java服务器端有多台机器都可以用来生成˜q™ä¸ªå”¯ä¸€IDåQŒæ‰€ä»¥éœ€è¦åœ¨ä¸åŒçš„æœºå™¨ä¸Šä¸èƒ½ç”Ÿæˆç›¸åŒçš„序列号åQŒæ‰€ä»¥éœ€è¦åœ¨æŸä¸€ç‚¹ä¸Šåšå…¨å±€çš„范围同步来保存˜q™åºåˆ? åïLš„唯一性ã€?其实如果不考虑需求里的唯一ID是有一定意义的格式的, 用UUID或MongoDBçš„ObjectId都是更好的选择åQŒå®Œå…¨ä¸éœ€è¦åœ¨æŸä¸€ç‚¹ä¸Š˜q›è¡ŒåŒæ­¥åQŒæ€§èƒ½ä¼šæ›´å¥½ã€?/p>

 

˜q™ä¸ªå¯ä»¥ç”Ÿæˆåºåˆ—åïLš„点, 我们可以做一个序列号生成服务器来对应åQ?也可以用数据库来对应ã€? å•å•ä¸ø™¿™ä¸ªç®€å•的功能准备一个服务器来做昄¡„¶ä¸åˆé€‚ã€?但是我们用的MongoDBòq¶æ²¡æœ‰ç±»ä¼égºŽMySQL或Oracle中的SELECT FOR UPDATE˜q™æ ·çš„锁机制ã€?所以没有办法简单的对这个序列号做原子操作ã€? 但是MongoDB的对单个document˜q›è¡Œupdate操作中有很是å…ähœ‰åŽŸå­æ€§çš„åQ?例如

  • $set
  • $unset
  • $inc
  • $push
  • $pushAll
  • $pull
  • $pullAll

我们可以利用˜q™äº›åŽŸå­æ“ä½œåQŒåœ¨æ•°æ®åº“层以乐观锁的åÅžå¼æ¥å®žçŽ°å¾ªçŽ¯åºåˆ—å­—æ®µã€‚äØ“äº†æ–¹ä¾¿è°ƒç”¨æˆ‘æŠŠè¿™ŒDµé€»è¾‘做成数据库中的Javascript函数ã€?¾cÖM¼¼ä¸ŽMySQL中的存储˜q‡ç¨‹ã€?/p>

 

首先我们需要一个collection来存攑ֺåˆ—号åQŒåƈ寚wœ€è¦çš„需要的序列可‚¿›è¡Œåˆå§‹åŒ–。我们叫它countersã€?/p>

Js代码  æ”¶è—ä»£ç 
  1. db.counters.save({_id:"SerialNo1", val:0, maxval:99})  

 

然后我们想system.js里添加一个Javascript函数

Js代码  æ”¶è—ä»£ç 
  1. db.system.js.save({_id:"getNextUniqueSeq",  
  2. value:function (keyName) {  
  3.     var seqObj = db.counters.findOne({_id:keyName});  
  4.     if (seqObj == null) {  
  5.         print("can not find record with key: " + keyName);  
  6.         return -1;  
  7.     }  
  8.       
  9.     // the max value of sequence  
  10.     var maxVal = seqObj.maxval;  
  11.     // the current value of sequence  
  12.     var curVal = seqObj.val;  
  13.       
  14.     while(true){  
  15.         // if curVal reach max, reset it  
  16.         if(curVal >= maxVal){  
  17.             db.counters.update({_id : keyName, val : curVal}, { $set : { val : 0 }}, falsefalse);  
  18.             var err = db.getLastErrorObj();  
  19.             if( err && err.code ) {  
  20.                 print( "unexpected error reset data: " + tojson( err ) );  
  21.                 return -2;  
  22.             } else if (err.n == 0){  
  23.                 // fail to reset value, may be reseted by others  
  24.                 print("fail to reset value: ");  
  25.             }   
  26.   
  27.             // get current value again.  
  28.             seqObj = db.counters.findOne({_id:keyName});  
  29.             maxVal = seqObj.maxval;  
  30.             curVal = seqObj.val;  
  31.             continue;  
  32.         }   
  33.           
  34.         // if curVal not reach the max, inc it;  
  35.         // increase   
  36.         db.counters.update({_id : keyName, val : curVal}, { $inc : { val : 1 }}, falsefalse);  
  37.         var err = db.getLastErrorObj();  
  38.         if( err && err.code ) {  
  39.             print( "unexpected error inc val: " + tojson( err ) );  
  40.                return -3;  
  41.         } else if (err.n == 0){  
  42.             // fail to reset value, may be increased by others  
  43.             print("fail to inc value: ");  
  44.               
  45.             // get current value again.  
  46.             seqObj = db.counters.findOne({_id:keyName});  
  47.             maxVal = seqObj.maxval;  
  48.             curVal = seqObj.val;  
  49.             continue;  
  50.         } else {  
  51.             var retVal = curVal + 1;  
  52.             print("success to get seq : " + retVal);  
  53.             // increase successful  
  54.             return retVal;  
  55.         }  
  56.     }  
  57. }  
  58. });  

上面˜q™æ®µä¼šæŠŠæŒ‡å®šçš„序列号的valå€?1åQŒå¦‚æžœval辑ֈ°ä¸Šé™åˆ™ä»Ž0开始。所以叫循环序列ã€?/p>

 

其实上面的实现在原理上和Java里的AtomicInteger¾pÕdˆ—的功能实现是¾cÖM¼¼çš„,利用循环重试和原子性的CAS来实现。这¿Uå®žçŽ°æ–¹å¼åœ¨å¤šçº¿½E‹çš„环境里由于锁åQˆMonitoråQ‰çš„范围很小åQŒæ‰€ä»¥åƈ发性上比排他锁要好一些ã€?/p>

 

下面我们用Java来测试一下这个函数的正确性ã€?卛_œ¨å¤šçº¿½E‹çš„æƒ…况下会不会得到重复的序列号ã€?/p>

 

½W¬ä¸€ä¸ªæµ‹è¯•,val=0åQ?maxval=2000åQ?Javaç«?0个线½E‹æ¯ä¸ªçº¿½E‹åó@环调ç”?00‹Æ¡ã€?å…?000‹Æ¡ã€?所以正¼‹®çš„æƒ…况下,ä»?åˆ?999应该每个数字只出çŽîC¸€‹Æ¡ã€?/p>

 

Java代码  æ”¶è—ä»£ç 
  1. @Test  
  2. public void testGetNextUniqueSeq1() throws Exception {  
  3.   
  4.     final int THREAD_COUNT = 20;  
  5.     final int LOOP_COUNT = 100;  
  6.   
  7.     Mongo mongoClient = new Mongo("172.17.2.100"27017);  
  8.     DB db = mongoClient.getDB("im");  
  9.     db.authenticate("imadmin""imadmin".toCharArray());  
  10.     BasicDBObject q = new BasicDBObject();  
  11.     q.put("_id""UNIQUE_KEY");  
  12.   
  13.     BasicDBObject upd = new BasicDBObject();  
  14.     BasicDBObject set = new BasicDBObject();  
  15.     set.put("val"0);  
  16.     set.put("maxval", THREAD_COUNT * LOOP_COUNT);  
  17.     upd.put("$set", set);  
  18.   
  19.     db.getCollection("counters").update(q, upd);  
  20.   
  21.     Thread[] threads = new Thread[THREAD_COUNT];  
  22.     final int[][] results = new int[THREAD_COUNT][LOOP_COUNT];  
  23.     for (int i = 0; i < THREAD_COUNT; i++) {  
  24.         final int temp_i = i;  
  25.         threads[i] = new Thread("" + i) {  
  26.             @Override  
  27.             public void run() {  
  28.                 try {  
  29.                     Mongo mongoClient = new Mongo("172.17.2.100"27017);  
  30.                     DB db = mongoClient.getDB("im");  
  31.                     db.authenticate("imadmin""imadmin".toCharArray());  
  32.                     for (int j = 0; j < LOOP_COUNT; j++) {  
  33.                         Object result = db.eval("getNextUniqueSeq(\"UNIQUE_KEY\")");  
  34.                         System.out.printf("Thread %s, seq=%d\n", Thread.currentThread().getName(), ((Double) result).intValue());  
  35.                         results[temp_i][j] = ((Double) result).intValue();  
  36.                     }  
  37.                 } catch (UnknownHostException e) {  
  38.                     e.printStackTrace();  
  39.                 }  
  40.             }  
  41.         };  
  42.     }  
  43.   
  44.     for (Thread thread : threads) {  
  45.         thread.start();  
  46.     }  
  47.   
  48.     for (Thread thread : threads) {  
  49.         thread.join();  
  50.     }  
  51.   
  52.     for (int num = 1; num <= LOOP_COUNT * THREAD_COUNT; num++) {  
  53.         // every number appear 1 times only!  
  54.         int times = 0;  
  55.         for (int j = 0; j < THREAD_COUNT; j++) {  
  56.             for (int k = 0; k < LOOP_COUNT; k++) {  
  57.                 if (results[j][k] == num)  
  58.                     times++;  
  59.             }  
  60.         }  
  61.   
  62.         assertEquals(1, times);  
  63.     }  
  64. }  

 

然后我们再测试一下åó@环的情况ã€?val=0, maxval=99ã€?同样是Javaç«?0个线½E‹æ¯ä¸ªçº¿½E‹åó@环调ç”?00‹Æ¡ã€?å…?000‹Æ¡ã€‚è¿™‹Æ¡ä»Ž0åˆ?9的数字每个应该取å¾?0‹Æ¡ã€?/p>

 

Java代码  æ”¶è—ä»£ç 
  1. @Test  
  2. public void testGetNextUniqueSeq2() throws Exception {  
  3.   
  4.     final int THREAD_COUNT = 20;  
  5.     final int LOOP_COUNT = 100;  
  6.   
  7.     Mongo mongoClient = new Mongo("172.17.2.100"27017);  
  8.     DB db = mongoClient.getDB("im");  
  9.     db.authenticate("imadmin""imadmin".toCharArray());  
  10.     BasicDBObject q = new BasicDBObject();  
  11.     q.put("_id""UNIQUE_KEY");  
  12.   
  13.     BasicDBObject upd = new BasicDBObject();  
  14.     BasicDBObject set = new BasicDBObject();  
  15.     set.put("val"0);  
  16.     set.put("maxval", LOOP_COUNT);  
  17.     upd.put("$set", set);  
  18.   
  19.     db.getCollection("counters").update(q, upd);  
  20.   
  21.     Thread[] threads = new Thread[THREAD_COUNT];  
  22.     final int[][] results = new int[THREAD_COUNT][LOOP_COUNT];  
  23.     for (int i = 0; i < THREAD_COUNT; i++) {  
  24.         final int temp_i = i;  
  25.         threads[i] = new Thread("" + i) {  
  26.             @Override  
  27.             public void run() {  
  28.                 try {  
  29.                     Mongo mongoClient = new Mongo("172.17.2.100"27017);  
  30.                     DB db = mongoClient.getDB("im");  
  31.                     db.authenticate("imadmin""imadmin".toCharArray());  
  32.                     for (int j = 0; j < LOOP_COUNT; j++) {  
  33.                         Object result = db.eval("getNextUniqueSeq(\"UNIQUE_KEY\")");  
  34.                         System.out.printf("Thread %s, seq=%d\n", Thread.currentThread().getName(), ((Double) result).intValue());  
  35.                         results[temp_i][j] = ((Double) result).intValue();  
  36.                     }  
  37.                 } catch (UnknownHostException e) {  
  38.                     e.printStackTrace();  
  39.                 }  
  40.             }  
  41.         };  
  42.     }  
  43.   
  44.     for (Thread thread : threads) {  
  45.         thread.start();  
  46.     }  
  47.   
  48.     for (Thread thread : threads) {  
  49.         thread.join();  
  50.     }  
  51.   
  52.     for (int num = 1; num <= LOOP_COUNT; num++) {  
  53.         // every number appear 20 times only!  
  54.         int times = 0;  
  55.         for (int j = 0; j < THREAD_COUNT; j++) {  
  56.             for (int k = 0; k < LOOP_COUNT; k++) {  
  57.                 if (results[j][k] == num)  
  58.                     times++;  
  59.             }  
  60.         }  
  61.   
  62.         assertEquals(20, times);  
  63.     }  
  64. }  

 

˜q™ä¸ª‹¹‹è¯•跑了几次都是正确的ã€?/p>

 

ç”׃ºŽæ²¡æœ‰å¯ä»¥˜q›è¡Œå¯Òޝ”其他的实现方式(例如排他锁)所以没有做性能‹¹‹è¯•ã€?/p>

 

写在最后ã€?虽然MongoDB支持¾cÖM¼¼äºŽå­˜å‚¨è¿‡½E‹çš„Stored JavascriptåQŒä½†æ˜¯å…¶å®žä¸å»ø™®®ä½¿ç”¨˜q™ä¸ªæ¥è§£å†›_¤æ‚问题。主要原因是没法调试åQŒç»´æŠ¤è“v来太不方ä¾Ñ€‚而且åœ?.4之前MongoDBå¯ÒŽœåŠ¡ç«¯ Javascript支持òq¶ä¸æ˜¯å¾ˆå¥½ï¼Œ 一个mongod˜q›ç¨‹åŒæ—¶åªèƒ½æ‰§è¡Œä¸€ŒDµJavascript。如果能在应用层解决掉还是在应用层里实现逻辑比较好ã€?/p>



黑灵 2013-04-26 22:57 发表评论
]]>
输出debug信息到postfix的loghttp://www.aygfsteel.com/mstar/archive/2013/04/26/398459.html黑灵黑灵Fri, 26 Apr 2013 11:25:00 GMThttp://www.aygfsteel.com/mstar/archive/2013/04/26/398459.htmlhttp://www.aygfsteel.com/mstar/comments/398459.htmlhttp://www.aygfsteel.com/mstar/archive/2013/04/26/398459.html#Feedback0http://www.aygfsteel.com/mstar/comments/commentRss/398459.htmlhttp://www.aygfsteel.com/mstar/services/trackbacks/398459.html
/etc/postfix/main.cf

debug_peer_list = example.com
debug_peer_level = 2

/etc/postfix/master.cf
smtp      inet  n       -       n       -       -       smtpd -v


黑灵 2013-04-26 19:25 发表评论
]]>
Java里的CompareAndSet(CAS)http://www.aygfsteel.com/mstar/archive/2013/04/24/398351.html黑灵黑灵Wed, 24 Apr 2013 09:20:00 GMThttp://www.aygfsteel.com/mstar/archive/2013/04/24/398351.htmlhttp://www.aygfsteel.com/mstar/comments/398351.htmlhttp://www.aygfsteel.com/mstar/archive/2013/04/24/398351.html#Feedback0http://www.aygfsteel.com/mstar/comments/commentRss/398351.htmlhttp://www.aygfsteel.com/mstar/services/trackbacks/398351.html Atomic 从JDK5å¼€å§? java.util.concurrentåŒ…é‡Œæä¾›äº†å¾ˆå¤šé¢å‘åÆˆå‘ç¼–½E‹çš„¾c? 使用˜q™äº›¾cÕdœ¨å¤šæ ¸CPU的机器上会有比较好的性能.
主要原因是这些类里面大多使用(å¤ÞpÓ|-重试方式çš?乐观锁而不是synchronized方式的悲观锁.

今天有时间跟ítªäº†ä¸€ä¸‹AtomicIntegerçš„incrementAndGet的实çŽ?
本ähå¯¹åÆˆå‘ç¼–½E‹ä¹Ÿä¸æ˜¯ç‰¹åˆ«äº†è§£, 在这里就是做个笔è®? 方便以后再深入研½I?

1. incrementAndGet的实�br />
    public final int incrementAndGet() {
        
for (;;) {
            
int current = get();
            
int next = current + 1;
            
if (compareAndSet(current, next))
                
return next;
        }
    }

首先可以看到他是通过一个无限åó@çŽ?spin)直到increment成功为止. 
循环的内å®ÒŽ˜¯
1.取得当前å€?br />2.计算+1后的å€?br />3.å¦‚æžœå½“å‰å€ÆD¿˜æœ‰æ•ˆ(没有è¢?的话讄¡½®é‚£ä¸ª+1后的å€?br />4.如果讄¡½®æ²¡æˆåŠ?当前值已¾læ— æ•ˆäº†åŒ™¢«åˆ«çš„¾U¿ç¨‹æ”¹è¿‡äº?, 再从1å¼€å§?

2. compareAndSet的实�br />
    public final boolean compareAndSet(int expect, int update) {
        
return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
    }

直接调用的是UnSafe˜q™ä¸ª¾cȝš„
compareAndSwapIntæ–ÒŽ³•
全称�/span>
sun.misc.Unsafe. ˜q™ä¸ª¾cÀL˜¯Oracle(Sun)提供的实çŽ? 可以在别的公司的JDK里就不是˜q™ä¸ª¾cÖMº†

3.
compareAndSwapInt的实�br />
    /**
     * Atomically update Java variable to <tt>x</tt> if it is currently
     * holding <tt>expected</tt>.
     * 
@return <tt>true</tt> if successful
     
*/
    
public final native boolean compareAndSwapInt(Object o, long offset,
                                                  
int expected,
                                                  
int x);

可以看到, 不是用Java实现çš? 而是通过JNI调用操作¾pȝ»Ÿçš„原生程åº?

4.
compareAndSwapInt的native实现
如果你下载了OpenJDK的源代码的话在hotspot\src\share\vm\prims\目录下可以找到unsafe.cpp
UNSAFE_ENTRY(jboolean, Unsafe_CompareAndSwapInt(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jint e, jint x))
  UnsafeWrapper(
"Unsafe_CompareAndSwapInt");
  oop p 
= JNIHandles::resolve(obj);
  jint
* addr = (jint *) index_oop_from_field_offset_long(p, offset);
  
return (jint)(Atomic::cmpxchg(x, addr, e)) == e;
UNSAFE_END

可以看到实际上调�/span>
Atomic¾cȝš„cmpxchgæ–ÒŽ³•.

5.
Atomicçš?/span>cmpxchg
˜q™ä¸ª¾cȝš„实现是跟操作¾pȝ»Ÿæœ‰å…³, è·ŸCPU架构也有å…? 如果是windows下x86的架æž?br />实现在hotspot\src\os_cpu\windows_x86\vm\目录的atomic_windows_x86.inline.hppæ–‡äšgé‡?br />
inline jint     Atomic::cmpxchg    (jint     exchange_value, volatile jint*     dest, jint     compare_value) {
  
// alternative for InterlockedCompareExchange
  int mp = os::is_MP();
  __asm {
    mov edx, dest
    mov ecx, exchange_value
    mov eax, compare_value
    LOCK_IF_MP(mp)
    cmpxchg dword ptr [edx], ecx
  }
}

在这里可以看到是用嵌入的汇编实现çš? 关键CPU指ä×oæ˜?/span>
cmpxchg
到这里没法再往下找代码äº? 也就是说CAS的原子性实际上是CPU实现çš? 其实在这一点上˜q˜æ˜¯æœ‰æŽ’他锁çš? 只是比è“v用synchronized, ˜q™é‡Œçš„æŽ’他时间要短的å¤? 所以在多线½E‹æƒ…况下性能会比较好.

代码里有�/span>
alternative for InterlockedCompareExchange
˜q™ä¸ª
InterlockedCompareExchange是WINAPI里的一个函æ•? 做的事情和上面这ŒD‰|±‡¾~–是一æ ïLš„
http://msdn.microsoft.com/en-us/library/windows/desktop/ms683560%28v=vs.85%29.aspx

6. 最后再贴一下x86的cmpxchg指定

Opcode CMPXCHG


CPU: I486+
Type of Instruction: User

Instruction: CMPXCHG dest, src

Description: Compares the accumulator with dest. If equal the "dest"
is loaded with "src", otherwise the accumulator is loaded
with "dest".

Flags Affected: AF, CF, OF, PF, SF, ZF

CPU mode: RM,PM,VM,SMM
+++++++++++++++++++++++
Clocks:
CMPXCHG reg, reg 6
CMPXCHG mem, reg 7 (10 if compartion fails)


 


]]>
Apache Mina 中文文档¾˜»è¯‘ - ç‰ÒŽ€?/title><link>http://www.aygfsteel.com/mstar/archive/2013/04/23/398309.html</link><dc:creator>黑灵</dc:creator><author>黑灵</author><pubDate>Tue, 23 Apr 2013 14:02:00 GMT</pubDate><guid>http://www.aygfsteel.com/mstar/archive/2013/04/23/398309.html</guid><wfw:comment>http://www.aygfsteel.com/mstar/comments/398309.html</wfw:comment><comments>http://www.aygfsteel.com/mstar/archive/2013/04/23/398309.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/mstar/comments/commentRss/398309.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/mstar/services/trackbacks/398309.html</trackback:ping><description><![CDATA[ç‰ÒŽ€?br />http://mina.apache.org/mina-project/features.html<br /><br />MINA是一个简单的却有功能丰富的网¾lœåº”用程序框æžÓž¼Œ 它提供如下特性:<br /><ul><li>为各¿Uä¼ è¾“类型提供一套统一的API</li></ul><blockquote><ul><li>通过Java NIO实现 TCP/IP & UPD/IP通信</li></ul></blockquote><blockquote><ul><li>通过RXTX实现串口通信åQˆRS232åQ?/li></ul></blockquote><blockquote><ul><li>VM内部½Ž¡é“通信</li></ul></blockquote><blockquote><ul><li>你可以实现自å·Þqš„通信方式</li></ul></blockquote><ul><li>通过Filter接口实现扩展点;¾cÖM¼¼ä¸ŽServletçš„Filter</li></ul><ul><li>低çñ”和高¾U§çš„API</li></ul><blockquote><ul><li>低çñ”åQšä‹É用ByteBuffer</li></ul></blockquote><blockquote><ul><li>高çñ”åQšç”¨æˆ¯‚‡ªå®šä¹‰çš„æ¶ˆæ¯å¯¹è±¡å’Œ¾~–码</li></ul></blockquote><ul><li>可以自由定制的线½E‹æ¨¡åž?/li></ul><blockquote><ul><li>单线½E?/li></ul></blockquote><blockquote><ul><li>一个线½E‹æ± </li></ul></blockquote><blockquote><ul><li>多个¾U¿ç¨‹æ± ï¼ˆä¾‹å¦‚ <a target="_blank" title="SEDA" >SEDA</a>åQ?/li></ul></blockquote><ul><li>利用Java5çš„SSLEngine实现的开½Ž±å³ç”¨çš„SSL,TLS, StartTLS功能</li></ul><ul><li>˜q‡è²ä¿æŠ¤ å’?带宽限制</li></ul><ul><li>通过Mock对象可以˜q›è¡Œå•体‹¹‹è¯•</li></ul><ul><li>通过JMX½Ž¡ç†æœåŠ¡å™?/li></ul><ul><li>通过StreamIoHandler支持åŸÞZºŽ‹¹çš„I/O</li></ul><ul><li>可以整合˜q›PicoContainerå’ŒSpring½{‰å¸¸ç”¨å®¹å™?/li></ul><ul><li>很容易从Netty˜qç§»˜q‡æ¥ã€?/li></ul><br /><img src ="http://www.aygfsteel.com/mstar/aggbug/398309.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/mstar/" target="_blank">黑灵</a> 2013-04-23 22:02 <a href="http://www.aygfsteel.com/mstar/archive/2013/04/23/398309.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Apache Mina 中文文档¾˜»è¯‘ - 概述http://www.aygfsteel.com/mstar/archive/2013/04/22/398241.html黑灵黑灵Mon, 22 Apr 2013 15:13:00 GMThttp://www.aygfsteel.com/mstar/archive/2013/04/22/398241.htmlhttp://www.aygfsteel.com/mstar/comments/398241.htmlhttp://www.aygfsteel.com/mstar/archive/2013/04/22/398241.html#Feedback0http://www.aygfsteel.com/mstar/comments/commentRss/398241.htmlhttp://www.aygfsteel.com/mstar/services/trackbacks/398241.html原文链接åQšhttp://mina.apache.org/mina-project/index.html

Apache MINA 是一个网¾lœåº”用框æžÓž¼Œ 它可以帮助你½Ž€å•容易的开发高性能åQŒé«˜å¯æ‰©å±•性的¾|‘络应用½E‹åºã€‚Apache MINA底层利用Java NIO实现åQŒåœ¨TCP/IPå’ŒUPD/IP½{‰ä¼ è¾“层上提供一个抽象的åŸÞZºŽäº‹äšg驱动的异步APIã€?br />
Apache MINA一般被¿UîCØ“åQ?br />
  • 一个NIO框架或库
  • 客户端,服务器框架或åº?/li>
  • 一个网¾lœSocketåº?/li>
ž®½ç®¡å¦‚æ­¤åQŒApache MINA要提供的比上面说的多得多ã€?你可以看一下它的功能特性列表, 利用˜q™äº›ç‰ÒŽ€§ä½ å¯ä»¥å¿«é€Ÿå¼€å‘网¾lœåº”用程序, 你还可以看一下äh们是怎么说MINAçš„ã€?请下载MINA的包åQŒå°è¯•一下快速开始指南, ‹¹è§ˆä¸€ä¸‹FAQ或者加入我们的½C‘ÖŒºã€?br />
Notice: Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at . http://www.apache.org/licenses/LICENSE-2.0 . Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.



黑灵 2013-04-22 23:13 发表评论
]]>
Properties.storeToXMLæ–ÒŽ³•抛出½IºæŒ‡é’ˆå“¦!http://www.aygfsteel.com/mstar/archive/2013/04/19/398100.html黑灵黑灵Fri, 19 Apr 2013 08:42:00 GMThttp://www.aygfsteel.com/mstar/archive/2013/04/19/398100.htmlhttp://www.aygfsteel.com/mstar/comments/398100.htmlhttp://www.aygfsteel.com/mstar/archive/2013/04/19/398100.html#Feedback0http://www.aygfsteel.com/mstar/comments/commentRss/398100.htmlhttp://www.aygfsteel.com/mstar/services/trackbacks/398100.html
¾cÖM¼¼ä¸‹é¢˜q™æ®µä»£ç :
    @Test(expected = IOException.class)
    
public void testPropertiesStoreToXml() throws IOException {
        Properties props 
= new Properties();
        props.put(
"key1", true);
        ByteArrayOutputStream baos 
= new ByteArrayOutputStream();
        props.storeToXML(baos,
null);
        String xml 
= new String(baos.toByteArray());
        Assert.fail(
"should not go to here");
    }

在生成XML的时候会抛出IOException. 坯D‡´˜q™ä¸ªIOException的是做XMLTransform的时候出çŽîCº†NullPointerException

感觉很奇æ€? 调试˜q›Properties的代码看了一ä¸?

    public String getProperty(String key) {
    Object oval 
= super.get(key);
    String sval 
= (oval instanceof String) ? (String)oval : null;
    
return ((sval == null) && (defaults != null)) ? defaults.getProperty(key) : sval;
    }

原来Properties˜q™è´§, 不是String的属性一码色的返回NULLå•?

¾l“果在XMLTransform的时å€? 直接对这个NULL˜q›è¡Œæ–ÒŽ³•调用.

后来看了一下Properties文档, Properties¾l§æ‰¿è‡³Hashtable, 所以有putå’ŒputAll之类的方æ³? 但是不徏议ä‹Éç”?
因䨓˜q™äº›æ–ÒŽ³•不限定String¾cÕdž‹. 推荐使用setPropertyæ–ÒŽ³•, ˜q™ä¸ªæ–ÒŽ³•çš„å€ég¸€å®šæ˜¯String.

Because Properties inherits from Hashtable, the put and putAll methods can be applied to a Properties object. Their use is strongly discouraged as they allow the caller to insert entries whose keys or values are not Strings. The setProperty method should be used instead. If the store or save method is called on a "compromised" Properties object that contains a non-String key or value, the call will fail. Similarly, the call to the propertyNames or list method will fail if it is called on a "compromised" Properties object that contains a non-String key.

OK,我承认是我不好好看文档就用了. 但是我脚的如果你把非Stringçš„å€ÆD°ƒç”¨ä¸€ä¸‹toString再ä‹É用不是更好吗?



黑灵 2013-04-19 16:42 发表评论
]]>
关于spring-mvcçš„InitBinder注解的参æ•?/title><link>http://www.aygfsteel.com/mstar/archive/2013/04/17/397945.html</link><dc:creator>黑灵</dc:creator><author>黑灵</author><pubDate>Tue, 16 Apr 2013 16:42:00 GMT</pubDate><guid>http://www.aygfsteel.com/mstar/archive/2013/04/17/397945.html</guid><wfw:comment>http://www.aygfsteel.com/mstar/comments/397945.html</wfw:comment><comments>http://www.aygfsteel.com/mstar/archive/2013/04/17/397945.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.aygfsteel.com/mstar/comments/commentRss/397945.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/mstar/services/trackbacks/397945.html</trackback:ping><description><![CDATA[通过Spring-mvcçš„@InitBinder注释的方法可以对WebDataBinder做一些初始化操作ã€?br />比如讄¡½®Validatorã€?<br />我一直在惌™ƒ½ä¸èƒ½ä¸ºæ¯ä¸ªRequest或者每个Actionæ–ÒŽ³•单独讄¡½®Validatorã€?br />也就是说Controller里有多个被@InitBinder标注的方法ã€?在不同的Action时被分别调用ã€?br /><br />我注意到了@InitBinderçš„value参数åQ?br /><br />api docs里是˜q™æ ·æè¿°çš„:<br />The names of command/form attributes and/or request parameters that this init-binder method is supposed to apply to. <p>Default is to apply to all command/form attributes and all request parameters processed by the annotated handler class. Specifying model attribute names or request parameter names here restricts the init-binder method to those specific attributes/parameters, with different init-binder methods typically applying to different groups of attributes or parameters. <br /></p><p>是乎是可以针对不同的Form对象或命令调用不同的InitBinderæ–ÒŽ³•ã€?/p><p>于是我写了下面的Controller试了一ä¸?/p><p></p><div style="background-color:#eeeeee;font-size:13px;BORDER:1px solid #CCCCCC;PADDING-RIGHT: 5px;PADDING-BOTTOM: 4px;PADDING-left: 4px;PADDING-TOP: 4px;WIDTH: 98%;word-break:break-all"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #000000; ">@Controller<br /></span><span style="color: #0000FF; ">public</span><span style="color: #000000; "> </span><span style="color: #0000FF; ">class</span><span style="color: #000000; "> HomeController {<br />    <br />    </span><span style="color: #0000FF; ">private</span><span style="color: #000000; "> </span><span style="color: #0000FF; ">static</span><span style="color: #000000; "> </span><span style="color: #0000FF; ">final</span><span style="color: #000000; "> Logger logger </span><span style="color: #000000; ">=</span><span style="color: #000000; "> LoggerFactory.getLogger(HomeController.</span><span style="color: #0000FF; ">class</span><span style="color: #000000; ">);<br />    <br />    @InitBinder(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">action1</span><span style="color: #000000; ">"</span><span style="color: #000000; ">)<br />    </span><span style="color: #0000FF; ">public</span><span style="color: #000000; "> </span><span style="color: #0000FF; ">void</span><span style="color: #000000; "> initBinder1(WebDataBinder binder){<br />        logger.info(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">initBinder1</span><span style="color: #000000; ">"</span><span style="color: #000000; ">);<br />    }<br />    <br />    @InitBinder(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">action2</span><span style="color: #000000; ">"</span><span style="color: #000000; ">)<br />    </span><span style="color: #0000FF; ">public</span><span style="color: #000000; "> </span><span style="color: #0000FF; ">void</span><span style="color: #000000; "> initBinder2(WebDataBinder binder){<br />        logger.info(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">initBinder2</span><span style="color: #000000; ">"</span><span style="color: #000000; ">);<br />    }<br />    <br />    </span><span style="color: #008000; ">/**</span><span style="color: #008000; "><br />     * Simply selects the home view to render by returning its name.<br />     </span><span style="color: #008000; ">*/</span><span style="color: #000000; "><br />    @RequestMapping(value </span><span style="color: #000000; ">=</span><span style="color: #000000; "> </span><span style="color: #000000; ">"</span><span style="color: #000000; ">/</span><span style="color: #000000; ">"</span><span style="color: #000000; ">, method </span><span style="color: #000000; ">=</span><span style="color: #000000; "> RequestMethod.GET)<br />    </span><span style="color: #0000FF; ">public</span><span style="color: #000000; "> String home(Model model) {        <br />        <br />        Date date </span><span style="color: #000000; ">=</span><span style="color: #000000; "> </span><span style="color: #0000FF; ">new</span><span style="color: #000000; "> Date();<br />        DateFormat dateFormat </span><span style="color: #000000; ">=</span><span style="color: #000000; "> DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG);<br />        <br />        String formattedDate </span><span style="color: #000000; ">=</span><span style="color: #000000; "> dateFormat.format(date);<br />        <br />        model.addAttribute(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">serverTime</span><span style="color: #000000; ">"</span><span style="color: #000000; ">, formattedDate );<br />        <br />        </span><span style="color: #0000FF; ">return</span><span style="color: #000000; "> </span><span style="color: #000000; ">"</span><span style="color: #000000; ">home</span><span style="color: #000000; ">"</span><span style="color: #000000; ">;<br />    }<br />    <br />    </span><span style="color: #008000; ">/**</span><span style="color: #008000; "><br />     * Simply selects the home view to render by returning its name.<br />     </span><span style="color: #008000; ">*/</span><span style="color: #000000; "><br />    @RequestMapping(value </span><span style="color: #000000; ">=</span><span style="color: #000000; "> </span><span style="color: #000000; ">"</span><span style="color: #000000; ">/doit</span><span style="color: #000000; ">"</span><span style="color: #000000; ">, method </span><span style="color: #000000; ">=</span><span style="color: #000000; "> RequestMethod.POST, params</span><span style="color: #000000; ">=</span><span style="color: #000000; ">"</span><span style="color: #000000; ">action1</span><span style="color: #000000; ">"</span><span style="color: #000000; ">)<br />    </span><span style="color: #0000FF; ">public</span><span style="color: #000000; "> String doit1(@RequestParam(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">value1</span><span style="color: #000000; ">"</span><span style="color: #000000; ">) </span><span style="color: #0000FF; ">int</span><span style="color: #000000; "> value1,<br />            @RequestParam(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">action1</span><span style="color: #000000; ">"</span><span style="color: #000000; ">) String action, Model model) {        <br />        logger.info(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">value1={}</span><span style="color: #000000; ">"</span><span style="color: #000000; ">,value1);<br />        <br />        Date date </span><span style="color: #000000; ">=</span><span style="color: #000000; "> </span><span style="color: #0000FF; ">new</span><span style="color: #000000; "> Date();<br />        DateFormat dateFormat </span><span style="color: #000000; ">=</span><span style="color: #000000; "> DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG);<br />        <br />        String formattedDate </span><span style="color: #000000; ">=</span><span style="color: #000000; "> dateFormat.format(date);<br />        <br />        model.addAttribute(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">serverTime</span><span style="color: #000000; ">"</span><span style="color: #000000; ">, formattedDate );<br />        <br />        </span><span style="color: #0000FF; ">return</span><span style="color: #000000; "> </span><span style="color: #000000; ">"</span><span style="color: #000000; ">home</span><span style="color: #000000; ">"</span><span style="color: #000000; ">;<br />    }<br />    <br />    </span><span style="color: #008000; ">/**</span><span style="color: #008000; "><br />     * Simply selects the home view to render by returning its name.<br />     </span><span style="color: #008000; ">*/</span><span style="color: #000000; "><br />    @RequestMapping(value </span><span style="color: #000000; ">=</span><span style="color: #000000; "> </span><span style="color: #000000; ">"</span><span style="color: #000000; ">/doit</span><span style="color: #000000; ">"</span><span style="color: #000000; ">, method </span><span style="color: #000000; ">=</span><span style="color: #000000; "> RequestMethod.POST, params</span><span style="color: #000000; ">=</span><span style="color: #000000; ">"</span><span style="color: #000000; ">action2</span><span style="color: #000000; ">"</span><span style="color: #000000; ">)<br />    </span><span style="color: #0000FF; ">public</span><span style="color: #000000; "> String doit2(@RequestParam(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">value1</span><span style="color: #000000; ">"</span><span style="color: #000000; ">) </span><span style="color: #0000FF; ">int</span><span style="color: #000000; "> value1,<br />            @RequestParam(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">action2</span><span style="color: #000000; ">"</span><span style="color: #000000; ">) String action, Model model) {        <br />        logger.info(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">value1={}</span><span style="color: #000000; ">"</span><span style="color: #000000; ">,value1);<br />        <br />        Date date </span><span style="color: #000000; ">=</span><span style="color: #000000; "> </span><span style="color: #0000FF; ">new</span><span style="color: #000000; "> Date();<br />        DateFormat dateFormat </span><span style="color: #000000; ">=</span><span style="color: #000000; "> DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG);<br />        <br />        String formattedDate </span><span style="color: #000000; ">=</span><span style="color: #000000; "> dateFormat.format(date);<br />        <br />        model.addAttribute(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">serverTime</span><span style="color: #000000; ">"</span><span style="color: #000000; ">, formattedDate );<br />        <br />        </span><span style="color: #0000FF; ">return</span><span style="color: #000000; "> </span><span style="color: #000000; ">"</span><span style="color: #000000; ">home</span><span style="color: #000000; ">"</span><span style="color: #000000; ">;<br />    }<br />}<br /></span></div><p>画面上的Form是这æ ïLš„</p><p><br /></p><p></p><div style="background-color:#eeeeee;font-size:13px;BORDER:1px solid #CCCCCC;PADDING-RIGHT: 5px;PADDING-BOTTOM: 4px;PADDING-left: 4px;PADDING-TOP: 4px;WIDTH: 98%;word-break:break-all"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #0000FF; "><</span><span style="color: #800000; ">form </span><span style="color: #FF0000; ">action</span><span style="color: #0000FF; ">="doit"</span><span style="color: #FF0000; "> method</span><span style="color: #0000FF; ">="post"</span><span style="color: #FF0000; "> enctype</span><span style="color: #0000FF; ">="application/x-www-form-urlencoded"</span><span style="color: #0000FF; ">></span><span style="color: #000000; "><br />    </span><span style="color: #0000FF; "><</span><span style="color: #800000; ">input </span><span style="color: #FF0000; ">type</span><span style="color: #0000FF; ">="text"</span><span style="color: #FF0000; "> name</span><span style="color: #0000FF; ">="value1"</span><span style="color: #FF0000; "> value</span><span style="color: #0000FF; ">="100"</span><span style="color: #0000FF; ">/></span><span style="color: #000000; "><br />    </span><span style="color: #0000FF; "><</span><span style="color: #800000; ">input </span><span style="color: #FF0000; ">type</span><span style="color: #0000FF; ">="submit"</span><span style="color: #FF0000; "> name</span><span style="color: #0000FF; ">="action1"</span><span style="color: #FF0000; "> value</span><span style="color: #0000FF; ">="Action1"</span><span style="color: #0000FF; ">/></span><span style="color: #000000; "><br />    </span><span style="color: #0000FF; "><</span><span style="color: #800000; ">input </span><span style="color: #FF0000; ">type</span><span style="color: #0000FF; ">="submit"</span><span style="color: #FF0000; "> name</span><span style="color: #0000FF; ">="action2"</span><span style="color: #FF0000; "> value</span><span style="color: #0000FF; ">="Action2"</span><span style="color: #0000FF; ">/></span><span style="color: #000000; "><br /></span><span style="color: #0000FF; "></</span><span style="color: #800000; ">form</span><span style="color: #0000FF; ">></span></div><br /><p>我的意愿是如果画面上åQŒç‚¹å‡»action1按钮择调用initBinder1æ–ÒŽ³•ã€?如果点击action2按钮则调用initBinder2æ–ÒŽ³•ã€?/p><p>实际上也¼‹®å®žæ˜¯è¿™æ ïLš„ã€?<br /></p><p>当点击action1æ—Óž¼Œ<span style="color: #000000; ">logger.info(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">initBinder1</span><span style="color: #000000; ">"</span><span style="color: #000000; ">); 会执è¡?/span></p><p>当点击action2是,<span style="color: #000000; ">logger.info(</span><span style="color: #000000; ">"</span><span style="color: #000000; ">initBinder2</span><span style="color: #000000; ">"</span><span style="color: #000000; ">); 会执è¡?/span></p><p>是乎是可以实现“每个Actionæ–ÒŽ³•单独讄¡½®Validator”这个目的ã€?/p><p>但是其实òq¶ä¸æ˜¯è¿™æ ïLš„ã€?/p><p>我调式进åŽÖMº†InitBinder相关的源代码InitBinderDataBinderFactoryåQ?¾l“果发现它只是在对action˜q™ä¸ªå‚æ•°¾l‘定的时候调用了上面˜q™ä¸ªæ–ÒŽ³•åQ?对value1¾l‘定的时候那个方法都没有调用。而我们常常要解决的是对同一个参数对于不同的action应用不同的Validatorã€?<br /></p><p>所以目前还是没有好的方法能直接解决˜q™ä¸ªé—®é¢˜åQ?/p><p>也许我们可以自己实现一个DataBinderFactory来解册™¿™ä¸ªé—®é¢˜ã€?/p><p><br /></p><img src ="http://www.aygfsteel.com/mstar/aggbug/397945.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/mstar/" target="_blank">黑灵</a> 2013-04-17 00:42 <a href="http://www.aygfsteel.com/mstar/archive/2013/04/17/397945.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>KMP½Ž—法里的next函数是怎么得到的?http://www.aygfsteel.com/mstar/archive/2013/04/14/397824.html黑灵黑灵Sun, 14 Apr 2013 15:24:00 GMThttp://www.aygfsteel.com/mstar/archive/2013/04/14/397824.htmlhttp://www.aygfsteel.com/mstar/comments/397824.htmlhttp://www.aygfsteel.com/mstar/archive/2013/04/14/397824.html#Feedback0http://www.aygfsteel.com/mstar/comments/commentRss/397824.htmlhttp://www.aygfsteel.com/mstar/services/trackbacks/397824.html也就是这ä¸?pâ‘?pâ‘?pâ‘¶â€?.p(k-1åQ‰â€?= ' p(j-k+1åQ‰p(j-k+2åQ‰â€¦â€¦p(j-1åQ‰â€™ã€?ä¸ÞZ»€ä¹ˆæ‰¾åˆ°è¿™ä¸ªk以后用k的元素比较字½W¦ä¸²ä¸­iž®Þp¡Œäº†ã€?br />
现在扑ֈ°ä¸€ä¸ªæœ€æŽ¥è¿‘明白的就是百度百¿U‘上çš?br />
假设
ä¸ÖM¸²åQšs: ‘sâ‘?sâ‘?sâ‘?……s(nåQ‰â€?;
模式ä¸?åQšp: ‘pâ‘?pâ‘?pâ‘¶â€?.p(måQ‰â€?br />把课本上的这一ŒD늜‹å®ŒåŽåQŒç‘ô¾l?br />现在我们假设 ä¸ÖM¸²½W¬i个字½W¦ä¸Žæ¨¡å¼ä¸²çš„½W¬j(j<=måQ‰ä¸ªå­—符‘失配’后åQŒä¸»ä¸²ç¬¬i个字½W¦ä¸Žæ¨¡å¼ä¸²çš„½W¬k(k<jåQ‰ä¸ªå­—符¾l§ç®‹æ¯”较
此时åQŒs(iåQ‰â‰ p(jåQ‰ï¼Œæœ?br />ä¸ÖM¸²åQšs⑴…â€?s(i-j+1åQ‰â€¦â€?s(i-1åQ?s(i) ………â€?
|| åQˆç›¸é…ï¼‰ || ≠(失配åQ?br />匚w…ä¸ÔŒ¼špâ‘?...........p(j-1åQ?p(j)
由此åQŒæˆ‘们得到关¾pÕd¼åQ?br />‘pâ‘?pâ‘?pâ‘¶â€?.p(j-1åQ‰â€?= â€?s(i-j+1åQ‰â€¦â€¦s(i-1åQ‰â€?br />ç”׃ºŽs(iåQ‰â‰ p(jåQ‰ï¼ŒæŽ¥ä¸‹æ¥s(iåQ‰å°†ä¸Žp(kåQ‰ç‘ô¾l­æ¯”较,则模式串中的前(k-1åQ‰ä¸ªå­—符的子串必™åÀL»¡­‘³ä¸‹åˆ—å…³¾pÕd¼åQŒåƈ且不可能存在 kâ€?gt;k 满èƒö下列关系式:åQˆk<j),
‘pâ‘?pâ‘?pâ‘¶â€?.p(k-1åQ‰â€?= â€?s(i-k+1åQ‰s(i-k+2åQ‰â€¦â€¦s(i-1åQ‰â€?br />卻I¼š
ä¸ÖM¸²åQšs⑴……s(i-k +1åQ?s(i-k +2åQ?……s(i-1åQ?s(i) ………â€?
|| åQˆç›¸é…ï¼‰ || ||åQˆæœ‰å¾…比较)
匚w…ä¸ÔŒ¼špâ‘?pâ‘?…â€?.... p(k-1åQ?p(k)
现在我们把前面æ€È»“的关¾pȝ»¼åˆä¸€ä¸?br />有:
s⑴…s(i-j +1åQ‰â€?s(i-k +1åQ?s(i-k +2åQ?…â€?s(i-1åQ?s(i) …â€?br />|| åQˆç›¸é…ï¼‰ || || || ≠(失配åQ?br />pâ‘?……p(j-k+1åQ?p(j-k+2åQ?â€?..... p(j-1åQ?p(j)
|| åQˆç›¸é…ï¼‰ || ||åQˆæœ‰å¾…比较)
pâ‘?pâ‘?…â€?..... p(k-1åQ?p(k)
ç”׃¸ŠåQŒæˆ‘们得到关¾p»ï¼š
'pâ‘?pâ‘?pâ‘¶â€?.p(k-1åQ‰â€?= ' p(j-k+1åQ‰p(j-k+2åQ‰â€¦â€¦p(j-1åQ‰â€?br />
不知道是从哪个课本上抄来的ã€?其实˜q˜æ˜¯ä¸å¤ªæ˜Žç™½æœ€åŽä¸€æ­¥ã€?br />

黑灵 2013-04-14 23:24 发表评论
]]>
½Ž€å•的监视某个端口的连接数的Linux命ä×ohttp://www.aygfsteel.com/mstar/archive/2012/10/30/linux_shell_watch_connection.html黑灵黑灵Tue, 30 Oct 2012 01:38:00 GMThttp://www.aygfsteel.com/mstar/archive/2012/10/30/linux_shell_watch_connection.htmlhttp://www.aygfsteel.com/mstar/comments/390432.htmlhttp://www.aygfsteel.com/mstar/archive/2012/10/30/linux_shell_watch_connection.html#Feedback0http://www.aygfsteel.com/mstar/comments/commentRss/390432.htmlhttp://www.aygfsteel.com/mstar/services/trackbacks/390432.html
#!/bin/sh
netstat 
-anp | grep :$1 | awk '{print $5}' | awk -F: '{print $1}' | sort | uniq -c

然后执行命ä×o:

watch -n 1 count_conn 8080

最后的参数ž®±æ˜¯ä½ è¦ç›‘视的端å?



黑灵 2012-10-30 09:38 发表评论
]]>
Ö÷Õ¾Ö©Öë³ØÄ£°å£º °×ɽÊÐ| Âú³ÇÏØ| ½­Î÷Ê¡| ÜìÄÏÏØ| ÎäÒåÏØ| ³à·åÊÐ| ʯÇþÏØ| ²ýÀÖÏØ| ÀóÆÖÏØ| ÑÀ¿ËʯÊÐ| ÓÀ´¨ÊÐ| ̨±±ÏØ| ÐÇ×ÓÏØ| н¨ÏØ| ½­ÁêÏØ| °ÙÉ«ÊÐ| ÈýÌ¨ÏØ| ³±°²ÏØ| µ¤°ÍÏØ| Õý°²ÏØ| ÑôÐÂÏØ| ÈéɽÊÐ| ºÓÄÏÊ¡| ³¤ÐËÏØ| ÑîÆÖÇø| Âú³ÇÏØ| ÔÀÑôÊÐ| ¾äÈÝÊÐ| Âé½­ÏØ| ¶«ÄþÏØ| °²ÔÀÏØ| Ë³Æ½ÏØ| äüÄÏÏØ| ƽ¹ÈÇø| »³Ô¶ÏØ| ¸¡ÁºÏØ| ÃÉÉ½ÏØ| ƽÄÏÏØ| µÂ¸ñÏØ| Çà´¨ÏØ| µÂÑôÊÐ|