2008年11月27日星期四

Collection List Set Map 区别记忆

这些都代表了Java中的集合,这里主要从其元素是否有序,是否可重复来进行区别记忆,以便恰当地使用,当然还存在同步方面的差异,见上一篇相关文章。

有序否
允许元素重复否
Collection
List
Set
AbstractSet
HashSet
TreeSet
是(用二叉树排序)
Map
AbstractMap
使用key-value来映射和存储数据,Key必须惟一,value可以重复
HashMap
TreeMap
是(用二叉树排序)
List接口对Collection进行了简单的扩充,它的具体实现类常用的有ArrayList和LinkedList。你可以将任何东西放 到一个List容器中,并在需要时从中取出。ArrayList从其命名中可以看出它是一种类似数组的形式进行存储,因此它的随机访问速度极快,而 LinkedList的内部实现是链表,它适合于在链表中间需要频繁进行插入和删除操作。在具体应用时可以根据需要自由选择。前面说的Iterator只 能对容器进行向前遍历,而ListIterator则继承了Iterator的思想,并提供了对List进行双向遍历的方法。

Set接口也是Collection的一种扩展,而与List不同的时,在Set中的对象元素不能重复,也就是说你不能把同样的东西两次放入同一个Set 容器中。它的常用具体实现有HashSet和TreeSet类。HashSet能快速定位一个元素,但是你放到HashSet中的对象需要实现 hashCode()方法,它使用了前面说过的哈希码的算法。而TreeSet则将放入其中的元素按序存放,这就要求你放入其中的对象是可排序的,这就用 到了集合框架提供的另外两个实用类Comparable和Comparator。一个类是可排序的,它就应该实现Comparable接口。有时多个类具 有相同的排序算法,那就不需要在每分别重复定义相同的排序算法,只要实现Comparator接口即可。集合框架中还有两个很实用的公用 类:Collections和Arrays。Collections提供了对一个Collection容器进行诸如排序、复制、查找和填充等一些非常有用 的方法,Arrays则是对一个数组进行类似的操作。


Map是一种把键对象和值对象进行关联的容器,而一个值对象又可以是一个Map,依次类推,这样就可形成一个多级映射。对于键对象来说,像Set一样,一 个Map容器中的键对象不允许重复,这是为了保持查找结果的一致性;如果有两个键对象一样,那你想得到那个键对象所对应的值对象时就有问题了,可能你得到 的并不是你想的那个值对象,结果会造成混乱,所以键的唯一性很重要,也是符合集合的性质的。当然在使用过程中,某个键所对应的值对象可能会发生变化,这时 会按照最后一次修改的值对象与键对应。对于值对象则没有唯一性的要求。你可以将任意多个键都映射到一个值对象上,这不会发生任何问题(不过对你的使用却可 能会造成不便,你不知道你得到的到底是那一个键所对应的值对象)。Map有两种比较常用的实现:HashMap和TreeMap。HashMap也用到了 哈希码的算法,以便快速查找一个键,TreeMap则是对键按序存放,因此它便有一些扩展的方法,比如firstKey(),lastKey()等,你还 可以从TreeMap中指定一个范围以取得其子Map。键和值的关联很简单,用pub(Object key,Object value)方法即可将一个键与一个值对象相关联。用get(Object key)可得到与此key对象所对应的值对象。


======================================================

 ArrayList: 由数组实现的List。它允许对元素进行快速随机访问,但是向List中间插入与移除元素的速度很慢。ListIterator只应该用来由后向前遍历ArrayList,而不是用来插入和删除元素,因为这比LinkedList开销要大很多。

  LinkedList: 对顺序访问进行了优化,向List中间插入与删除得开销不大,随机访问则相对较慢(可用ArrayList代替)。它具有方法addFirst()、 addLast()、getFirst()、getLast()、removeFirst()、removeLast(),这些方法(没有在任何接口或基 类中定义过)使得LinkedList可以当作堆栈、队列和双向队列使用。

  3.Set的功能方法

  Set(interface): 存入Set的每个元素必须是唯一的,因为Set不保存重复元素。加入Set的Object必须定义equals()方法以确保对象的唯一性。Set与Collection有完全一样的接口。Set接口不保证维护元素的次序。

  HashSet: 为快速查找而设计的Set。存入HashSet的对象必须定义hashCode()。

  TreeSet: 保持次序的Set,底层为树结构。使用它可以从Set中提取有序的序列。

  LinkedHashSet: 具有HashSet的查询速度,且内部使用链表维护元素的顺序(插入的次序)。于是在使用迭代器遍历Set时,结果会按元素插入的次序显示。

  HashSet采用散列函数对元素进行排序,这是专门为快速查询而设计的;TreeSet采用红黑树的数据结构进行排序元 素;LinkedHashSet内部使用散列以加快查询速度,同时使用链表维护元素的次序,使得看起来元素是以插入的顺序保存的。需要注意的是,生成自己 的类时,Set需要维护元素的存储顺序,因此要实现Comparable接口并定义compareTo()方法。

===================================================

容器类可以大大提高编程效率和编程能力,在Java2中,所有的容器都由SUN公司的Joshua Bloch进行了重新设计,丰富了容器类库的功能。 

  Java2容器类类库的用途是"保存对象",它分为两类: 

  Collection----一组独立的元素,通常这些元素都服从某种规则。List必须保持元素特定的顺序,而Set不能有重复元素。 

  Map----一组成对的"键值对"对象,即其元素是成对的对象,最典型的应用就是数据字典,并且还有其它广泛的应用。另外,Map可以返回 其所有键组成的Set和其所有值组成的Collection,或其键值对组成的Set,并且还可以像数组一样扩展多维Map,只要让Map中键值对的每个 "值"是一个Map即可。 

  1.迭代器 

  迭代器是一种设计模式,它是一个对象,它可以遍历并选择序列中的对象,而开发人员不需要了解该序列的底层结构。迭代器通常被称为"轻量级"对象,因为创建它的代价小。 

  Java中的Iterator功能比较简单,并且只能单向移动: 

  (1) 使用方法iterator()要求容器返回一个Iterator。第一次调用Iterator的next()方法时,它返回序列的第一个元素。 

  (2) 使用next()获得序列中的下一个元素。 

  (3) 使用hasNext()检查序列中是否还有元素。 

  (4) 使用remove()将迭代器新返回的元素删除。 

  Iterator是Java迭代器最简单的实现,为List设计的ListIterator具有更多的功能,它可以从两个方向遍历List,也可以从List中插入和删除元素。 

  2.List的功能方法 

  List(interface): 次序是List最重要的特点;它确保维护元素特定的顺序。List为Collection添加了许多方 法,使得能够向List中间插入与移除元素(只推荐LinkedList使用)。一个List可以生成ListIterator,使用它可以从两个方向遍 历List,也可以从List中间插入和删除元素。 


===================================================

Collection
├List
│├LinkedList
│  ArrayList
│└Vector
│ └Stack
└Set
Map
├Hashtable
├HashMap
└WeakHashMap

Collection接口
   Collection是最基本的集合接口,一个Collection代表一组Object,即Collection的元素(Elements)。一些 Collection允许相同的元素而另一些不行。一些能排序而另一些不行。Java SDK不提供直接继承自Collection的类,Java SDK提供的类都是继承自Collection的"子接口"如List和Set。
  所有实现Collection接口的类都必须提供两个标准的 构造函数:无参数的构造函数用于创建一个空的Collection,有一个 Collection参数的构造函数用于创建一个新的Collection,这个新的Collection与传入的Collection有相同的元素。后 一个构造函数允许用户复制一个Collection。
  如何遍历Collection中的每一个元素?不论Collection的实际类型如何,它都支持一个iterator()的方法,该方法返回一个迭代子,使用该迭代子即可逐一访问Collection中每一个元素。典型的用法如下:
    Iterator it = collection.iterator(); // 获得一个迭代子
    while(it.hasNext()) {
      Object obj = it.next(); // 得到下一个元素
    }
  由Collection接口派生的两个接口是List和Set。

List接口
  List是有序的Collection,使用此接口能够精确的控制每个元素插入的位置。用户能够使用索引(元素在List中的位置,类似于数组下标)来访问List中的元素,这类似于Java的数组。
和下面要提到的Set不同,List允许有相同的元素。
   除了具有Collection接口必备的iterator()方法外,List还提供一个listIterator()方法,返回一个 ListIterator接口,和标准的Iterator接口相比,ListIterator多了一些add()之类的方法,允许添加,删除,设定元素, 还能向前或向后遍历。
  实现List接口的常用类有LinkedList,ArrayList,Vector和Stack。

LinkedList类
   LinkedList实现了List接口,允许null元素。此外LinkedList提供额外的get,remove,insert方法在 LinkedList的首部或尾部。这些操作使LinkedList可被用作堆栈(stack),队列(queue)或双向队列(deque)。
  注意LinkedList没有同步方法。如果多个线程同时访问一个List,则必须自己实现访问同步。一种解决方法是在创建List时构造一个同步的List:
    List list = Collections.synchronizedList(new LinkedList(...));

ArrayList类
  ArrayList实现了可变大小的数组。它允许所有元素,包括null。ArrayList没有同步。
size,isEmpty,get,set方法运行时间为常数。但是add方法开销为分摊的常数,添加n个元素需要O(n)的时间。其他的方法运行时间为线性。
   每个ArrayList实例都有一个容量(Capacity),即用于存储元素的数组的大小。这个容量可随着不断添加新元素而自动增加,但是增长算法并 没有定义。当需要插入大量元素时,在插入前可以调用ensureCapacity方法来增加ArrayList的容量以提高插入效率。
  和LinkedList一样,ArrayList也是非同步的(unsynchronized)。

Vector类
   Vector非常类似ArrayList,但是Vector是同步的。由Vector创建的Iterator,虽然和ArrayList创建的 Iterator是同一接口,但是,因为Vector是同步的,当一个Iterator被创建而且正在被使用,另一个线程改变了Vector的状态(例 如,添加或删除了一些元素),这时调用Iterator的方法时将抛出ConcurrentModificationException,因此必须捕获该 异常。

Stack 类
  Stack继承自Vector,实现一个后进先出的堆栈。Stack提供5个额外的方法使得 Vector得以被当作堆栈使用。基本的push和pop 方法,还有peek方法得到栈顶的元素,empty方法测试堆栈是否为空,search方法检测一个元素在堆栈中的位置。Stack刚创建后是空栈。

Set接口
  Set是一种不包含重复的元素的Collection,即任意的两个元素e1和e2都有e1.equals(e2)=false,Set最多有一个null元素。
  很明显,Set的构造函数有一个约束条件,传入的Collection参数不能包含重复的元素。
  请注意:必须小心操作可变对象(Mutable Object)。如果一个Set中的可变元素改变了自身状态导致Object.equals(Object)=true将导致一些问题。

Map接口
   请注意,Map没有继承Collection接口,Map提供key到value的映射。一个Map中不能包含相同的key,每个key只能映射一个 value。Map接口提供3种集合的视图,Map的内容可以被当作一组key集合,一组value集合,或者一组key-value映射。

Hashtable类
  Hashtable继承Map接口,实现一个key-value映射的哈希表。任何非空(non-null)的对象都可作为key或者value。
  添加数据使用put(key, value),取出数据使用get(key),这两个基本操作的时间开销为常数。
Hashtable 通过initial capacity和load factor两个参数调整性能。通常缺省的load factor 0.75较好地实现了时间和空间的均衡。增大load factor可以节省空间但相应的查找时间将增大,这会影响像get和put这样的操作。
使用Hashtable的简单示例如下,将1,2,3放到Hashtable中,他们的key分别是"one","two","three":
    Hashtable numbers = new Hashtable();
    numbers.put("one", new Integer(1));
    numbers.put("two", new Integer(2));
    numbers.put("three", new Integer(3));
  要取出一个数,比如2,用相应的key:
    Integer n = (Integer)numbers.get("two");
    System.out.println("two = " + n);
   由于作为key的对象将通过计算其散列函数来确定与之对应的value的位置,因此任何作为key的对象都必须实现hashCode和equals方 法。hashCode和equals方法继承自根类Object,如果你用自定义的类当作key的话,要相当小心,按照散列函数的定义,如果两个对象相 同,即obj1.equals(obj2)=true,则它们的hashCode必须相同,但如果两个对象不同,则它们的hashCode不一定不同,如 果两个不同对象的hashCode相同,这种现象称为冲突,冲突会导致操作哈希表的时间开销增大,所以尽量定义好的hashCode()方法,能加快哈希 表的操作。
  如果相同的对象有不同的hashCode,对哈希表的操作会出现意想不到的结果(期待的get方法返回null),要避免这种问题,只需要牢记一条:要同时复写equals方法和hashCode方法,而不要只写其中一个。
  Hashtable是同步的。

HashMap类
   HashMap和Hashtable类似,不同之处在于HashMap是非同步的,并且允许null,即null value和null key。,但是将HashMap视为Collection时(values()方法可返回Collection),其迭代子操作时间开销和HashMap 的容量成比例。因此,如果迭代操作的性能相当重要的话,不要将HashMap的初始化容量设得过高,或者load factor过低。

WeakHashMap类
  WeakHashMap是一种改进的HashMap,它对key实行"弱引用",如果一个key不再被外部所引用,那么该key可以被GC回收。

总结
  如果涉及到堆栈,队列等操作,应该考虑用List,对于需要快速插入,删除元素,应该使用LinkedList,如果需要快速随机访问元素,应该使用ArrayList。
  如果程序在单线程环境中,或者访问仅仅在一个线程中进行,考虑非同步的类,其效率较高,如果多个线程可能同时操作一个类,应该使用同步的类。
  要特别注意对哈希表的操作,作为key的对象要正确复写equals和hashCode方法。
  尽量返回接口而非实际的类型,如返回List而非ArrayList,这样如果以后需要将ArrayList换成LinkedList时,客户端代码不用改变。这就是针对抽象编程。

2008年11月26日星期三

睡五分钟=六小时方法 (转)

  做软件的人熬夜是很正常的事,但经常熬夜对身体会产生很坏的影响,无意中看到这篇文章,转载过来,或许对经常熬夜的同行们会有所帮助。
睡觉的诀窍

  根据医学和我的体验、观察,一个人真正睡着觉最多只有两个钟头,其余都是浪费时间,躺在枕头上做梦,没有哪个人不做梦。至于醒来觉得自己没有做梦,那是因为他忘记了。

  通常一个人睡两个钟头就够了,为什么有人要睡七、八个钟头?那是你赖床躺在枕头上休息的习惯养成的,并非我们需要那么久的睡眠时间,尤其打坐做功夫的 人晓得,正午只要闭眼真正睡着三分钟,等于睡两个钟头,不过要对好正午的时间。夜晚则要在正子时睡着,五分钟等于六个钟头。

  就这个时间的学问又大了,同宇宙法则、地球法则、易经阴阳的道理有关系,而且你会感觉到,心脏下面硬是有一股力量降下来,与丹田(肾上)的力量融合,所谓"水火既济",豁然一下,那你睡眠够了,精神百倍。

  所以失眠或真要夜里熬夜的人,正子时的时刻,哪怕二十分钟也一定要睡,睡不着也要训练自己睡着。

  过了正子时大约十二点半以后,你不会想睡了,这很糟糕。更严重的,到了天快亮,四、五点钟,五、六点卯时的时候,你又困得想睡,这时如果一睡,一天都会昏头。

  所以想从事熬夜工作的人,正子时,即使有天大的事也要摆下来,睡它半小时,到了卯时想睡觉千万不要睡,那一天精神就够了。

  不过失眠的人都挨过十二点,在床上翻来覆去睡不着,结果快天亮睡着了,到第二天下午都昏头昏脑,因此你会感觉失眠、睡眠不足,实际上是你没有经验。


 睡眠与养生

  一、睡眠的规则

  战国时名医文挚对齐威王说:"我的养生之道把睡眠放在头等位置,人和动物只有睡眠才生长,睡眠帮助脾胃消化食物,所以,所以睡眠是养生的第一大补,人一个晚上不睡觉,其损失一百天也难以恢复。"

  晚21点到凌晨5点为有效睡眠时间。人是动物,和植物同属于生物,白天(凌晨5点到晚上21点)活动产生能量,晚上(21点到凌晨5点)开始进行细胞 分裂,把能量转化为新生的细胞,是人体细胞休养生息、推陈出新的时间,也是人随着地球旋转到背向太阳的一面。阴主静,是人睡眠的良辰,此时休息,才会有良 好的身体和精神状态。这和睡觉多的婴儿长得胖、长得快,而爱闹觉的孩子发育不良是一样的道理。

  睡觉是养生的一大功能,养就是用大量的健康细胞去取代腐败的细胞,如一夜睡不着就换不了新细胞。如果说白天消亡一百万个细胞,一晚上只补回来五十万个 细胞,这时你的身体就会出现亏空,时间长了,人就糠了,像糠萝卜似的。为什么世上有百岁老人呢?因为他们每晚都在21点钟准时睡觉。

  植物吸收阳光的能量,夜里生长,所以夜晚在农村的庄稼地里可听到拔节的声音。人类和植物同属于生物,细胞分裂的时间段大致相同,错过夜里睡觉的良辰, 细胞的新生远赶不上消亡,人就会过早的衰老或患病,人要顺其自然,就应跟着太阳走,即天醒我醒,天睡我睡。人在太阳面前小如微尘,"与太阳对着干"是愚蠢 的选择,迟早会被太阳巨大的引力催垮。这是客观真理。

  现实生活中,不少人有入睡难,睡眠质量不高的毛病。睡眠不好是一个综合性的问题,如肝火过盛,睡觉警觉;胃火过剩,睡觉不安;肝阴不足,睡觉劳累。

二、睡眠与疾病

  现代的生活习惯和生活方式给人们的身体带来了很多负面影响形成"四大病":水果病、冰箱病、电视电脑病、熬夜病。肝脏有一特点:卧则回血,坐立向外供血。

  子时(23:00―1:00),其实23点就是新的一天的开始,并不是0点开始的,这是我们犯的误识。肝胆相表里,互为一家,23点胆经开了,如若不 睡,大伤胆气,由于十一脏腑皆取决于胆也,胆气一虚,全身脏腑功能下降,代谢力、免疫力纷纷下降,人体机能大大降低,胆气支持中枢神经,胆气受伤易患各种 精神疾病,比如抑郁症、精神分裂症、强迫症、躁动症等。子时胆要更换胆汁,胆经渐旺人如不卧,胆汁更替不利,过浓而结晶成石,久之即得胆结石,如果把胆给 摘了,一摘就胆怯了,全身的免疫力下降了50%以上,所以不能摘,要用它本系统的巨大潜能把它化掉。

  丑时肝经最旺,丑时(1:00―3:00)不眠,肝无法解除掉有毒之物,产生新鲜血液,因藏血不利,面呈青色,久之易患各类肝病,现在有些人肝不太 好,特别在欧洲平均4个人就有一个大三阳或是小三阳,大都是因为违反自然规律过了子时不睡觉造成的。甲肝比较好治,乙肝就很难治。乙肝病毒携带者,是由于 晚上经常不睡觉,人太虚弱了,也就是说秩序太乱了,病毒已经到了细胞里了。也就是说乙肝的病毒已经到了细胞里面,但是现在它还没有能力造成肝炎,当人身体 处于最薄弱的时候就形成成肝炎,乙型肝炎就意味着将来40%――60%的肝硬化。聪明的人是应该了解天、地、人之间的关系,不聪明的人就是应该被淘汰的 人。


 肝主疏泄,过子时不睡,可引起肝疏泄不利,肝气郁结,可见易怒,头痛头晕,眼红,眼痛,耳鸣,耳聋,胸肋胀痛,女性月经不调,便秘,也可引起肝气升发不足,人会目倦神疲,腰膝酸软,晕眩,失眠,惊悸,精神恍惚,重则会晕倒在大街上,不省人事。

  肝有藏血、调节血液的功能,过子时不睡,会造成肝血不足,还会引起吐血、流鼻血、皮下出血、牙龈出血、眼底出血、耳出血等出血证状。

  肝开窍于目,过子时不睡,易引起肝虚,则出现视力模糊、老花、夜盲、畏光、迎风流泪,等症状,还会形成青光眼、白内障、眼底动脉硬化、视网膜病变等眼疾。

  肝主筋,其华在爪,过子时不睡觉,会引起肝血不足,就出现筋痛,麻木,屈伸困难,痉挛抽搐,易造成灰指甲,缺钙,髌骨软化,癫痫病,骨质疏松等症。

  肝与心,过子时不睡觉,可引起肝血不足,由于心主一身之血脉,肝有储藏和调节血液的功能,会造成心脏供血不足,引起心慌、心颤等症状,严重的形成心脏病、高血压等心脑血管疾病。

  肝与脾,过子时不睡觉,会引起肝胃不和,由于肝助脾胃消化,由于肝气太虚不能助脾胃消化,使人脾胃消化功能不好,表现为舌苔厚,长期以来会造成中气塌陷。

  肝与肺,过子时不睡觉,无法滋阴潜阳,肝阴亏损,引起肝火过盛灼肺,出现干咳、或咳嗽、咳痰血等木火刑金的证状,易导致牛皮癣等各种皮肤病。

  肝与肾,过子时不睡觉,肝虚导致肾亏,由于肝肾同源,容易造成生殖系统疾病、不育、骨病、牙病、脱发、糖尿病、肾衰竭等疾病。


 三、睡眠的方法

  交通规则――你不懂就容易出事故。比如说,23点至凌晨3点为子丑时,胆肝经最活跃的时候,肝胆要回血,"躺下去回血,站起来供血"。如果你每晚22 点钟左右躺下,静静得不要说话,到23点的时候,也就睡着了。肝胆开始回血,把有毒的血过滤掉,产生新鲜的血液,到一百岁也没有胆结石,也没有肝炎、囊肿 一类的病。如果你天天熬夜到1点多,肝回不了血,有毒的血排不掉,新鲜的血生不成,胆又无法换胆汁,所以这些人容易得胆结石、囊肿、大三阳、小三阳各种病 症。

  在欧洲地区,平均四个人就有一个肝炎病毒携带者,这就叫不懂规则。睡前半小时最好不要讲话,睡觉的时候更不要说话,如一说话,肺经动,然后心经又动,(因为心肺共为上焦)人就容易进入兴奋状态,所以就很难入睡。

  21:00―23:00为亥时。亥时三焦经旺,三焦通百脉。亥时入眠,百脉皆得濡养,故百岁老人得共同特点即21:00(亥时)之前入睡。女性若想长久的保持容颜娇好,应做到早睡早期。

  睡觉要关窗,不能开风扇、不能开空调,人生病很多都与此有关,因为人在睡眠之中,气血流通缓慢,体温下降,人体会在表面形成一种阳气层,这种阳气层它 使人叫"鬼魅不侵",什么意思呢,阳气足的人,不做恶梦,就是这种阳气,占了上风。开空调,开风扇,情况就不一样了,开窗户,窗户走的是风,风入的是筋, 如果开空调,也有风,风入筋,寒入骨,早上起来,身上发黄,脸发黄,脖子后面那条筋发硬,骨节酸痛,甚至有人就开始发烧,这就是风和寒侵入到了筋和骨头里 的缘故,这也就是气受伤了。如果说晚上睡觉不开窗,不开空调,不开风扇,连房门也关上,效果最好,如果热,把房门打开,把窗户关上,效果就差了一点,但是 他不至于第二天早上起来浑身乏力,后背僵硬.


有人把客厅的空调开开了,把卧室的门打开,和直接开空调睡觉是差不多的,开了空调以后,空调那个寒进了骨了,所以心里发冷,心在哪,心在脑髓,脑为髓之海,骨髓里有寒,那肯定心里就寒了,怎么办,补肾阳、补中气,什么时候补到心里不冷,烧就退了,寒走出去了。

  睡觉要尽量早睡,睡得晚,伤了少阳之气,必然第二天是疲倦无力,要关上窗户,不开空调、电扇,保护阳气。

  肝胆在下焦,如果胃出现问题的时候,他就会出现寝睡不安,一个是胃寒,如果这个人胃阳本来就不足,过多的喝绿茶,就会出现胃寒,胃寒的时候人是睡不好觉的,或者吃带泥沙之物过多,胃隐隐作寒,肯定是睡不好;

  再一个是胃热,就是热气往上走,嘴里喘的都是热气,像这种情况也睡不好觉;再一个是胃燥,口干舌燥,胃里感觉到燥;

  还有一个就是胃厚,气味的味,胃厚,这种情况就是吃了这种厚腻的味道,有人吃海鲜、吃鱼、吃炖鸡,味道好鲜美,吃多了,美味不可多用,这些东西在里面要稀释它,不稀释它,它在里面味太厚了,所以这个也睡不好觉;

  再一个腹涨,腹是涨鼓鼓的,也睡不着,翻来覆去也睡不着;再一个是胃气太虚,冒冷汗,这也睡不好觉,这些原因都可能形成胃不宁,胃不宁就睡不好。

  睡觉时要肢暖,四肢要暖,因为四肢是阳之本,这个大家都知道了,四肢不暖,肯定是肾阳不足,应该在睡觉之前把手脚捂暖,手脚和肚脐、背后的命门都要盖好。


睡眠法因人而异,下面介绍3种做法:

  1、睡觉前简单的压腿,然后在床上自然盘坐,两手重叠放于腿上,自然呼吸,感觉全身毛孔随呼吸一张一合,若能流泪打哈欠效果最佳,到了想睡觉时倒下便睡。

  2、仰卧,自然呼吸,感觉呼吸像春风,先融化大脚趾,然后是其他脚趾,接着脚、小腿、大腿逐渐融化。如还未醒着,再从头做。

  3、入睡快的人可右侧卧,右手掌托右耳。右掌心为火,耳为水,二者形成水火即济,在人体中形成心肾相交。久之,养心滋肾。

  睡眠一定要早起,即使在冬天,也不可超过6点起床,春夏秋季尽量在5点之前起床,因为人在寅时(3点―5点)肺经旺的时候起床,能够使肺气得以舒展, 以顺应阳气的舒长,来完成新陈代谢,肃降浊气,使肺气清,这样有助于养肺和顺应太阳的天势升起人体阳气,使人一天阳气充足,否则,就好像发动机,过了这段 好时机就很难发动人体阳气,人体阳气淤积在人体下部不能由命门向上发动升起,会形成淫气,严重损害人的身心健康。


早晨5点至7点是人体大肠经最旺的时候,人体需要把代谢的浊物排出体外,此时如果不起床,大肠得不到充分活动,无法很好的完成排浊功能,使浊物停留而形成 毒素,危害人体血液和脏腑百骸。早晨7点到9点人体胃经最旺,9点到11点人体脾经最旺,这时人的消化吸收运化的能力最好,如果这时还不起床,人体胃酸会 严重腐蚀胃粘膜,人体在最佳吸收营养时间得不到营养,长期以来会患脾胃疾病,造成营养不良、中气塌陷。所以千万不要赖床,赖床会造成头昏、疲惫不堪、睡眠 不足的感觉,而应按时起床,历史上许多伟人都是有三四点钟起床的习惯,比如华盛顿、拿破仑、康熙皇帝、曾国藩等。另外早起能增加工作效益,俗话说:"三天 早起,一天工"。

  现代医学证明,早睡早起的人精神压力较小,不易患精神类疾病。早晨不要太早出去锻炼,因为早晨在太阳没有出来之前,地下道的漳气、浊气正往上走(尤其是城市),这些气对人体损伤是很严重的。

  养身三大事,一睡眠,二便利,三饮食,其余起居、服装等皆是辅助。

  三事中睡眠第一。然胃纳不和者,夜眠不安,故以通便利为第二。而饮食无节,饥饱过度者,肠胃必受伤,而营养日减。睡以安神为主,神以心安为主,应配合 年龄,壮年至多七小时至八小时,多睡则智昏头晕眼红胀,四肢疲软,童年必睡足八小时,或过九小时勿碍,老或病人至多六小时已足。


应注意:

  (一)睡眠宜早,勿过十时,老年人以八点为正,勿过九点。凡交十一时,为阳生时,属肾,此时失眠,肾水必亏,心肾相连,水亏则火旺,最易伤神。千万勿以安眠药片助睡。

  (二)枕上切忌思索计算未来事,睡时宜一切不思,鼻息调匀,自己静听其气,由粗而细,由细而微细而息。视此身如无物,或如糖入于水,化为乌有,自然睡着。

  (三)如有思想,不能安着,切勿在枕上转侧思虑,此最耗神,可坐起一时再睡。

  (四)如在午时,即上午十一点至一点,为阴生之时,属心,此时如不能睡,可静坐一刻钟,闭目养神,则心气强。凡有心脏病者切宜注意,每日于此二时注意,则元气日强,无心跳腹泄或小便频速之病。

  (五)夏日起宜早,冬日起宜迟。居北方宜防寒气,如在粤桂等省,早起防山岚瘴气中病。食后勿仰天睡,早起如在寅时三点至五点,此时切忌郁怒,必损肺伤肝,万望注意。

下文转的是一篇站长的经验给大家参考(草根创业路上最真实的27条创业经验)

  1、不要仅仅因为情谊而组成团队

  虽说不提倡网站主在网络创业的过程中闭门造车,但是不要仅仅因为彼此的情谊而组成团队。如果团队的人员彼此连一起做垃圾站的默契都没有,最后的结局只有一个,不欢而散,连原本的情谊也没有了。

  2、不要让自己的思维超越了自己的脚步

  这个问题很多朋友在创业中国每天的文章中经常看到,就是执行力问题。网站主大多思维活跃,不缺。半夜三更或许会因为一个自己觉得优秀的创意而兴奋的睡不着觉,可是第二天早晨起来一切依旧。所以做的过程中不要想的太多,不要让自己的思维超越了自己的脚步。

  3、考虑清楚自己的抗压能力

  网络创业不是一蹴而就的,从有创业的念头开始,到创业成功,这之间有个漫长的过程。在这个过程中,要承受"苦心志,饿体肤"的痛苦,抗压能力弱,意志薄弱者很有可能会在一阶段放弃。

  4、不要老是问做什么站既有流量又赚钱快之类的问题

  多看看前辈的经验性的文章,遇到不懂的问题要多跟朋友交流。但是不要一加别人的QQ,连起码的"你好"就没有,在确定对方是高人后立马来句," 告诉我做什么站既有流量又赚钱快"。对于高人而言,做什么站都是既有流量赚钱也快,而对于你而言可能是做什么站既没有流量也无法赚钱。

  5、可以做垃圾站但是不要做垃圾站长

  看完帖子不要动不动就"靠你妈,你真是个垃圾",骂别人是垃圾的人很多时候自己其实是个垃圾。如果不同意文章的观点或文中作者的人生态度,可以用文明的语言,不需要动不动就像古惑仔一样,现在是21世纪,是个崇尚文明的社会。

  6、网站运营时间不到一年就不要说自己坚持了

  经常有朋友说,说坚持了,但是失败了。问他坚持了多长时间,他说,我坚持了一个多月,流量还是没上来,所以我关闭网站。这样的站长没有读懂坚持二字的含义。

  7、在上服务器前做好被挂马的心理准备

  网站主大多都会从虚拟空间时代过渡到服务器时代,在架设自己的独立服务器之前要做好网站被黑或被挂马的准备,所以要做好数据备份的准备,必要的时候要准备好备用服务器。

  8、要有一帮铁心的朋友

  网站主通过网络创业的过程是艰辛的,所以一定要有一帮铁心的朋友,即使他们不是做网站的。因为在很多人都关注你飞的高不高的时候,这群朋友会关注你飞得累不累。

  9、要有一颗感恩的心

  不要觉得别人成功了,别人知道你不知道的问题,别人就有帮助你的义务。要学会感恩,不要在别人花很长时间在QQ上解决掉你的问题后说句"哦,知道了",然后就下线了。连个谢谢就不说。

  10、要坚持自己的原则有自己的观点

  在网上看完别人的文章,对文中的不同观点,要敢于表达自己的想法。

  11、不要总是看别人的经验心得

  什么时候自己也写一点经验出来,如果没有很好的文笔,那就写的淳朴实在一点,别人不会因为你的文笔而否定你的真诚,如果这样也写不出来,那说明你很危险了。

  12、如果在没有执行力的情况下跟风别人的网站时,不要随便说:它做的还不行,我要做大做强

  其实你也不行,跟风就是跟风,跟别人的风其实就是对自己的挑战,"我要比他做的好"是做出来的,不是说出来的。

  13、作为站长平常要多看最适合自己的经验心得,但不能只会说"很好,支持。"

  做站长也是需要学习,明确自己的方向,看最有实用价值的文章,然后运用在自己的执行中,这才叫真正学到手,不要只会看热闹,那样只是浪费时间。

  14、做网站要量力而行

  自己什么层次,能做什么,要非常清楚,在技术不怎么好的情况下,学会运营,找一个踏实的项目,运营好了一样赚钱,有多大本事创多大业,心态摆正 为先。马云说:心中无底,无敌于天下,虽然有点扯淡的感觉,其实是说明了心态的重要性。是你的终究是你的,不是你的莫强求,煮熟的鸭子也会飞。

  15、请尽量不要相信凭空想象的"赚钱创意"

  站长一大把,现实社会各方面都趋于理性,你帮我赚10块,我可以给你5块,好的赚钱创意是从现实中来,解决现实的问题。赚钱的模式其实是最简单的模式,最简单的服务就是最优质的服务。

  16、踏踏实实把站做好,勇敢的去炒作

  程度自己拿捏好,不要太过分。想早点出头,炒作是个好办法。当被别人指责炒作时,不用太顾虑,没有争议不叫炒作。

  17、用脑做站,用手执行,用嘴推站,切勿反过来,那样的梦永远是梦

  18、个人资金少技术差做站创业,请尽量避开流量、引擎,多关注地方站

  19、多交80后和部分70后私企老板为朋友。

  这一部分人群对网络的接受程度都还不错,比较容易接受,如果项目可以的话,可以给这些老板的实体厂服务,实在不行,当创业缺资金时拉点小投资也好。

  20、做站最低级的运营策略就是拿免费吸引人,可悲的是免费也找不到赢利点

  天上不会掉馅饼,免费说明你不能提供优质的服务,没有核心竞争力,一直这样下去没有突破的话就是失败,好东西好服务不会免费。

  21、放宽心,学会快乐,学会说话幽默

  郁闷是一天,快乐也是一天,何乐而不为?身心快乐有助于解决问题克服苦难,问题解决了,也就进步了。没事看看郭德纲相声,学会讲哲理性的笑话,这样线下跟客户打交道时,容易有一个活跃的氛围。

  22、清楚自己创业的动力是什么

  是一时的兴起?是玩一下?这些在创业路上动力不够持久,如果是迫于生计,那完全两种情况,只有曾经有过身无分文经历的人才能真正体会到在这个社 会生存有多难,钱有多重要,这样的创业者做事情才会结合现实稳扎稳打,最终的成功率会高些。人的潜力是很大的,但潜力要激发出来也不那么容易。

  23、在综合能力达不到的情况下,成功学、励志学看的越多越等于白看

  当一个婴儿连站都困难的时候,让他学习骑自行车的话,只会令他受伤,更加烦躁。只是打个比方,如果换做站长,那只会更加的"飘"。

  24、站长们坚持住,站长有出头的一天

  站长真的是一个了不起的群体,社会也开始慢慢的关注起来了,站长在电视台的出镜率越来越频繁,想对做地方站的朋友说,把站做好,如果你有不寻常于平常人的经历,相信你有机会成为将来的焦点,个人的付出会被认可,同时也是推广的好机会。

  这是一个美好的愿望,闭上眼睛想像一下也可以,呵呵,起码想像一下是美好的,不管怎样先把站做好,努力加油。

  25、平常也到"我分网"逛一下

  以上的东西我都认可,也深有所感,闲着一个空间,就做了一个站长经验心得的分享站,里面的东西符合像我这样技术差水平低,更多的是关注于网站运营的站长,里面的东西虽然不是最好的,但都是个人认为比较实用的东西,多关注于地方站。

  26、穷不怕,不怕穷,抹开脸面往前冲

  要钱没钱,要技术没技术,但还想在站长生涯混出个样来,怎么办?只能网站运营上下点功夫,抹开脸多点执行力,线下多做点工作,积累点实际经验,肯定对网站有很大帮助。

  27、关注一下身边的女性

  有女朋友的平常多陪下女友,偶尔浪漫一下,从高压中释放一下;没女朋友的选择性的跟美女聊聊天,有助于血液循环,同时物色一个女友。对于有压力的站长来说,女友或者女孩有时候就是起降压作用。

  平常吃完晚饭后,不要急着回到电脑前,多跟母亲说说话,聊聊天就行。咱站长在别人眼里可能是只会上网的没用的人,那是因为他们不理解,平常受多 这些人的冷眼,但天下没有狠心的母亲,在母亲眼里永远都是自己的好儿女,饭后跟母亲聊聊天撒撒娇,或许能让站长那颗经受打击的心获得一点的温暖。

  我们加上 好了,想说的还很多,不多说了,前10条摘自《个人站长网络创业不容忽视的10点》是网上看见的,后面17条是有感而发写下的,希望多交真诚的站长朋友,QQ:397251430 www.admin5.com站长网首发 转载请注明出处。

2008年11月23日星期日

三万元搭建LINUX服务器集群案例

1.什么是服务器集群

  随着Internet的爆炸性增长,Internet与人的生活越来越息息相关,通过Internet上进行交易也就越来越受关注。近几年,电子商务的年增长均超过100%.服务器的工作量也迅速增长,所以服务器(特别是一个受人欢迎的WEB服务器)很容易在访问高峰时期过载。
 
  而另一方面,计算机从1946年单纯的科学计算任务到现在大量纷繁复杂的信息处理,工作量越来越大,需要越来越快的处理能力。所以计算机界就不得不不断研究更快的处理器,存储器,以适应这一需求。
 
  然而,科学家们意识到,单块处理器的速度发展空间是有限的,为什么不能让计算机象人一样协同工作,"群策群力"地将工作完成好呢!这时,就掀起了"并行计算"的研究。
 
  举个例子来说,我们架设了一台WWW服务器,上面构建了一个电子商务网站,然而随着时间的推移,名声越来越大,这时点击率也就越来越高,WWW服务器的负载也就越来越高。这种情况下,我们就必须提升WWW服务器的能力,以满足以益增长的服务请求。这时,我们就面临两种选择:1)升级WWW服务器,采用更快的CPU,增加更多的内存,使其更具有POWER;但日益增长的服务请求又会使服务器再次过载,需要再次升级,这样就陷入了升级的怪圈。还有,升级时还得考虑到服务如何接续,能否中止!
 
  2)增加WWW服务器,让多台服务器来完成相同的服务。

这种方法就是服务器集群,通过并行技术来大大提升系统性能。也就是这一章的主要内容,这种方法具有很好的扩展性,而且可以最大限度地利用已有投资。

1.1.集群的概念

集群,是一组独立的计算机系统构成一个松耦合的多处理器系统,它们之间通过网络实现进程间的通信。应用程序可以通过网络共享内存进行消息传送,实现分布式计算机。

近几年来,微处理器、内存、总线技术、网络技术有了非常大的进步,软件的并行技术也有了非常大的进步,这使得让一组廉价的个人电脑与工作站协同工作成为可能,甚至可以与拥有强大的芯片处理能力的超级计算机竞争。

比如,16个普通微处理器组成的集群系统可以达到亿次级浮点计算机能力,

而且总的成本小于40万元。

不幸的是,建造一个集群并不是一件简单的事件。集群的组成部分必须根据要运行的主要应用进行调整,以使之运行在最佳状态。这此因素带来的结果就是,建造集群系统不是只有一个标准的方案,在本章中,我们就会看到许多种建造方案。

集群技术是计算机系统结构的前沿领域,笔者也仅是略有了解,希望本文能起到抛砖引玉之用。

1.2.并行技术

这是一个非常简单的建造四节点的小集群系统的例子,它是构建在Linux操作系统上,通过MPICH软件包实现的,希望这个小例子能让大家对集群系统的构建有一个最基本的了解。

2.使用MPICH构建一个四节点的集群系统

这是一个非常简单的建造四节点的小集群系统的例子,它是构建在Linux操作系统上,通过MPICH软件包实现的,希望这个小例子能让大家对集群系统的构建有一个最基本的了解。

2.1 所需设备

1).4台采用Pentium II处理器的PC机,每台配 
置64M内存,2GB以上的硬盘,和EIDE接口的光盘驱动器。

2).5块100M快速以太网卡,如SMC 9332 EtherPower 10/100(其中四块卡用于连接集群中的结点,另外一块用于将集群中的其中的一个节点与其它网络连接。)

3).5根足够连接集群系统中每个节点的,使用5类非屏蔽双绞线制作的RJ45缆线

4).1个快速以太网(100BASE-Tx)的集线器或交换

5).1张Linux安装盘

2.2 构建说明

对计算机硬件不熟的人,实施以下这些构建步骤会感到吃力。如果是这样,请找一些有经验的专业人士寻求帮助。

1. 准备好要使用的采用Pentium II处理器的PC机。确信所有的PC机都还没有接上电源,打开PC机的机箱,在准备与网络上的其它设备连接的PC机上安装上两块快速以太网卡,在其它的PC机上安装上一块快速以太网卡。当然别忘了要加上附加的内存。确定完成后盖上机箱,接上电源。

2. 使用4根RJ45线缆将四台PC机连到快速以太网的集线器或交换机上。使用剩下的1根RJ45线将额外的以太网卡(用于与其它网络相连的那块,这样机构就可以用上集群)连接到机构的局域网上(假定你的机构局域网也是快速以太网),然后打开电源。

3. 使用LINUX安装盘在每一台PC机上安装。请确信在LINUX系统中安装了C编译器和C的LIB库。当你配置TCP/IP时,建议你为四台PC分别指定为192.168.1.1192.168.1.2192.168.1.3192.168.1.4。第一台PC为你的服务器节点(拥有两块网卡的那台)。在这个服务器节点上的那块与机构局域网相连的网卡,你应该为其指定一个与机构局域网吻合的IP地址。

4.当所有PC都装好Linux系统后,编辑每台机器的/etc/hosts文件,让其包含以下几行:

192.168.1.1 node1 server

192.168.1.2 node2

192.168.1.3 node3

192.168.1.4 node4

编辑每台机器的/etc/hosts.equiv文件,使其包含以下几行:

node1

node2

node3

node4

$p#

以下的这些配置是为了让其能使用MPICH's p4策略去执行分布式的并行处理应用。

1. 在服务器节点 
,建一个/mirror目录,并将其配置成为NFS服务器,并在/etc/exports文件中增加一行:

/mirror node1(rw) node2(rw) node3(rw) node4(rw)

2. 在其他节点上,也建一个/mirror目录,关在/etc/fstab文件中增加一行:

server:/mirror /mirror nfs rw,bg,soft 0 0

3. /mirror这个目录从服务器上输出,装载在各个客户端,以便在各个节点间进行软件任务的分发。

4. 在服务器节点上,安装MPICH。MPICH的文档可在

http://www.mcs.anl.gov/mpi/mpich/docs.html获得。

5.任何一个集群用户(你必须在每一个节点新建一个相同的用户),必须在/mirror目录下建一个属于它的子目录,如/mirror/username,用来存放MPI程序和共享数据文件。这种情况,用户仅仅需要在服务器节点上编译MPI程序,然后将编译后的程序拷贝到在/mirror目录下属于它的的子目录中,然后从他在/mirror目录下属于它的的子目录下使用p4 MPI策略运行MPI程序。

2.3 MPICH安装指南

1.如果你有gunzip,就d下载mpich.tar.gz,要不然就下载mpich.tar.Z。你可以到http://www.mcs.anl.gov/mpi/mpich/downloa下载,也可以使用匿名FTP到ftp.mcs.anl.gov的pub/mpi目录拿。(如果你觉得这个东西太大,你可以到pub/mpi/mpisplit中取分隔成块的几个小包,然后用cat命令将它们合并)

2.解压:gunzip �;c mpich.tar.gz  tar xovf-(或zcat mpich.tar.Z tar xovf-)

3.进入mpich目录

4.执行:./configure为MPICH选择一套适合你的实际软硬件环境的参数组,如果你对这些默认选择的参数不满意,可以自己进行配置(具体参见MPICH的配置文档)。最好选择一个指定的目录来安装和配置MPICH,例如:

./configure -prefix=/usr/local/mpich-1.2.0

5.执行:make >& make.log 这会花一段较长的时间,不同的硬件环境花的时间也就不同,可能从10分钟到1个小时,甚至更多。

6.(可选)在工作站网络,或是一台单独的工作站,编辑mpich/util/machines/machines.xxx(xxx是MPICH对你机器体系结构取的名称,你能很容易的认出来)以反映你工作站的当地主机名。你完全可以跳过这一步。在集群中,这一步不需要。

7.(可选)编译、运行一个简单的测试程序:

cd examples/basic

make cpi

ln �;s ../../bin/mpirun mpirun

./mpirun �;np 4 cpi
此时,你就在你的系统上运行了一个MPI程序。

8.(可选)构建MPICH其余的环境,为ch_p4策略使 
安全的服务会使得任何启动速度加快,你可以执行以下命令构建:

make serv_p4

(serv_p4是一个较新的P4安全服务的版本,它包含在MPICH 1.2.0版中),nupshot程序是upshot程序的一个更快版本,但他需要tk 3.6版的源代码。如果你有这个包,你就用以下命令可以构建它:

make nupshot

9.(可选)如果你想将MPICH安装到一个公用的地方让其它人使用它,你可以执行:

make install 或 bin/mpiinstall

你可以使用-prefix选项指定MPICH安装目录。安装后将生成include、lib、bin、sbin、www和man目录以及一个小小的示例目录,

(可选)到此你可以通告所有的用户如何编译、执行一个MPI程序。

2.4 费用统计

这个小的集群方案总的费用大致如下:

设备费用:

4台 带EIDE CD-ROM 的机器: 24000元

5块快速以太网卡: 800元

1个快速以太网的集线机:2000元

5根双绞线:50元

软件费用:

LINUX安装光盘:50元

MPICH:0元

合计:26900元。

这样一个集群系统可以用于一些大量的科学计算,信息处理,而且其性价比实在是太好了,仅需不到三万元。



2008年11月22日星期六

孔雀鱼幼仔的饲养

母鱼产仔后,一定要捞出来,小鱼才不会被吃。
小鱼第一天不要喂食,要到第二或第三天再喂。

1.幼鱼对温度的变化不可超过1℃,所以养幼鱼的缸要放在温度较高且稳定的地方。还有,幼鱼对水质也很敏感,换入的水的水质和原水的水质差异较大时,很可以让小鱼死掉.给幼鱼换水不要太频繁。
2.幼鱼运动能力差,所以水流不能太强。
3.喂食方面有几种方法:
1.喂草履虫、丰年虾、水蚯蚓。丰年虾可以到鱼铺买卵来孵化。
2.鸡蛋黄,可以捏碎用纱布包住,喂的时候在鱼缸里晃晃。也可以用一小部分放到水里。
3.饲料,如果喂大鱼的饲料是固体颗粒饲料,可以把它研碎,投放到水里,饲料会被泡软,小鱼就能吃了。
注意要及时清理粪便和残料,以免夏天气温高水变质。
因为它是杂食性的,当它大一点的时候还可以喂一些绿色的食物。
当它大到一定后,就能像大鱼一样照顾了。
4.幼鱼体质较弱,一但发现有病就要马上治疗,用药份量不能太多。

EL表达式[转]

一、EL简介
1.语法结构
    ${expression}
2.[]与.运算符
    EL 提供.和[]两种运算符来存取数据。
    当要存取的属性名称中包含一些特殊字符,如.或?等并非字母或数字的符号,就一定要使用 []。例如:
        ${user.My-Name}应当改为${user["My-Name"] }
    如果要动态取值时,就可以用[]来做,而.无法做到动态取值。例如:
        ${sessionScope.user[data]}中data 是一个变量
3.变量
    EL存取变量数据的方法很简单,例如:${username}。它的意思是取出某一范围中名称为username的变量。
    因为我们并没有指定哪一个范围的username,所以它会依序从Page、Request、Session、Application范围查找。
    假如途中找到username,就直接回传,不再继续找下去,但是假如全部的范围都没有找到时,就回传null。
    属性范围在EL中的名称
        Page         PageScope
        Request         RequestScope
        Session         SessionScope
        Application     ApplicationScope
       
二、EL隐含对象
1.与范围有关的隐含对象
与范围有关的EL 隐含对象包含以下四个:pageScope、requestScope、sessionScope 和applicationScope;
它们基本上就和JSP的pageContext、request、session和application一样;
在EL中,这四个隐含对象只能用来取得范围属性值,即getAttribute(String name),却不能取得其他相关信息。

例如:我们要取得session中储存一个属性username的值,可以利用下列方法:
    session.getAttribute("username") 取得username的值,
在EL中则使用下列方法
    ${sessionScope.username}

2.与输入有关的隐含对象
与输入有关的隐含对象有两个:param和paramValues,它们是EL中比较特别的隐含对象。

例如我们要取得用户的请求参数时,可以利用下列方法:
    request.getParameter(String name)
    request.getParameterValues(String name)
在EL中则可以使用param和paramValues两者来取得数据。
    ${param.name}
    ${paramValues.name}

3.其他隐含对象

cookie
JSTL并没有提供设定cookie的动作,
例:要取得cookie中有一个设定名称为userCountry的值,可以使用${cookie.userCountry}来取得它。

header和headerValues
header 储存用户浏览器和服务端用来沟通的数据
例:要取得用户浏览器的版本,可以使用${header["User-Agent"]}。
另外在鲜少机会下,有可能同一标头名称拥有不同的值,此时必须改为使用headerValues 来取得这些值。

initParam
initParam取得设定web站点的环境参数(Context)
例:一般的方法String userid = (String)application.getInitParameter("userid");
    可以使用 ${initParam.userid}来取得名称为userid

pageContext
pageContext取得其他有关用户要求或页面的详细信息。
    ${pageContext.request.queryString}         取得请求的参数字符串
    ${pageContext.request.requestURL}         取得请求的URL,但不包括请求之参数字符串
    ${pageContext.request.contextPath}         服务的web application 的名称
    ${pageContext.request.method}           取得HTTP 的方法(GET、POST)
    ${pageContext.request.protocol}         取得使用的协议(HTTP/1.1、HTTP/1.0)
    ${pageContext.request.remoteUser}         取得用户名称
    ${pageContext.request.remoteAddr }         取得用户的IP 地址
    ${pageContext.session.new}             判断session 是否为新的
    ${pageContext.session.id}               取得session 的ID
    ${pageContext.servletContext.serverInfo}   取得主机端的服务信息

三、EL运算符
1.算术运算符有五个:+、-、*或$、/或div、%或mod
2.关系运算符有六个:==或eq、!=或ne、<或lt、>或gt、<=或le、>=或ge
3.逻辑运算符有三个:&&或and、||或or、!或not
4.其它运算符有三个:Empty运算符、条件运算符、()运算符
    例:${empty param.name}、${A?B:C}、${A*(B+C)}

四、EL函数(functions)。
语法:ns:function( arg1, arg2, arg3 …. argN)
其中ns为前置名称(prefix),它必须和taglib 指令的前置名称一置

---------------------------------------------

补充:

<%@ taglib prefix="c" uri="http://java.sun.com/jstl/core_rt" %>

FOREACH:

<c:forEach items="${messages}"
var="item"
begin="0"
end="9"
step="1"
varStatus="var">
……
</c:forEach>


OUT:

<c:out value="/${logininfo.username}"/>
c:out>将value 中的内容输出到当前位置,这里也就是把logininfo 对象的
username属性值输出到页面当前位置。
${……}是JSP2.0 中的Expression Language(EL)的语法。它定义了一个表达式,
其中的表达式可以是一个常量(如上),也可以是一个具体的表达语句(如forEach循环体中
的情况)。典型案例如下:
Ø ${logininfo.username}
这表明引用logininfo 对象的username 属性。我们可以通过"."操作符引
用对象的属性,也可以用"[]"引用对象属性,如${logininfo[username]}
与${logininfo.username}达到了同样的效果。
"[]"引用方式的意义在于,如果属性名中出现了特殊字符,如"."或者"-",
此时就必须使用"[]"获取属性值以避免语法上的冲突(系统开发时应尽量避免
这一现象的出现)。
与之等同的JSP Script大致如下:
LoginInfo logininfo =
(LoginInfo)session.getAttribute("logininfo");
String username = logininfo.getUsername();
可以看到,EL大大节省了编码量。
这里引出的另外一个问题就是,EL 将从哪里找到logininfo 对象,对于
${logininfo.username}这样的表达式而言,首先会从当前页面中寻找之前是
否定义了变量logininfo,如果没有找到则依次到Request、Session、
Application 范围内寻找,直到找到为止。如果直到最后依然没有找到匹配的
变量,则返回null.
如果我们需要指定变量的寻找范围,可以在EL表达式中指定搜寻范围:
${pageScope.logininfo.username}
${requestScope.logininfo.username}
${sessionScope.logininfo.username}
${applicationScope.logininfo.username}
在Spring 中,所有逻辑处理单元返回的结果数据,都将作为Attribute 被放
置到HttpServletRequest 对象中返回(具体实现可参见Spring 源码中
org.springframework.web.servlet.view.InternalResourceView.
exposeModelAsRequestAttributes方法的实现代码),也就是说Spring
MVC 中,结果数据对象默认都是requestScope。因此,在Spring MVC 中,
以下寻址方法应慎用:
${sessionScope.logininfo.username}
${applicationScope.logininfo.username}
Ø ${1+2}
结果为表达式计算结果,即整数值3。
Ø ${i>1}
如果变量值i>1的话,将返回bool类型true。与上例比较,可以发现EL会自
动根据表达式计算结果返回不同的数据类型。
表达式的写法与java代码中的表达式编写方式大致相同。

IF / CHOOSE:

<c:if test="${var.index % 2 == 0}">
*
</c:if>
判定条件一般为一个EL表达式。
<c:if>并没有提供else子句,使用的时候可能有些不便,此时我们可以通过<c:choose>
tag来达到类似的目的:
<c:choose>
<c:when test="${var.index % 2 == 0}">
*
</c:when>
<c:otherwise>
!
</c:otherwise>
</c:choose>
类似Java 中的switch 语句,<c:choose>提供了复杂判定条件下的简化处理手法。其
中<c:when>子句类似case子句,可以出现多次。上面的代码,在奇数行时输出"*"号,
而偶数行时输出"!"。
---------------------------------------------

再补充:

        1   EL表达式用${}表示,可用在所有的HTML和JSP标签中 作用是代替JSP页面中复杂的JAVA代码.

        2   EL表达式可操作常量 变量 和隐式对象. 最常用的 隐式对象有${param}和${paramValues}. ${param}表示返回请求参数中单个字符串的值. ${paramValues}表示返回请求参数的一组值.pageScope表示页面范围的变量.requestScope表示请求对象的变量. sessionScope表示会话范围内的变量.applicationScope表示应用范围的变量.

        3   <%@ page isELIgnored="true"%> 表示是否禁用EL语言,TRUE表示禁止.FALSE表示不禁止.JSP2.0中默认的启用EL语言.

        4   EL语言可显示 逻辑表达式如${true and false}结果是false    关系表达式如${5>6} 结果是false     算术表达式如 ${5+5} 结果是10

        5   EL中的变量搜索范围是:page request session application   点运算符(.)和"[ ]"都是表示获取变量的值.区别是[ ]可以显示非词类的变量

EL表达式的简单介绍[转]

一、JSP EL语言定义


        E L(Expression Language)  目的:为了使JSP写起来更加简单。
       表达式语言的灵感来自于 ECMAScript 和 XPath 表达式语言,它提供了在 JSP 中简化表达式的方法。它是一种简单的语言,基于可用的命名空间(PageContext 属性)、嵌套属性和对集合、操作符(算术型、关系型和逻辑型)的访问符、映射到 Java 类中静态方法的可扩展函数以及一组隐式对象。

       EL 提供了在 JSP 脚本编制元素范围外使用运行时表达式的功能。脚本编制元素是指页面中能够用于在 JSP 文件中嵌入 Java 代码的元素。它们通常用于对象操作以及执行那些影响所生成内容的计算。JSP 2.0 将 EL 表达式添加为一种脚本编制元素。

二、JSP EL简介
1、语法结构
     ${expression}
2、[ ]与.运算符
     EL 提供"."和"[ ]"两种运算符来存取数据。
     当要存取的属性名称中包含一些特殊字符,如.或?等并非字母或数字的符号,就一定要使用"[ ]"。例如:
         ${user.My-Name}应当改为${user["My-Name"] }
     如果要动态取值时,就可以用"[ ]"来做,而"."无法做到动态取值。例如:
         ${sessionScope.user[data]}中data 是一个变量
3、变量
     EL存取变量数据的方法很简单,例如:${username}。它的意思是取出某一范围中名称为username的变量。
     因为我们并没有指定哪一个范围的username,所以它会依序从Page、Request、Session、Application范围查找。
     假如途中找到username,就直接回传,不再继续找下去,但是假如全部的范围都没有找到时,就回传null。
     属性范围在EL中的名称
         Page          PageScope
         Request          RequestScope
         Session          SessionScope
         Application      ApplicationScope


二、JSP EL 中的有效表达式
       有效表达式可以包含文字、操作符、变量(对象引用)和函数调用。我们将分别了解这些有效表达式中的每一种:

1、文字
JSP 表达式语言定义可在表达式中使用的以下文字:

 

文字 文字的值
Boolean
 true 和 false
 
Integer
 与 Java 类似。可以包含任何正数或负数,例如 24、-45、567
 
Floating Point
 与 Java 类似。可以包含任何正的或负的浮点数,例如 -1.8E-45、4.567
 
String
 任何由单引号或双引号限定的字符串。对于单引号、双引号和反斜杠,使用反斜杠字符作为转义序列。必须注意,如果在字符串两端使用双引号,则单引号不需要转义。
 
Null null


2、操作符
JSP 表达式语言提供以下操作符,其中大部分是 Java 中常用的操作符:

术语 定义
算术型
 +、-(二元)、*、/、div、%、mod、-(一元)
 
逻辑型
 and、&&、or、||、!、not
 
关系型
 ==、eq、!=、ne、、gt、<=、le、>=、ge。可以与其他值进行比较,或与布尔型、字符串型、整型或浮点型文字进行比较。
 

 空操作符是前缀操作,可用于确定值是否为空。
 
条件型 A ?B :C。根据 A 赋值的结果来赋值 B 或 C。 


3、隐式对象
JSP 表达式语言定义了一组隐式对象,其中许多对象在 JSP scriplet 和表达式中可用:

                                         术语

 JSP 页的上下文。它可以用于访问 JSP 隐式对象,如请求、响应、会话、输出、servletContext 等。例如,${pageContext.response} 为页面的响应对象赋值。
 


此外,还提供几个隐式对象,允许对以下对象进行简易访问:

术语 定义
param
 将请求参数名称映射到单个字符串参数值(通过调用 ServletRequest.getParameter (String name) 获得)。getParameter (String) 方法返回带有特定名称的参数。表达式 $(param.name) 相当于 request.getParameter (name)。
 
paramValues
 将 请求参数名称映射到一个数值数组(通过调用 ServletRequest.getParameter (String name) 获得)。它与 param 隐式对象非常类似,但它检索一个字符串数组而不是单个值。表达式 ${paramvalues.name) 相当于 request.getParamterValues(name)。
 
header
 将请求头名称映射到单个字符串头值(通过调用 ServletRequest.getHeader(String name) 获得)。表达式 ${header.name} 相当于 request.getHeader(name)。
 
headerValues
 将 请求头名称映射到一个数值数组(通过调用 ServletRequest.getHeaders(String) 获得)。它与头隐式对象非常类似。表达式 ${headerValues.name} 相当于 request.getHeaderValues(name)。
 
cookie 将 cookie 名称映射到单个 cookie 对象。向服务器发出的客户端请求可以获得一个或多个 cookie。表达式 ${cookie.name.value} 返回带有特定名称的第一个 cookie 值。如果请求包含多个同名的 cookie,则应该使用 ${headerValues.name} 表达式。
initParam 将上下文初始化参数名称映射到单个值(通过调用 ServletContext.getInitparameter(String name) 获得)。 


除了上述两种类型的隐式对象之外,还有些对象允许访问多种范围的变量,如 Web 上下文、会话、请求、页面:

术语 定义
pageScope
 将页面范围的变量名称映射到其值。例如,EL 表达式可以使用 ${pageScope.objectName} 访问一个 JSP 中页面范围的对象,还可以使用 ${pageScope.objectName.attributeName} 访问对象的属性。
 
requestScope
 将 请求范围的变量名称映射到其值。该对象允许访问请求对象的属性。例如,EL 表达式可以使用 ${requestScope.objectName} 访问一个 JSP 请求范围的对象,还可以使用 ${requestScope.objectName.attributeName} 访问对象的属性。
 
sessionScope
 将会话范围的变量名称映射到其值。该对象允许访问会话对象的属性。例如:


$sessionScope.name}

 
applicationScope
 将应用程序范围的变量名称映射到其值。该隐式对象允许访问应用程序范围的对象。
 


三、特别强调:
1、注意当表达式根据名称引用这些对象之一时,返回的是相应的对象而不是相应的属性。例如:即使现有的 pageContext 属性包含某些其他值,${pageContext} 也返回 PageContext 对象。

2、 注意 <%@ page isELIgnored="true" %> 表示是否禁用EL语言,TRUE表示禁止.FALSE表示不禁止.JSP2.0中默认的启用EL语言。

四、举例说明
1、例如,

      < %=request.getParameter("username")% >       等价于       ${ param.username }

2、例如,但是下面的那句EL语言可以完成如果得到一个username为空,则不显示null,而是不显示值。

userName:<input name="uname" type="text" value="${param.uname}/> 

pwd:<input name="pwd" type="password" value="${param.pwd}/>

addr:<input name="addr" type="text" value="${param.addr}/>

3、例如:

<% =request.getAttribute("userlist") %>     等价于$     { requestScope.userlist }

4、例如,原理如上例3。

${ sessionScope.userlist } 1

${ sessionScope.userlist } 2

${ applicationScope.userlist } 3

${ pageScope.userlist } 4

${uselist} 含义:执行顺序为4 1 2 3。

"."后面的只是一个字符串,并不是真正的内置对象,不能调用对象。

4、例如,

   <%=user.getAddr( ) %>      等价于     ${user.addr}

第一句前面的user,为一个变量。

   第二句后面user,必须为在某一个范围里的属性。

2008年11月19日星期三

什么是SSI

  SSI(Server Side Include),通常称为服务器端嵌入,是一种类似于ASP的基于服务器的网页制作技术。大多数(尤其是基于Unix平台)的WEB服务器如Netscape Enterprise Server等均支持SSI命令。
  SSI工作原理:
  将内容发送到浏览器之前,可以使用"服务器端包含 (SSI)"指令将文本、图形或应用程序信息包含到网页中。例如,可以使用 SSI 包含时间/日期戳、版权声明或供客户填写并返回的表单。对于在多个文件中重复出现的文本或图形,使用包含文件是一种简便的方法。将内容存入一个包含文件中即可,而不必将内容输入所有文件。通过一个非常简单的语句即可调用包含文件,此语句指示 Web 服务器将内容插入适当网页。而且,使用包含文件时,对内容的所有更改只需在一个地方就能完成。
  因为包含 SSI 指令的文件要求特殊处理,所以必须为所有 SSI 文件赋予 SSI 文件扩展名。默认扩展名是 .stm、.shtm 和 .shtml
  SSI有什么用?
  之所以要扯到ssi,是因为shtml--server-parsed HTML 的首字母缩略词。包含有嵌入式服务器方包含命令的 HTML 文本。在被传送给浏览器之前,服务器会对 SHTML 文档进行完全地读取、分析以及修改。
  shtml和asp 有一些相似,以shtml命名的文件里,使用了ssi的一些指令,就像asp中的指令,你可以在SHTML文件中写入SSI指令,当客户端访问这些shtml文件时,服务器端会把这些SHTML文件进行读取和解释,把SHTML文件中包含的SSI指令解释出来
  比如:你可以在SHTML文件中用SSI指令引用其他的html文件(#include ),服务器传送给客户端的文件,是已经解释的SHTML不会有SSI指令。它实现了HTML所没有的功能,就是可以实现了动态的SHTML,可以说是HTML的一种进化吧。像新浪的新闻系统就是这样的,新闻内容是固定的但它上面的广告和菜单等就是用#include引用进来的。
  目前,主要有以下几种用用途:
  1、显示服务器端环境变量<#echo>
  2、将文本内容直接插入到文档中<#include>
  3、显示WEB文档相关信息<#flastmod #fsize> (如文件制作日期/大小等)
  4、直接执行服务器上的各种程序<#exec>(如CGI或其他可执行程序)
  5、设置SSI信息显示格式<#config>(如文件制作日期/大小显示方式) 高级SSI<XSSI>可设置变量使用if条件语句。
  使用SSI
  SSI是为WEB服务器提供的一套命令,这些命令只要直接嵌入到HTML文档的注释内容之中即可。如:
  <!--#include file="info.htm"-->
  就是一条SSI指令,其作用是将"info.htm"的内容拷贝到当前的页面中,当访问者来浏览时,会看到其它HTML文档一样显示info.htm其中的内容。
  其它的SSI指令使用形式基本同刚才的举例差不多,可见SSI使用只是插入一点代码而已,使用形式非常简单。
  当然,如果WEB服务器不支持SSI,它就会只不过将它当作注释信息,直接跳过其中的内容;浏览器也会忽略这些信息。
  如何在我的WEB服务器上配置SSI功能?
  在一些WEB服务器上(如IIS 4.0/SAMBAR 4.2),包含 #include 指令的文件必须使用已被映射到 SSI 解释程序的扩展名;否则,Web 服务器将不会处理该SSI指令;默认情况下,扩展名 .stm、.shtm 和 .shtml 被映射到解释程序(Ssinc.dll)。
  Apache则是根据你的设置情况而定,修改srm.conf如:
  AddType text/x-server-parsed-html .shtml 将只对.shtml扩展名的文件解析SSI指令
  AddType text/x-server-parsed-html .html将对所有HTML文档解析SSI指令
  Netscape WEB服务器直接使用Administration Server(管理服务器)可打开SSI功能。
  Website使用Server Admin程序中的Mapping标签,扩展名添加内容类型为:wwwserver/html-ssi
  Cern服务器不支持SSI,可用SSI诈骗法,到http://sw.cse.bris.ac.uk/webtools/fakessi.html ;上下载一个PERL脚本,即可使你的CERN服务器使用一些SSI指令。(不支持exec指令。)
  SSI指令基本格式
  SSI指令基本格式:
  程序代码:
  <!-� 指令名称="指令参数">
  <!-� 指令名称="指令参数">
  如 程序代码:
  <!--#include file="info.htm"-->
  <!--#include file="info.htm"-->
  说明:
  1.<!-- -->是HTML语法中表示注释,当WEB服务器不支持SSI时,会忽略这些信息。
  2.#include 为SSI指令之一。
  3.file 为include的参数, info.htm为参数值,在本指令中指将要包含的文档名。
  注意:
  1.<!--与#号间无空格,只有SSI指令与参数间存在空格。
  2.上面的标点="",一个也不能少。
  3.SSI指令是大小写敏感的,因此参数必须是小写才会起作用。
  SSI指令使用详解
  #echo 示范
  作用:
  将环境变量插入到页面中。
  语法:
  程序代码:
  <!--#echo var="变量名称"-->
  <!--#echo var="变量名称"-->
  本文档名称:程序代码:
  <!--#echo var="DOCUMENT_NAME"-->
  <!--#echo var="DOCUMENT_NAME"-->
  现在时间:程序代码:
  <!--#echo var="DATE_LOCAL"-->
  <!--#echo var="DATE_LOCAL"-->
  你的IP地址是程序代码:
  <!--#echo var="REMOTE_ADDR"-->
  <!--#echo var="REMOTE_ADDR"-->
  #include 示范
  作用:
  将文本文件的内容直接插入到文档页面中。
  语法:
  程序代码:
  <!--#include file="文件名称"-->
  <!--#include virtual="文件名称"-->
  <!--#include file="文件名称"-->
  <!--#include virtual="文件名称"-->
  file 文件名是一个相对路径,该路径相对于使用 #include 指令的文档所在的目录。被包含文件可以在同一级目录或其子目录中,但不能在上一级目录中。如表示当前目录下的的nav_head.htm文档,则为file="nav_head.htm"。
  virtual 文件名是 Web 站点上的虚拟目录的完整路径。如表示相对于服务器文档根目录下hoyi目录下的nav_head.htm文件;则为file="/hoyi/nav_head.htm"
  参数:
  file 指定包含文件相对于本文档的位置
  virtual 指定相对于服务器文档根目录的位置
  注意:
  1、文件名称必须带有扩展名。
  2、被包含的文件可以具有任何文件扩展名,我觉得直接使用htm扩展名最方便,微软公司推荐使用 .inc 扩展名(这就看你的爱好了)。
  示例:
  程序代码:
  <!--#include file="nav_head.htm"-->将头文件插入到当前页面
  <!--#include file="nav_foot.htm"-->将尾文件插入到当前页面
  <!--#include file="nav_head.htm"-->将头文件插入到当前页面
  <!--#include file="nav_foot.htm"-->将尾文件插入到当前页面
  #flastmod 和#fsize 示范
  作用: #flastmod 文件最近更新日期
  #fsize 文件的长度
  语法:
  程序代码:
  <!--#flastmod file="文件名称"-->
  <!--#fsize file="文件名称"-->
  <!--#flastmod file="文件名称"-->
  <!--#fsize file="文件名称"-->
  参数:
  file 指定包含文件相对于本文档的位置 如 info.txt 表示当前目录下的的info.txt文档
  virtual 指定相对于服务器文档根目录的位置 如 /hoyi/info.txt 表示
  注意:
  文件名称必须带有扩展名。
  示例:
  程序代码:
  <!--#flastmod file="news.htm"-->
  <!--#flastmod file="news.htm"-->
  将当前目录下news.htm文件的最近更新日期插插入到当前页面
  程序代码:
  <!--#fsize file="news.htm"-->
  <!--#fsize file="news.htm"-->
  将当前目录下news.htm的文件大小入到当前页面
  #exec 示范
  作用:
  将某一外部程序的输出插入到页面中。可插入CGI程序或者是常规应用程序的输入,这取决于使用的参数是cmd还是cgi。
  语法:
  程序代码:
  <!--#exec cmd="文件名称"-->
  <!--#exec cgi="文件名称"-->
  <!--#exec cmd="文件名称"-->
  <!--#exec cgi="文件名称"-->
  参数:
  cmd 常规应用程序
  cgi CGI脚本程序
  示例:
  程序代码:
  <!--#exec cmd="cat /etc/passwd"-->将会显示密码文件
  <!--#exec cmd="dir /b"-->将会显示当前目录下文件列表
  <!--#exec cgi="/cgi-bin/gb.cgi"-->将会执行CGI程序gb.cgi。
  <!--#exec cgi="/cgi-bin/access_log.cgi"-->将会执行CGI程序access_log.cgi。
  <!--#exec cmd="cat /etc/passwd"-->将会显示密码文件
  <!--#exec cmd="dir /b"-->将会显示当前目录下文件列表
  <!--#exec cgi="/cgi-bin/gb.cgi"-->将会执行CGI程序gb.cgi。
  <!--#exec cgi="/cgi-bin/access_log.cgi"-->将会执行CGI程序access_log.cgi。
  注意:
  从上面的示例可以看出,这个指令相当方便,但是也存在安全问题。
  禁止方法:
  .Apache,将access.conf中的"Options Includes ExecCGI"这行代码删除;
  .在IIS中,要禁用 #exec 命令,可修改 SSIExecDisable 元数据库;
  #config
  作用: 指定返回给客户端浏览器的错误信息、日期和文件大小的格式。
  语法:
  程序代码:
  <!--#config errmsg="自定义错误信息"-->
  <!--#config sizefmt="显示单位"-->
  <!--#config timefmt="显示格式"-->
  <!--#config errmsg="自定义错误信息"-->
  <!--#config sizefmt="显示单位"-->
  <!--#config timefmt="显示格式"-->
  参数:
  errmsg 自定义SSI执行错误信息,可以为任何你喜欢的方式。
  sizefmt 文件大小显示方式,默认为字节方式("bytes")可以改为千字节方式("abbrev")
  timefmt 时间显示方式,最灵活的配置属性。
  示例: 显示一个不存在文件的大小
  程序代码:
  <!--#config errmsg="服务器执行错误,请联系管理员 yiho@126.com,谢谢!"-->
  <!--#fsize file="不存在的文件.htm"-->
  <!--#config errmsg="服务器执行错误,请联系管理员 yiho@126.com,谢谢!"-->
  <!--#fsize file="不存在的文件.htm"-->
  以千字节方式显示文件大小
  程序代码:
  <!--#config sizefmt="abbrev"-->
  <!--#fsizefile="news.htm"-->
  <!--#config sizefmt="abbrev"-->
  <!--#fsizefile="news.htm"-->
  以特定的时间格式显示时间
  程序代码:
  <!--#config timefmt="%Y年/%m月%d日 星期%W 北京时间%H:%M:%s,%Y年已过去了%j天 今天是%Y年的第%U个星期"-->
  <!--#echo var="DATE_LOCAL"--> 显示今天是星期几,几月,时区
  <!--#config timefmt="今天%A, %B ,服务器时区是 %z,是"-->
  <!--#echo var="DATE_LOCAL"-->
  <!--#config timefmt="%Y年/%m月%d日 星期%W 北京时间%H:%M:%s,%Y年已过去了%j天 今天是%Y年的第%U个星期"-->
  <!--#echo var="DATE_LOCAL"--> 显示今天是星期几,几月,时区
  <!--#config timefmt="今天%A, %B ,服务器时区是 %z,是"-->
  <!--#echo var="DATE_LOCAL"-->
  XSSI
  XSSI(Extended SSI)是一组高级SSI指令,内置于Apache 1.2或更高版本的mod-include模块之中。
  其中可利用的的指令有:
  #printenv
  #set
  #if
  #printenv
  作用: 显示当前存在于WEB服务器环境中的所有环境变量。
  语法:程序代码:
  <!--#printenv-->
  <!--#printenv-->
  <!--#printenv-->
  <!--#printenv-->
  #set
  作用:可给变量赋值,以用于后面的if语句。
  语法:程序代码:
  <!--#set var="变量名"value="变量值"-->
  <!--#set var="变量名"value="变量值"-->
  参数:无
  示例: 程序代码:
  <!--#set var="color"value="红色"-->
  <!--#set var="color"value="红色"-->
  #if
  作用: 创建可以改变数据的页面,这些数据根据使用if语句时计算的要求予以显示。
  语法: 程序代码:
  <!--#if expr="$变量名=\"变量值A\""-->
  显示内容
  <!--#elif expr="$变量名=\"变量值B\""-->
  显示内容
  <!--#else-->
  显示内容
  <!--

2008年11月18日星期二

用Java实现HTTP文件队列下载

 
 序言

  许多用户可能会遇到这样的情况:在网站上发现一个很好的资源,但是这个资源是分成了很多个文件存放的,如果想把它保存到本地,只有靠用户点击另存来完成保存,如果资源分了几百甚至上千上万,那简直是个灾难。

  在Internet上很多的资源分成多个文件存放时,它的文件命名是有一定的规则的;正因如此,我们就可以用程序来完成这个资源的完全下载。

  1. 基础知识

  在Internet上,我们要下载网站上的某个资源,我们会获得一个URL(Uniform Resource Locator),它是一个服务器资源定位的描述,下载的过程总是如下步骤:

  步骤1:客户端发起连接请求一个URL

  步骤2:服务器解析URL,并将指定的资源返回一个输入流给客户

  步骤3:客户端接收输入流,将流中的内容存到文件

  2. 网络连接的建立

  Java提供了对URL访问和大量的流操作的的API,我们可以很容易的完成对网络上资源的存取,下面的代码段就完成了对一个网站的资源进行访问:

......
destUrl="http://www.ebook.com/java/网络编程001.zip";
url = new URL(destUrl);
httpUrl = (HttpURLConnection) url.openConnection();
//连接指定的网络资源
httpUrl.connect();
//获取网络输入流
bis = new BufferedInputStream(httpUrl.getInputStream());
......

  3. 代理的访问

  Java 中通过代理服务器访问外网的方法已经是世人皆知的秘密了。这里就不再多描述了,访问的JAVA代码如下:

//设置代理服务器
System.getProperties().put("proxySet", "true");
System.getProperties().put("proxyHost", "10.154.134.110");
System.getProperties().put("proxyPort", "8080");

  4. 网络资源的保存

  在上节中,我们已经获取了指定网络资源的输入流,接下来我们要完成的就是读取输入流中的所以内容,并将其保存在文件中。示例代码:

......
fos = new FileOutputStream(fileName);
if (this.DEBUG)
System.out.println("正在获取链接[" + destUrl + "]的内容...\n将其保存为文件[" + fileName +"]");

//保存文件
while ( (size = bis.read(buf)) != -1)
fos.write(buf, 0, size);
......

  上面的示例代码就将网络资源的内容保存到了本地指定的文件中。

  5. 代码清单

import java.io.*;
import java.net.*;
import java.util.*;

/**
* <p>Title: 个人开发的API</p>
* <p>Description: 将指定的HTTP网络资源在本地以文件形式存放</p>
* <p>Copyright: Copyright (c) 2004</p>
* <p>Company: NewSky</p>
* @author MagicLiao
* @version 1.0
*/
public class HttpGet {

  public final static boolean DEBUG = true;//调试用
  private static int BUFFER_SIZE = 8096;//缓冲区大小
  private Vector vDownLoad = new Vector();//URL列表
  private Vector vFileList = new Vector();//下载后的保存文件名列表

  /**
  * 构造方法
  */
  public HttpGet() {}

  /**
  * 清除下载列表
  */
  public void resetList() {
   vDownLoad.clear();
   vFileList.clear();
  }

  /**
  * 增加下载列表项
  *
  * @param url String
  * @param filename String
  */

public void addItem(String url, String filename) {
  vDownLoad.add(url);
  vFileList.add(filename);
}

  /**
  * 根据列表下载资源
  */
public void downLoadByList() {
  String url = null;
  String filename = null;

  //按列表顺序保存资源
  for (int i = 0; i < vDownLoad.size(); i++) {
   url = (String) vDownLoad.get(i);
   filename = (String) vFileList.get(i);

   try {
    saveToFile(url, filename);
   }
   catch (IOException err) {
    if (DEBUG) {
     System.out.println("资源[" + url + "]下载失败!!!");
    }
   }
  }

  if (DEBUG) {
   System.out.println("下载完成!!!");
  }
}

/**
* 将HTTP资源另存为文件
*
* @param destUrl String
* @param fileName String
* @throws Exception
*/
public void saveToFile(String destUrl, String fileName) throws IOException {
  FileOutputStream fos = null;
  BufferedInputStream bis = null;
  HttpURLConnection httpUrl = null;
  URL url = null;
  byte[] buf = new byte[BUFFER_SIZE];
  int size = 0;

  //建立链接
  url = new URL(destUrl);
  httpUrl = (HttpURLConnection) url.openConnection();
  //连接指定的资源
  httpUrl.connect();
  //获取网络输入流
  bis = new BufferedInputStream(httpUrl.getInputStream());
  //建立文件
  fos = new FileOutputStream(fileName);

  if (this.DEBUG)
   System.out.println("正在获取链接[" + destUrl + "]的内容...\n将其保存为文件[" + fileName + "]");

  //保存文件
  while ( (size = bis.read(buf)) != -1)
   fos.write(buf, 0, size);

  fos.close();
  bis.close();
  httpUrl.disconnect();
}

/**
* 设置代理服务器
*
* @param proxy String
* @param proxyPort String
*/
public void setProxyServer(String proxy, String proxyPort) {
  //设置代理服务器
  System.getProperties().put("proxySet", "true");
  System.getProperties().put("proxyHost", proxy);
  System.getProperties().put("proxyPort", proxyPort);
}

/**
* 设置认证用户名与密码
*
* @param uid String
* @param pwd String
*/
public void setAuthenticator(String uid, String pwd) {
Authenticator.setDefault(new MyAuthenticator(uid, pwd));
}

/**
* 主方法(用于测试)
*
* @param argv String[]
*/
public static void main(String argv[]) {
  HttpGet oInstance = new HttpGet();
  try {
   //增加下载列表(此处用户可以写入自己代码来增加下载列表)
   oInstance.addItem("http://www.ebook.com/java/网络编程001.zip","./网络编程1.zip");
   oInstance.addItem("http://www.ebook.com/java/网络编程002.zip","./网络编程2.zip");
   oInstance.addItem("http://www.ebook.com/java/网络编程003.zip","./网络编程3.zip");
   oInstance.addItem("http://www.ebook.com/java/网络编程004.zip","./网络编程4.zip");
   oInstance.addItem("http://www.ebook.com/java/网络编程005.zip","./网络编程5.zip");
   oInstance.addItem("http://www.ebook.com/java/网络编程006.zip","./网络编程6.zip");
   oInstance.addItem("http://www.ebook.com/java/网络编程007.zip","./网络编程7.zip");
   //开始下载
   oInstance.downLoadByList();
  }
  catch (Exception err) {
   System.out.println(err.getMessage());
  }
}
}



[广告] 金秋最关注楼盘-房不胜房

2008年11月17日星期一

java里 equals和== 区别

equals 只是比较值是否相同
而==则是比较两个变量 是不是同一个变量,也应时是说
要看看这两个变量是不是引用的同一个地址,
java 中只有引用地址相同的两个变量才被视为==
如果明白值传递与地址传递的话,这个问题应该不难理解
 
举个例子
String s1 = "Hello";
String s2 = "Hello";
if (s1 == s2)
{
System.out.println("s1 = s2");
}

String t1 = new String("Hello");
String t2 = new String("Hello");
if (t1 == t2)
{
System.out.println("t1 = t2");
}

我们知道进行字符串比较需要使用字符串对象String的equals方法。这是
因为操作符 == 进行的是狭义上的比较,而方法equals进行的是广义上的
比较。也就是说,操作符 == 比较的是引用,而方法equals比较的是被引
用的值。用C/C++的术语来说,操作符 == 比较的是指针的值,方法equals
比较的是被指针指向的值。

根据以上认识,我们会认为上述程序片断运行时肯定不会打印s1 = s2,
因为字符串s1和s2是两个不同的String对象,其引用应该是不同的。但是
这样的想法是错误的,因为程序运行时却是打印了s1 = s2。

Java通过重新利用相同的字符串对象从而达到节约系统资源的目的。由于
s1和s2的内容完全相同,因此s1和s2在内存中的地址是完全相同的。正是
因为这样的原因,s1 = s2成立。

那么t1和t2是否象等呢?他们的内容也完全相同。

答案是否定的,因为操作符new强制为t1和t2重新生成新的字符串对象,而
不是重新利用现有的具有相同内容的字符串对象。因此t1和t2在内存中的
地址是不同的,其引用也是不同的。因此,t1 = t2不成立。

2008年11月12日星期三

学java得这样学,学习东西确实也得这样(转载)

软件开发之路是充满荆棘与挑战之路,也是充满希望之路。Java学习也是如此,没有捷径可走。梦想像《天龙八部》中虚竹一样被无崖子醍醐灌顶而轻松获得一 甲子功力,是很不现实的。每天仰天大叫"天神啊,请赐给我一本葵花宝典吧",殊不知即使你获得了葵花宝典,除了受自宫其身之苦外,你也不一定成得了"东方 不败",倒是成"西方失败"的几率高一点。
    "不走弯路,就是捷径",佛经说的不无道理。
    1.如何学习程序设计?
    Java是一种平台,也是一种程序设计语言,如何学好程序设计不仅仅适用于Java,对C++等其他程序设计语言也一样管用。有编程高手认为,Java也 好C也好没什么分别,拿来就用。为什么他们能达到如此境界?我想是因为编程语言之间有共通之处,领会了编程的精髓,自然能够做到一通百通。如何学习程序设 计理所当然也有许多共通的地方。
  1.1 培养兴趣
    兴趣是能够让你坚持下去的动力。如果只是把写程序作为谋生的手段的话,你会活的很累,也太对不起自己了。多关心一些行业趣事,多想想盖茨。不是提倡天天做 白日梦,但人要是没有了梦想,你觉得有味道吗?可能像许多深圳本地农民一样,打打麻将,喝喝功夫茶,拜拜财神爷;每个月就有几万十几万甚至更多的进帐,凭 空多出个"食利阶层"。你认为,这样有味道吗?有空多到一些程序员论坛转转,你会发现,他们其实很乐观幽默,时不时会冒出智慧的火花。
    1.2 慎选程序设计语言
    男怕入错行,女怕嫁错郎。初学者选择程序设计语言需要谨慎对待。软件开发不仅仅是掌握一门编程语言了事,它还需要其他很多方面的背景知识。软件开发也不仅仅局限于某几个领域,而是已经渗透到了各行各业几乎每一个角落。
如 果你对硬件比较感兴趣,你可以学习C语言/汇编语言,进入硬件开发领域。如果你对电信的行业知识及网络比较熟悉,你可以在C/C++等之上多花时间,以期 进入电信软件开发领域。如果你对操作系统比较熟悉,你可以学习C/Linux等等,为Linux内核开发/驱动程序开发/嵌入式开发打基础。
如果你想介入到应用范围最广泛的应用软件开发(包括电子商务电子政务系统)的话,你可以选择J2EE或.NET,甚至LAMP组合。每个领域要求的背景知识不一样。做应用软件需要对数据库等很熟悉。总之,你需要根据自己的特点来选择合适你的编程语言。
  1.3 要脚踏实地,快餐式的学习不可取
  先分享一个故事。 
  有一个小朋友,他很喜欢研究生物学,很想知道那些蝴蝶如何从蛹壳里出来,变成蝴蝶便会飞。有一次,他走到草原上面看见一个蛹,便取了回家,然后看着,过了 几天以后,这个蛹出了一条裂痕,看见里面的蝴蝶开始挣扎,想抓破蛹壳飞出来。这个过程达数小时之久,蝴蝶在蛹里面很辛苦地拼命挣扎,怎么也没法子走出来。 这个小孩看着看着不忍心,就想不如让我帮帮它吧,便随手拿起剪刀在蛹上剪开,使蝴蝶破蛹而出。 但蝴蝶出来以后,因为翅膀不够力,变得很臃肿,飞不起来。
    这个故事给我们的启示是:欲速则不达。
    浮躁是现代人最普遍的心态,能怪谁?也许是贫穷落后了这么多年的缘故,就像当年的大跃进一样,都想大步跨入***主义社会。现在的软件公司、客户、政府、 学校、培训机构等等到处弥漫着浮躁之气。就拿我比较熟悉的大连大工IT职业培训来说吧,居然打广告宣称"20多年的计算机职业教育,辽宁省十佳学校",殊 不知中国计算机发展才几年,软件发展才几年,居然去报名的学生不少,简直是藐视天下程序员。培训出来的"程序员"大多不知道OO,OP为何物?社会环境如 是,我们不能改变,只能改变自己,闹市中的安宁,弥足珍贵。许多初学者C++/Java没开始学,立马使用VC/JBuilder,会使用 VC/JBuilder开发一个Hello World程序,就忙不迭的向世界宣告,"我会软件开发了",简历上也大言不惭地写上"精通VC/Java"。结果到软件公司面试时要么被三两下打发走 了,要么被驳的体无完肤,无地自容。到处碰壁之后才知道捧起《C++编程思想》《Java编程思想》仔细钻研,早知如此何必当初呀。
"你现在讲究简单方便,你以后的路就长了",好象也是佛经中的劝戒。
  1.4 多实践,快实践 
    彭端淑的《为学一首示子侄》中有穷和尚与富和尚的故事。
  从前,四川边境有两个和尚,一个贫穷,一个有钱。一天,穷和尚对富和尚说:"我打算去南海朝圣,你看怎么样?"富和尚说:"这里离南海有几千里远,你靠什 么去呢?"穷和尚说:"我只要一个水钵,一个饭碗就够了。"富和尚为难地说:"几年前我就打算买条船去南海,可至今没去成,你还是别去吧!" 一年以后,富和尚还在为租赁船只筹钱,穷和尚却已经从南海朝圣回来了。
这个故事可解读为:任何事情,一旦考虑好了,就要马上上路,不要等到准备周 全之后,再去干事情。假如事情准备考虑周全了再上路的话,别人恐怕捷足先登了。软件开发是一门工程学科,注重的就是实践,"君子动口不动手"对软件开发人 员来讲根本就是错误的,他们提倡"动手至上",但别害怕,他们大多温文尔雅,没有暴力倾向,虽然有时候蓬头垢面的一副"比尔盖茨"样。有前辈高人认为,学 习编程的秘诀是:编程、编程、再编程,笔者深表赞同。不仅要多实践,而且要快实践。我们在看书的时候,不要等到你完全理解了才动手敲代码,而是应该在看书 的同时敲代码,程序运行的各种情况可以让你更快更牢固的掌握知识点。
    1.5 多参考程序代码
    程序代码是软件开发最重要的成果之一,其中渗透了程序员的思想与灵魂。许多人被《仙剑奇侠传》中凄美的爱情故事感动,悲剧的结局更有一种缺憾美。为什么要 以悲剧结尾?据说是因为写《仙剑奇侠传》的程序员失恋而安排了这样的结局,他把自己的感觉融入到游戏中,却让众多的仙剑迷扼腕叹息。
    多多参考代码例子,对Java而言有参考文献[4.3],有API类的源代码(JDK安装目录下的src.zip文件),也可以研究一些开源的软件或框架。
  1.6 加强英文阅读能力
    对学习编程来说,不要求英语, 但不能一点不会,。最起码像Java API文档(参考文献[4.4])这些东西还是要能看懂的,连猜带懵都可以;旁边再开启一个"金山词霸"。看多了就会越来越熟练。在学Java的同时学习 英文,一箭双雕多好。另外好多软件需要到英文网站下载,你要能够找到它们,这些是最基本的要求。英语好对你学习有很大的帮助。口语好的话更有机会进入管理 层,进而可以成为剥削程序员的"周扒皮"。
    1.7 万不得已才请教别人
    笔者在Martix与Java论坛的在线辅导系统中解决学生问题时发现,大部分的问题学生稍做思考就可以解决。请教别人之前,你应该先回答如下几个问题。
    你是否在google中搜索了问题的解决办法? 
    你是否查看了Java API文档?
    你是否查找过相关书籍?
    你是否写代码测试过?
    如果回答都是"是"的话,而且还没有找到解决办法,再问别人不迟。要知道独立思考的能力对你很重要。要知道程序员的时间是很宝贵的。
    1.8 多读好书
      书中自有颜如玉。比尔盖茨是一个饱读群书的人。虽然没有读完大学,但九岁的时候比尔盖茨就已经读完了所有的百科全书,所以他精通天文、历史、地理等等各类学科,可以说比尔?茨不仅是当今世界上金钱的首富,而且也可以称得上是知识的巨富。
笔 者在给学生上课的时候经常会给他们推荐书籍,到后来学生实在忍无可忍开始抱怨,"天呐,这么多书到什么时候才能看完了","学软件开发,感觉上了贼船 "。这时候,我的回答一般是,"别着急,什么时候带你们去看看我的书房,到现在每月花在技术书籍上的钱400元,这在软件开发人员之中还只能够算是中等的 ",学生当场晕倒。(注:这一部分学生是刚学软件开发的)

    1.9 使用合适的工具
    工欲善其事必先利其器。软件开发包含各种各样的活动,需求收集分析、建立用例模型、建立分析设计模型、编程实现、调试程序、自动化测试、持续集成等等,没 有工具帮忙可以说是寸步难行。工具可以提高开发效率,使软件的质量更高BUG更少。组合称手的武器。到飞花摘叶皆可伤人的境界就很高了,无招胜有招,手中 无剑心中有剑这样的境界几乎不可企及。
    2.软件开发学习路线 
    两千多年的儒家思想孔孟之道,中庸的思想透入骨髓,既不冒进也不保守并非中庸之道,而是找寻学习软件开发的正确路线与规律。
从软件开发人员的生涯规划来讲,我们可以大致分为三个阶段,软件工程师→软件设计师→架构设计师或项目管理师。不想当元帅的士兵不是好士兵,不想当架构设计师或项目管理师的程序员也不是好的程序员。我们应该努力往上走。让我们先整理一下开发应用软件需要学习的主要技术。
    A.基础理论知识,如操作系统、编译原理、数据结构与算法、计算机原理等,它们并非不重要。如不想成为计算机科学家的话,可以采取"用到的时候再来学"的原则。
    B.一门编程语言,现在基本上都是面向对象的语言,Java/C++/C#等等。如果做WEB开发的话还要学习HTML/JavaScript等等。
    C.一种方法学或者说思想,现在基本都是面向对象思想(OOA/OOD/设计模式)。由此而衍生的基于组件开发CBD/面向方面编程AOP等等。
    D.一种关系型数据库,ORACLE/SqlServer/DB2/MySQL等等
    E.一种提高生产率的IDE集成开发环境JBuilder/Eclipse/VS.NET等。
    F.一种UML建模工具,用ROSE/VISIO/钢笔进行建模。
    G.一种软件过程,RUP/XP/CMM等等,通过软件过程来组织软件开发的众多活动,使开发流程专业化规范化。当然还有其他的一些软件工程知识。
    H.项目管理、体系结构、框架知识。
    正确的路线应该是:B→C→E→F→G→H。
    还需要补充几点:
    1).对于A与C要补充的是,我们应该在实践中逐步领悟编程理论与编程思想。新技术虽然不断涌现,更新速度令人眼花燎乱雾里看花;但万变不离其宗,编程理 论与编程思想的变化却很慢。掌握了编程理论与编程思想你就会有拨云见日之感。面向对象的思想在目前来讲是相当关键的,是强势技术之一,在上面需要多投入时 间,给你的回报也会让你惊喜。
  2).对于数据库来说是独立学习的,这个时机就由你来决定吧。
  3).编程语言作为学习软件开发的主线,而其余的作为辅线。
  4).软件工程师着重于B、C、E、D;软件设计师着重于B、C、E、D、F;架构设计师着重于C、F、H。
  3.如何学习Java?
  3.1 Java学习路线
      3.1.1 基础语法及Java原理
    基础语法和Java原理是地基,地基不牢靠,犹如沙地上建摩天大厦,是相当危险的。学习Java也是如此,必须要有扎实的基础,你才能在J2EE、 J2ME领域游刃有余。参加SCJP(SUN公司认证的Java程序员)考试不失为一个好方法,原因之一是为了对得起你交的1200大洋考试费,你会更努 力学习,原因之二是SCJP考试能够让你把基础打得很牢靠,它要求你跟JDK一样熟悉Java基础知识;但是你千万不要认为考过了SCJP就有多了不起, 就能够获得软件公司的青睐,就能够获取高薪,这样的想法也是很危险的。获得"真正"的SCJP只能证明你的基础还过得去,但离实际开发还有很长的一段路要 走。
      3.1.2 OO思想的领悟 
  掌握了基础语法和Java程序运行原理后,我们就可以用Java语言实现面向对象的思想了。面向对象,是一种方法学;是独立于语言之外的编程思想;是 CBD基于组件开发的基础;属于强势技术之一。当以后因工作需要转到别的面向对象语言的时候,你会感到特别的熟悉亲切,学起来像喝凉水这么简单。
使用面向对象的思想进行开发的基本过程是:
    ●调查收集需求。
    ●建立用例模型。
    ●从用例模型中识别分析类及类与类之间的静态动态关系,从而建立分析模型。
    ●细化分析模型到设计模型。
    ●用具体的技术去实现。
    ●测试、部署、总结。
    3.1.3 基本API的学习
    进行软件开发的时候,并不是什么功能都需要我们去实现,也就是经典名言所说的"不需要重新发明轮子"。我们可以利用现成的类、组件、框架来搭建我们的应 用,如SUN公司编写好了众多类实现一些底层功能,以及我们下载过来的JAR文件中包含的类,我们可以调用类中的方法来完成某些功能或继承它。那么这些类 中究竟提供了哪些方法给我们使用?方法的参数个数及类型是?类的构造器需不需要参数?总不可能SUN公司的工程师打国际长途甚至飘洋过海来告诉你他编写的 类该如何使用吧。他们只能提供文档给我们查看,Java DOC文档(参考文献4.4)就是这样的文档,它可以说是程序员与程序员交流的文档。
    基本API指的是实现了一些底层功能的类,通用性较强的API,如字符串处理/输入输出等等。我们又把它成为类库。熟悉API的方法一是多查Java DOC文档(参考文献4.4),二是使用JBuilder/Eclipse等IDE的代码提示功能。
    3.1.4 特定API的学习
    Java介入的领域很广泛,不同的领域有不同的API,没有人熟悉所有的API,对一般人而言只是熟悉工作中要用到的API。如果你做界面开发,那么你需 要学习Swing/AWT/SWT等API;如果你进行网络游戏开发,你需要深入了解网络API/多媒体API/2D3D等;如果你做WEB开发,就需要 熟悉Servlet等API啦。总之,需要根据工作的需要或你的兴趣发展方向去选择学习特定的API。
    3.1.5 开发工具的用法
    在学习基础语法与基本的面向对象概念时,从锻炼语言熟练程度的角度考虑,我们推荐使用的工具是Editplus/JCreator+JDK,这时候不要急 于上手JBuilder/Eclipse等集成开发环境,以免过于关注IDE的强大功能而分散对Java技术本身的注意力。过了这一阶段你就可以开始熟悉 IDE了。
程序员日常工作包括很多活动,编辑、编译及构建、调试、单元测试、版本控制、维持模型与代码同步、文档的更新等等,几乎每一项活动都有 专门的工具,如果独立使用这些工具的话,你将会很痛苦,你需要在堆满工具的任务栏上不断的切换,效率很低下,也很容易出错。在JBuilder、 Eclipse等IDE中已经自动集成编辑器、编译器、调试器、单元测试工具JUnit、自动构建工具ANT、版本控制工具CVS、DOC文档生成与更新 等等,甚至可以把UML建模工具也集成进去,又提供了丰富的向导帮助生成框架代码,让我们的开发变得更轻松。应该说IDE发展的趋势就是集成软件开发中要 用到的几乎所有工具。
    从开发效率的角度考虑,使用IDE是必经之路,也是从一个学生到一个职业程序员转变的里程碑。
    Java开发使用的IDE主要有Eclipse、JBuilder、JDeveloper、NetBeans等几种;而Eclipse、JBuilder 占有的市场份额是最大的。JBuilder在近几年来一直是Java集成开发环境中的霸主,它是由备受程序员尊敬的Borland公司开发,在硝烟弥漫的 Java IDE大战中,以其快速的版本更新击败IBM的Visual Age for Java等而成就一番伟业。IBM在Visual Age for Java上已经无利可图之下,干脆将之贡献给开源社区,成为Eclipse的前身,真所谓"柳暗花明又一村"。浴火重生的Eclipse以其开放式的插件 扩展机制、免费开源获得广大程序员(包括几乎所有的骨灰级程序员)的青睐,极具发展潜力。
    3.1.6 学习软件工程
    对小型项目而言,你可能认为软件工程没太大的必要。随着项目的复杂性越来越高,软件工程的必要性才会体现出来。参见"软件开发学习路线"小节。
    3.2学习要点
    确立的学习路线之后,我们还需要总结一下Java的学习要点,这些要点在前文多多少少提到过,只是笔者觉得这些地方特别要注意才对它们进行汇总,不要嫌我婆婆妈妈啊。
    3.2.1勤查API文档
    当程序员编写好某些类,觉得很有成就感,想把它贡献给各位苦难的同行。这时候你要使用"Javadoc"工具(包含在JDK中)生成标准的Java DOC文档,供同行使用。J2SE/J2EE/J2ME的DOC文档是程序员与程序员交流的工具,几乎人手一份,除了菜鸟之外。J2SE DOC文档官方下载地址:http://Java.sun.com/j2se/1.5.0/download.jsp,你可以到google搜索CHM版本下载。也可以在线查看:http://Java.sun.com/j2se/1.5.0/docs/api/index.html
    对待DOC文档要像毛主席语录,早上起床念一遍,吃饭睡觉前念一遍。
    当需要某项功能的时候,你应该先查相应的DOC文档看看有没有现成的实现,有的话就不必劳神费心了直接用就可以了,找不到的时候才考虑自己实现。使用步骤一般如下:
  ●找特定的包,包一般根据功能组织。
  ●找需要使用类,类命名规范的话我们由类的名字可猜出一二。
  ●选择构造器,大多数使用类的方式是创建对象。
  ●选择你需要的方法。
    3.2.2 查书/google->写代码测试->查看源代码->请教别人
  当我们遇到问题的时候该如何解决?
  这时候不要急着问别人,太简单的问题,没经过思考的问题,别人会因此而瞧不起你。可以先找找书,到google中搜一下看看,绝大部分问题基本就解决了。 而像"某些类/方法如何使用的问题",DOC文档就是答案。对某些知识点有疑惑是,写代码测试一下,会给你留下深刻的印象。而有的问题,你可能需要直接看 API的源代码验证你的想法。万不得已才去请教别人。
    3.2.3学习开源软件的设计思想
    Java领域有许多源代码开放的工具、组件、框架,JUnit、ANT、Tomcat、Struts、Spring、Jive论坛、PetStore宠物 店等等多如牛毛。这些可是前辈给我们留下的瑰宝呀。入宝山而空手归,你心甘吗?对这些工具、框架进行分析,领会其中的设计思想,有朝一日说不定你也能写一 个XXX框架什么的,风光一把。分析开源软件其实是你提高技术、提高实战能力的便捷方法。
    3.2.4 规范的重要性 
    没有规矩,不成方圆。这里的规范有两层含义。第一层含义是技术规范,多到http://www.jcp.org下 载JSRXXX规范,多读规范,这是最权威准确最新的教材。第二层含义是编程规范,如果你使用了大量的独特算法,富有个性的变量及方法的命名方式;同时, 没给程序作注释,以显示你的编程功底是多么的深厚。这样的代码别人看起来像天书,要理解谈何容易,更不用说维护了,必然会被无情地扫入垃圾堆。Java编 码规范到此查看或下载http://Java.sun.com/docs/codeconv/,中文的也有,啊,还要问我在哪,请参考3.2.2节。
    3.2.5 不局限于Java
    很不幸,很幸运,要学习的东西还有很多。不幸的是因为要学的东西太多且多变,没时间陪老婆家人或女朋友,导致身心疲惫,严重者甚至导致抑郁症。幸运的是别人要抢你饭碗绝非易事,他们或她们需要付出很多才能达成心愿。
    Java不要孤立地去学习,需要综合学习数据结构、OOP、软件工程、UML、网络编程、数据库技术等知识,用横向纵向的比较联想的方式去学习会更有效。 如学习Java集合的时候找数据结构的书看看;学JDBC的时候复习数据库技术;采取的依然是"需要的时候再学"的原则。
    4.结束语
    需要强调的是,学习软件开发确实有一定的难度,也很辛苦,需要付出很多努力,但千万不要半途而废。本文如果能对一直徘徊在Java神殿之外的朋友有所帮助 的话,笔者也欣慰了。哈哈,怎么听起来老气横秋呀?没办法,在电脑的长期辐射之下,都快变成小老头了。最后奉劝各位程序员尤其是MM程序员,完成工作后赶 快远离电脑,据《胡播乱报》报道,电脑辐射会在白皙的皮肤上面点缀一些小黑点,看起来鲜艳无比…… 拖起明天的梦想还得靠自己!

2008年11月11日星期二

群发短信价格揭秘

一般谈价格三个方式

1. 按照所有号码或号码段,空号、停机号码、假号码都包含在内,这个价格最便宜,也是通常大家说的2分钱一条的;

2.    按照是否发送成功谈价格,这个价格最能蒙人最能忽悠的,一般个人的群发器几乎都显示发送成功。空号、停机号码、假号码都包含在内,都可以显示发送成功,当然价格稍微高点,水分最多,和2分钱一条的没多大区别;

3.    按照最近实时在线号码或空号软件检测的号码发送成功的可能好点,成功率比较高,但是价格相对比较高。关机的刚停机的号码就无法接收到了,特别是节假日休息时间等关机的这个比例更多。关机的刚停机的一样显示成功发送!更关键的是谁来保证是否是最近实时在线号码的真实性和空号检测结果的权威鉴定,现在打停立即换号十分频繁;

4.    按照成功接收数量收费是比较有价值的,这个真实结算价格不会低于6分钱,标准收费是1毛-1毛5。低于结算价格6分的绝对有水分,因为没有哪一个运营商或者代理赔钱赚吆喝!关机又开机、停机又缴费开通的号码都可以在24小时内收到短信。只有在24小时后统计的结果才是真实的!这种原理就是手机上的短消息报告功能,24小时内用户接收到了短信就会发送给主叫号码一个回复,没有接收到就不回复,系统也就不计费。检测时间可以设置1小时或12小时或24小时或48小时。一般个人的群发器或软件都很难做到!

5.目前接收成功率统计:运营商级别的短信群发系统按照全部号码的15-30%是发送成功率,发送成功号码的30-60%是成功接收率!

6.提供成功发送、成功接收统计报告和详细发送明细单,就像手机电话通话详单一样,那才是真实的东西,然后打电话抽查检测是否接收到了,这样不会多花冤枉钱

例如:群发10万号码,每条2分合计是2000元,按照接收成功率也就是2万条,每条6分合计1200元。比较一下可以节省800元,合计每条1分2!哪种方式更省钱大家明白了吧!

以上观点仅供参考!

2008年11月7日星期五

利用迅雷做下载资源站

是框架广告,而前面的方法目前国内最大的资源下载平台,但迅雷本身并没有资源,迅雷提供的是资源其时都来源于网络上的资源站。迅雷与资源站之间是一种双嬴的合作模式,资源站提供资源给迅雷。迅雷为这些资源站带去流量。一个被审核通过的本地资源站,在资源足够多的情况下,一天通过迅雷获取几万个IP的流量是很轻松的事。不过,这种迅雷流量质量都有很差,因为通过迅雷访问这些站的网民其目的的性都很单一,就是为了下载资源,除了下载资源他们什么都不感兴趣。所以,这每天几万的IP无论是投放点击类广,推介类广告或者弹窗广告,效果都很差,基本上没有啥收入。迅雷站,一般都是投放框架广告,每万个IP可以获得100~150元的流量。这些框架广告在用户访问这些站点时,就自动地被安装到用户的电脑中。

除了资源下载站外,有些音乐站像百度音乐频道,里面的资源也均是来源于网络。这些音乐资源站也是通过百度音乐家搜索来获取高流量,同时也给百度音乐带来了资源。

那么如何做迅雷资源站呢?步骤如下。

(1)       在迅雷上随意搜索几个关键词,寻找出一些非大型的资源下载站作为模仿的网站。

(2)         使用论坛程序制作下载站,因为网站简单明了。很容易通过迅雷联盟的审核。

(3)         模仿的网站上有什么资源我们就复制什么资源,可以同时复制两个站的资源。

(4)         主要选择一些RAR文件格式的下载资源站。

(5)       对本站进行适当的宣传,然后提交迅雷联盟。

(6)         通过迅雷联盟审核后,流量就会源源不断地流进这个网站

(7)       在网页里面投放框架广告。

(8)       本站服务器上的RAR资源全部重新解压缩,在压缩文件里面放入广告页快捷链接。

(9)       迅雷资源的盗链是很疯狂的,很快你的站点资源就会被人疯狂地下载。

这个方法与前面介绍的利用小于5M资源做下载站的方法是有区别的。

(1)                  本方法是依赖的是巨的迅雷搜索流量,所以本站资源不是只选择小的,而是选择热门的。

(2)                  迅雷是不允许在RAR文件里投放广告的,所以只能是在通过审核以后悄悄地放入。

(3)                  本方法不仅网页有流量,资源也有下载量,而前面介绍的方法网页上没有流量,但是资源有下载。

(4)                  本方法核心嬴利核心嬴利是靠压缩文件里的广告。

利用盗链每天获取500元

如果认识做电影或下载类资源站的站长,问一下他们最烦恼的事情是什么?他们会回答多数是资源被盗链,导致服务器运行缓慢。盗链是资源类网站站长 最头疼的事情,盗链防不胜防,再好的防盗链技术也会被人破解。所以想做好资源类的下载站,首要问题就是防盗链,解决好这个问题,站上的资源等于是为别人创造的。]

现在做电影或者资源站时,首先想到的也是去盗链他站的资源。网络上大部分下载站,都是盗链他站的资源。一个站如果没有很好的防盗链的技术,普通服务器不用一周就会被盗链网站拖垮。而本身却不能获得任何流量,自己辛苦租了服务器却为他人作嫁衣。于是,网络上就形成了一个恶性循环。与其自己创建本地资源被人盗链,还不如自己也去盗链别人的资源。这样,越来越多的站长放弃了使用自己服务器资源,而盗链别人的资源。

有什么办法可以全理地利用这些疯狂盗链子者的流量呢?下面的方法可以借鉴一下:

(1)       按月租赁服务器,这样费用比较低,一个月几百块钱就可以租赁到VPS

(2)       寻找一些比较热门的下载资源列表,挑选出小于5MB的资源。单介资源越小,被下载的总人数就越多。

(3)       制作一个论坛。论坛的每个帖子是一个下载资源。直接给出资源的目录。

(4)       对每个资源都进行压缩包装,在压缩以前,在文件里面加上自己的广告页快捷链接。命名为"免费电影。html''.

(5)       不断地添加新资源,每个资源都按上一步进行压缩包装。

(6)       这些资源很快就会被别的网站盗链。因为网络上有大量的扫描软件,可以自动扫描资源。

一些-常用软件每天被下载次数要超过10万次,别人一旦盗链。廉洁给帮助你宣传广告页,所以斧广告页每天都会被几万人浏览。一般情况下,一台VPS虚拟服务器每天可以带来到5万个IP 才一分钱左右的收入,5万个IP z约有500元的收入。不过相比VPS服务器一个月租赁费350元来说。还是有的赚的。

这就是利用网络上的盗链行为来嬴利的例子,适全每个朋友操作项目,因为资源永远都不过剩,短时间内网络人也改变不了盗链的习惯,所以这个流量技巧在几年甚至更长时间内仍然有效。当然我们更应该学习这种变害为利的思维模式。再举一个例子。

铁血论坛,是一个著名的论坛,里面的文章大多都是原创的,这些文章会被大量的转载。于是论坛就作了一个设置,当文章被转载时,会自动在文章的段落里加上一句"该文章转铁血论坛,网址是www.tiexue.net".像起点文学网也有类似的设置[ 也是一个利用网络"借用"行为来做宣传的例子。

对于"利用盗链来获得收入"的项目,有些新手看了以后能明白其中的道理,却认为自己做不起来,究其原因是以为自己不懂技术,操作起来难度太大。这是一种错误的思维模式!在网络赚钱过程中,技术是相对次要的环节,自己做不了的事情,要学会借助别人的力量来完成,绝对不能以"自己不懂技术工农个理由而不思进取。网赚行业,很多高手都是不懂技术的,但是他们懂得运营人才来实现自己的想法,就如同卖鸡蛋的人不一定要懂的母鸡是如何下蛋的一样

挂QQ日收入5000元

现在上网的人基本上都有QQ号,QQ号已z经成为上网的必需装备。很多人都用过QQ搜索功能搜索异性朋友,尤其是男性朋友。经常通过QQ搜索功能来查找同城的女性,相对而言,男性QQ每天被女性搜索到的几率不大,因为女性很少主动搜索男性。曾经有一个有趣的统计,一个女性QQ保持在线一天,在约会被20个男性请求加为好友,很明显,在加好友前,这些男性通常会查看一下女号QQ的个人资料。 这点就是我们要加以利用。

如果有100个女性QQ号,QQ号上的地理位置设置为不同的城市,在个性说明里,设置上广告,那么每天就能带来2000多个IP的流量,如果有1000个这样的QQ号,每天就可以带来2万个IP 的流量。如果有10000个这样的QQ 号,每天就可以带来20万个IP 的流量,这些流量如果做短信联盟广告的话,每天20万个IP的流量带来的收入是每天8000元以上。看到这里,有人就会问了。真的会有那么高的收入吗?你到哪儿去弄这么多的QQ号呢?全靠申请不可能吧!

其时,上面所说的这些是2006年下半年一群网赚人真实收入的写照,当时这群人平均每天的收入都在2000元以上,高的甚至达到每天上万元。他们都是去淘宝上购买QQ号,便宜的1000QQ号大约15元。贵的也有一元每个QQ号。一台机器使用NOOPENQQ或者TENYQQ可以挂约1500QQ,同时在网吧里挂着。只要把这些QQ资料修改为女性。同时在个人资料中加上广告地址,再用软件把这些QQ挂起来保持在线。能够被人查找到,后面就不需要管什么了。只需要坐在家里数数钱就行了。

曾经在QQ上搜索过女性的朋友。过去肯定经常搜索到一些在个人资料里面带有广告网址的QQ其时这些都是广告QQ。据推测。平均每3个在线的女性QQ中就有一个是广告QQ,可见在当时挂QQ是多么的疯狂。当然,这已经是一个过时的技巧了,因为腾讯推出了新的政策,限制了一个IP地址登陆QQ的个数。同时还改变了查找结果中QQ出现的规则,所以使用这种方法获取流量的难度也越来越大了。

我们要了解这种方法的原理,以方便应用在其它地方。因为人们在网络上并不非全聚集在QQ上,其他有流量的软件或者网站,也应该是可以采取这个原理来获取流量。仔细分析一下可以看出。其原理就是简单地利用搜索源的方式来获取流量,也就是说,人们平时喜欢搜索什么,那么就通过人海战术去创造数量庞大的目标等待搜索,从而产生流量。在网络上,男性搜索女性的频率是最高的。下面延伸几个实例:

(1)              在一些异性交友论坛里面,一般都是男性发很多交友信息,女性是很少发交友信息的。但有个人发了一个帖子,标题是"本人找寻男性朋友交流,有兴趣的进",帖子内容是"本人32岁,自己拥有一家公司,寻找长期上网的的男性朋友交流,本人QQ号是XXXXXXX,有兴趣的朋友可以跟帖留下你的QQ号,因为有人不停的跟帖,所以这个帖子一直排在第一页第一名。通过这种方式也就获取了很高的流量。在一个比较火热的异性交友论坛,一个类似的帖子一天就可以带来1000IP以上的流量,而且都是高质量的IP ,做短信注册类或者'亚交'类广告,也可以带来百多块钱的收入,

(2)              在百度空间里也有一个查询系统,可以查询当地女性朋友的百度空间,于是就有人做了大量的当地女性资料的百度空间,然后在空间资料里面投放上广告,等待百度空间的用户主动过来搜索,这个方法也可以获取大量的流量,

在前面几节里提到的利用交友中心做流量的技巧,其实本质上也是创造搜索源来等待被查找而获取流量。

技巧总结:根据网络用户的搜索习惯,创造其需要的众多搜索目标以获取流量。这个方法适合于任何一个具有查询系统或者搜索功能的软件或者网站,

再延伸两面三刀个例子:

(1)              在网上,经常会遇到一些招商者的手机号或者是联系电话等,有些网民会习惯性地搜索一下。看看招商者在网络上发布过什么信息,他在网络上是干什么的。别人对他的评价如何;有时接到一些陌生电话,我们也会想搜索一下这个电话是哪里的;有时我我们还会把一些手机号码在搜索引擎里输入一下,想看看这个号码的归属地。但是,手机是属于个人隐私性的东西,一般在网络上搜索不出结果,可手机号码每天搜索量还是巨大的。假如我们做一个站。把每个手机号码都产生一个页面,当这个站收录的时候,无论搜索什么手机号码时,这个站都被搜索出来的。于是大家就会习惯性地点开看一下,这就会带来的流量。这也是一种创造搜索 源的例子,有兴趣的朋友可以把这个站操作起来。

(2)              我们出行的时候,可能会查询一下出发地到目的地之间的路线。比如,笔者想开车从日照到拉萨,就会在网上搜索一下这两个地名,可是搜索像日照到拉萨这类信息,往往没有搜索结果。因为一些非热门城市之间的交通线路很少有人去关注。那么我们就可以把国内的任意两个城市进行组合,每组合一次产生一个网页。这样无论搜索搜索两个城市之间的线路时,这个站都会出现在第一位。因为除了这个站网络上没有别的搜索结果,这样该站也可以获取大量的流量。可以做成自驾游系列的网站。当然,把全国所有城市都组合进来。信息可能过于庞大,可以再作一次筛选。

做网络,掌握一些基本的技巧是有必要的。但更重要的是学会并掌握里面成功的思维模式,只有这样自己才能够灵活运用。得心应手地去驾驭网络。