<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    Raymond
    Java筆記

    2005年12月22日

    在Java高效編程里面看到變量一個(gè)ArrayList的時(shí)候,有兩種方式:
    假設(shè)a是個(gè)ArrayList

    1、 for (int i=0;i<a.size();i++) {
    2、 for (int i=0,n=a.size();i<n;i++) {

    帶著點(diǎn)懷疑我做了一下試驗(yàn),的確是方法2快一點(diǎn)的,估計(jì)是a.size()方法里面花費(fèi)了一點(diǎn)多余的時(shí)間。后來我想到j(luò)dk 1.5開始還有一種遍歷的for/each方法,我做了一下比較,結(jié)果有點(diǎn)驚訝。

    源程序如下

     1import java.util.ArrayList;
     2
     3public class ProfileArrayList {
     4
     5  public static void main(String[] args) {
     6    ArrayList<String> s=new ArrayList<String>();
     7    for (int i=0;i<15000;i++{
     8      s.add(""+System.currentTimeMillis());
     9    }

    10    System.out.println("Start ");
    11    testOne(s);
    12    testTwo(s);
    13    testThree(s);
    14    System.out.println("End ");
    15  }

    16  
    17  private static void testOne(ArrayList<String> a) {
    18    int j=0;String s=null;
    19    for (int i=0;i<a.size();i++{
    20      s=a.get(i);
    21      j++;
    22    }

    23  }

    24  
    25private static void testTwo(ArrayList<String> a) {
    26    int j=0;
    27    String s=null;
    28    for (int i=0,n=a.size();i<n;i++{
    29      s=a.get(i);
    30      j++;
    31    }

    32  }

    33
    34private static void testThree(ArrayList<String> a) {
    35  int j=0;
    36  for (String s : a) {
    37    j++;
    38  }

    39}

    40
    41}

    42

    通過Profiling工具看結(jié)果:
    方法      運(yùn)行時(shí)間
    testOne   0.055764
    testTwo  0.043821
    testThres 0.132451

    也就是說,jdk 1.5的for/each循環(huán)是最慢的。有點(diǎn)不相信。開頭覺得是因?yàn)橘x值造成的,但后來在另兩個(gè)方法里面加上賦值語(yǔ)句,依然是for/each最慢。比較有趣的結(jié)果。

    從代碼清晰角度,用for/each消耗多一點(diǎn)點(diǎn)時(shí)間似乎也無所謂。但是,另兩種代碼也不見得“不清晰”,呵呵??粗k了。

    posted @ 2006-03-03 12:00 Raymond的Java筆記 閱讀(497) | 評(píng)論 (0)編輯 收藏
     

    JMeter是apache的jakarta上面的項(xiàng)目,用于軟件的壓力測(cè)試(Load Test),不但可以對(duì)HTTP,也可以對(duì)數(shù)據(jù)庫(kù)(通過JDBC)、FTP、Web Service、Java 對(duì)象等等進(jìn)行壓力測(cè)試。

    項(xiàng)目地址:http://jakarta.apache.org/jmeter

    使用: 運(yùn)行bin目錄下的jmeterw.bat,運(yùn)行jmeter.bat也可以,不過就會(huì)有一個(gè)命令窗口顯示。

    要提醒一下的是jmeter根據(jù)當(dāng)前系統(tǒng)的locale顯示菜單的語(yǔ)言,為了方便想設(shè)置回英文的話,可以修改jmeter.properties文件,設(shè)置language=en  (我下載的2.1.1版本把“退出”誤譯為“推出”,怎么看都不順眼

    使用:

    JMeter的測(cè)試計(jì)劃(Test Plan)呈樹狀結(jié)構(gòu),樹里面有多種元素類型,樹狀結(jié)構(gòu)的元素之間有的是有繼承關(guān)系的(其原理有點(diǎn)類似log4j)。下面簡(jiǎn)述一下元素類型:

    1、ThreadGroup
          顧名思義就是線程組,測(cè)試必須有一個(gè)ThreadGroup元素作為基礎(chǔ)(否則就沒有測(cè)試線程在跑了),這個(gè)元素可以配置跑多少個(gè)線程、每個(gè)線程循環(huán)多少次,所有線程數(shù)的總啟動(dòng)時(shí)間(Ramp-up period)等等。

    2、Controller
         包括Logical Controller和Sampler,前者用來作一些邏輯上的控制,例如輪換、條件、循環(huán)等等。Sampler就是真正“干活”的“取樣器”,例如“HTTP Request”,就是拿來執(zhí)行一個(gè)HTTP請(qǐng)求的。

    3、Listener
        Listener對(duì)請(qǐng)求過程進(jìn)行監(jiān)聽,可以簡(jiǎn)單理解為獲取結(jié)果的東東。例如Simple Data Writer,可以把結(jié)果寫到一個(gè)文本文件里(其實(shí)所有Listener都可以寫數(shù)據(jù)到文件里),還有View Results in Table,就是把結(jié)果顯示在表格里。

    4、 Timer
        用來控制執(zhí)行流程中的時(shí)間延遲等功能。

    5、 Assertion
        斷言,加到Sampler里面可以對(duì)返回的結(jié)果進(jìn)行判斷,例如判斷HTTP返回結(jié)果里面是否含有某個(gè)字符串。如果斷言為真,JMeter會(huì)標(biāo)記請(qǐng)求為成功,否則標(biāo)記為失敗。

    6、 Configuration Element
       
    配置用的元素,很有用。由于測(cè)試計(jì)劃是樹狀和有繼承關(guān)系的,可以在高層次指定一個(gè)Configuration Element,低層次的相關(guān)Sampler如果沒有顯式地指定配置,就繼承高層次的配置信息。(跟log4j很像吧?)

    7、 Pre-Processor/Post-Processor Elements
       用來在Sampler運(yùn)行前和運(yùn)行后作一些預(yù)處理和后處理工作的。例如動(dòng)態(tài)修改請(qǐng)求的參數(shù)(預(yù)處理),從返回信息里面提取信息(后處理)等等。

    舉例:要做一個(gè)最簡(jiǎn)單的HTTP壓力測(cè)試: 用10個(gè)線程訪問一個(gè)URL,每個(gè)線程訪問100次。
    做法:
    1、 在Test Plan下面加一個(gè)Thread Group,配置里面,線程數(shù)填10,循環(huán)次數(shù)填100
    2、 在Thread Group下面加一個(gè)HTTP Request,這是一個(gè)Sampler,在它的配置里面填寫主機(jī)信息,端口、協(xié)議、路徑、參數(shù)等信息
    3、 在HTTP Request下面加一個(gè)View Results in Table,如果你想把記錄記到文件,則填寫文件路徑。
    4、 保存一些這個(gè)Test Plan,就可以選擇Run菜單下面的Run來運(yùn)行了。直到Run菜單項(xiàng)從灰色變回黑色,就表示運(yùn)行完了。在View Results in Table下面,你可以看到運(yùn)行結(jié)果。

    關(guān)于元素的詳細(xì)描述可以參考官方文檔

    JMeter功能很豐富的,還有很強(qiáng)的擴(kuò)展能力,而且又是免費(fèi),值得研究使用。
    posted @ 2006-03-01 10:04 Raymond的Java筆記 閱讀(1570) | 評(píng)論 (0)編輯 收藏
     

    本文只作很簡(jiǎn)要介紹,可視作備忘參考。

    TPTP是eclipse官方的profiling插件,初步使用下感覺功能強(qiáng)大。

    下載安裝: 在http://www.eclipse.org/tptp/下載,我選擇All-Runtime,然后像其它插件一樣解壓到eclipse的目錄,然后允許eclipse -clean來刷新一把。

    使用: 
       常用的profiling簡(jiǎn)單來講就對(duì)程序運(yùn)行進(jìn)行記錄,然后從數(shù)據(jù)中分析哪些方法運(yùn)行時(shí)間長(zhǎng),哪些對(duì)象吃內(nèi)存多,哪些類的實(shí)例多等等。一個(gè)比較好的使用入門sample在這里: http://www.eclipse.org/tptp/home/documents/tutorials/profilingtool/profilingexample_32.html 我就不羅嗦了。

    值得多講的是Remote Profiling,就是遠(yuǎn)程剖析。實(shí)現(xiàn)的原理是在遠(yuǎn)程機(jī)器上運(yùn)行一個(gè)代理進(jìn)程,要被遠(yuǎn)程剖析的程序或者Application Server啟動(dòng)的時(shí)候加一個(gè)JVM參數(shù)來識(shí)別這個(gè)代理進(jìn)程,兩者相互作用,代理就可以把收集到的信息發(fā)給在遠(yuǎn)程的一方(就是運(yùn)行著eclipse的一方)。

    因此要實(shí)現(xiàn)Remote Profiling,還要在目標(biāo)機(jī)器上裝一個(gè)agent。 -->

    下載安裝:http://www.eclipse.org/tptp/home/downloads/drops/TPTP-4.0.1.html 選擇對(duì)應(yīng)操作系統(tǒng)的Agent Controller下載,選擇Runtime即可。

    下載后,閱讀依照getting_started.html的說明來安裝即可,這里簡(jiǎn)述一下:
    1、 把它的bin目錄放到PATH里面
    2、 運(yùn)行一下SetConfig來設(shè)置參數(shù),注意如果想讓除本地localhost意外所以機(jī)器都訪問的話,要注意設(shè)置Network Access Mode,默認(rèn)是localhost的。
    3、 運(yùn)行RAStart來啟動(dòng)代理(Linux下)
    4、 服務(wù)器端程序(例如tomcat)啟動(dòng)的JVM參數(shù)里面加入-XrunpiAgent:server=enabled即可(還有其它參數(shù)值參見文檔)
    5、 然后就可以在遠(yuǎn)程用eclipse來啟動(dòng)一個(gè)Profiling進(jìn)程來attach到這個(gè)agent controller了。效果和在eclipse里面直接profile應(yīng)用程序一樣。

    posted @ 2006-02-27 14:14 Raymond的Java筆記 閱讀(5634) | 評(píng)論 (2)編輯 收藏
     

    Volatile Fields

    Sometimes, it seems excessive to pay the cost of synchronization just to read or write an instance field or two. After all, what can go wrong? Unfortunately, with modern processors and compilers, there is plenty of room for error:

    • Computers with multiple processors can temporarily hold memory values in registers or local memory caches. As a consequence, threads running in different processors may see different values for the same memory location!

    • Compilers can reorder instructions for maximum throughput. Compilers won't choose an ordering that changes the meaning of the code, but they make the assumption that memory values are only changed when there are explicit instructions in the code. However, a memory value can be changed by another thread!

    If you use locks to protect code that can be accessed by multiple threads, then you won't have these problems. Compilers are required to respect locks by flushing local caches as necessary and not inappropriately reordering instructions. The details are explained in the Java Memory Model and Thread Specification developed by JSR 133 (see http://www.jcp.org/en/jsr/detail?id=133). Much of the specification is highly complex and technical, but the document also contains a number of clearly explained examples. A more accessible overview article by Brian Goetz is available at http://www-106.ibm.com/developerworks/java/library/j-jtp02244.html.

    NOTE

    Brian Goetz coined the following "synchronization motto": "If you write a variable which may next be read by another thread, or you read a variable which may have last been written by another thread, you must use synchronization."


    The volatile keyword offers a lock-free mechanism for synchronizing access to an instance field. If you declare a field as volatile, then the compiler and the virtual machine take into account that the field may be concurrently updated by another thread.

    For example, suppose an object has a boolean flag done that is set by one thread and queried by another thread. You have two choices:

    1. Use a lock, for example:

      public synchronized boolean isDone() { return done; }
      private boolean done;
      

      (This approach has a potential drawback: the isDone method can block if another thread has locked the object.)

    2. Declare the field as volatile:

      public boolean isDone() { return done; }
      private volatile boolean done;
      

    Of course, accessing a volatile variable will be slower than accessing a regular variablethat is the price to pay for thread safety.

    NOTE

    Prior to JDK 5.0, the semantics of volatile were rather permissive. The language designers attempted to give implementors leeway in optimizing the performance of code that uses volatile fields. However, the old specification was so complex that implementors didn't always follow it, and it allowed confusing and undesirable behavior, such as immutable objects that weren't truly immutable.


    In summary, concurrent access to a field is safe in these three conditions:

    • The field is volatile.

    • The field is final, and it is accessed after the constructor has completed.

    • The field access is protected by a lock.

    posted @ 2006-02-19 15:58 Raymond的Java筆記 閱讀(380) | 評(píng)論 (0)編輯 收藏
     

    The Joel Test: 12 Steps to Better Code


    By Joel Spolsky
    Wednesday, August 09, 2000
    Printer Friendly Version

    Have you ever heard of SEMA? It's a fairly esoteric system for measuring how good a software team is. No, wait! Don't follow that link! It will take you about six years just to understand that stuff. So I've come up with my own, highly irresponsible, sloppy test to rate the quality of a software team. The great part about it is that it takes about 3 minutes. With all the time you save, you can go to medical school.

    The Joel Test

    1. Do you use source control?
    2. Can you make a build in one step?
    3. Do you make daily builds?
    4. Do you have a bug database?
    5. Do you fix bugs before writing new code?
    6. Do you have an up-to-date schedule?
    7. Do you have a spec?
    8. Do programmers have quiet working conditions?
    9. Do you use the best tools money can buy?
    10. Do you have testers?
    11. Do new candidates write code during their interview?
    12. Do you do hallway usability testing?

    The neat thing about The Joel Test is that it's easy to get a quick yes or no to each question. You don't have to figure out lines-of-code-per-day or average-bugs-per-inflection-point. Give your team 1 point for each "yes" answer. The bummer about The Joel Test is that you really shouldn't use it to make sure that your nuclear power plant software is safe.

    A score of 12 is perfect, 11 is tolerable, but 10 or lower and you've got serious problems. The truth is that most software organizations are running with a score of 2 or 3, and they need serious help, because companies like Microsoft run at 12 full-time. 

    Of course, these are not the only factors that determine success or failure: in particular, if you have a great software team working on a product that nobody wants, well, people aren't going to want it. And it's possible to imagine a team of "gunslingers" that doesn't do any of this stuff that still manages to produce incredible software that changes the world. But, all else being equal, if you get these 12 things right, you'll have a disciplined team that can consistently deliver.

    1. Do you use source control?
    I've used commercial source control packages, and I've used CVS, which is free, and let me tell you, CVS is fine. But if you don't have source control, you're going to stress out trying to get programmers to work together. Programmers have no way to know what other people did. Mistakes can't be rolled back easily. The other neat thing about source control systems is that the source code itself is checked out on every programmer's hard drive -- I've never heard of a project using source control that lost a lot of code.

    2. Can you make a build in one step?
    By this I mean: how many steps does it take to make a shipping build from the latest source snapshot? On good teams, there's a single script you can run that does a full checkout from scratch, rebuilds every line of code, makes the EXEs, in all their various versions, languages, and #ifdef combinations, creates the installation package, and creates the final media -- CDROM layout, download website, whatever.

    If the process takes any more than one step, it is prone to errors. And when you get closer to shipping, you want to have a very fast cycle of fixing the "last" bug, making the final EXEs, etc. If it takes 20 steps to compile the code, run the installation builder, etc., you're going to go crazy and you're going to make silly mistakes.

    For this very reason, the last company I worked at switched from WISE to InstallShield: we required that the installation process be able to run, from a script, automatically, overnight, using the NT scheduler, and WISE couldn't run from the scheduler overnight, so we threw it out. (The kind folks at WISE assure me that their latest version does support nightly builds.)

    3. Do you make daily builds?
    When you're using source control, sometimes one programmer accidentally checks in something that breaks the build. For example, they've added a new source file, and everything compiles fine on their machine, but they forgot to add the source file to the code repository. So they lock their machine and go home, oblivious and happy. But nobody else can work, so they have to go home too, unhappy.

    Breaking the build is so bad (and so common) that it helps to make daily builds, to insure that no breakage goes unnoticed. On large teams, one good way to insure that breakages are fixed right away is to do the daily build every afternoon at, say, lunchtime. Everyone does as many checkins as possible before lunch. When they come back, the build is done. If it worked, great! Everybody checks out the latest version of the source and goes on working. If the build failed, you fix it, but everybody can keep on working with the pre-build, unbroken version of the source.

    On the Excel team we had a rule that whoever broke the build, as their "punishment", was responsible for babysitting the builds until someone else broke it. This was a good incentive not to break the build, and a good way to rotate everyone through the build process so that everyone learned how it worked. 

    Read more about daily builds in my article Daily Builds are Your Friend.

    4. Do you have a bug database?
    I don't care what you say. If you are developing code, even on a team of one, without an organized database listing all known bugs in the code, you are going to ship low quality code. Lots of programmers think they can hold the bug list in their heads. Nonsense. I can't remember more than two or three bugs at a time, and the next morning, or in the rush of shipping, they are forgotten. You absolutely have to keep track of bugs formally.

    Bug databases can be complicated or simple. A minimal useful bug database must include the following data for every bug:

    • complete steps to reproduce the bug
    • expected behavior
    • observed (buggy) behavior
    • who it's assigned to
    • whether it has been fixed or not

    If the complexity of bug tracking software is the only thing stopping you from tracking your bugs, just make a simple 5 column table with these crucial fields and start using it.

    For more on bug tracking, read Painless Bug Tracking.

    5. Do you fix bugs before writing new code?
    The very first version of Microsoft Word for Windows was considered a "death march" project. It took forever. It kept slipping. The whole team was working ridiculous hours, the project was delayed again, and again, and again, and the stress was incredible. When the dang thing finally shipped, years late, Microsoft sent the whole team off to Cancun for a vacation, then sat down for some serious soul-searching.

    What they realized was that the project managers had been so insistent on keeping to the "schedule" that programmers simply rushed through the coding process, writing extremely bad code, because the bug fixing phase was not a part of the formal schedule. There was no attempt to keep the bug-count down. Quite the opposite. The story goes that one programmer, who had to write the code to calculate the height of a line of text, simply wrote "return 12;" and waited for the bug report to come in about how his function is not always correct. The schedule was merely a checklist of features waiting to be turned into bugs. In the post-mortem, this was referred to as "infinite defects methodology".

    To correct the problem, Microsoft universally adopted something called a "zero defects methodology". Many of the programmers in the company giggled, since it sounded like management thought they could reduce the bug count by executive fiat. Actually, "zero defects" meant that at any given time, the highest priority is to eliminate bugs before writing any new code. Here's why. 

    In general, the longer you wait before fixing a bug, the costlier (in time and money) it is to fix.

    For example, when you make a typo or syntax error that the compiler catches, fixing it is basically trivial.

    When you have a bug in your code that you see the first time you try to run it, you will be able to fix it in no time at all, because all the code is still fresh in your mind.

    If you find a bug in some code that you wrote a few days ago, it will take you a while to hunt it down, but when you reread the code you wrote, you'll remember everything and you'll be able to fix the bug in a reasonable amount of time.

    But if you find a bug in code that you wrote a few months ago, you'll probably have forgotten a lot of things about that code, and it's much harder to fix. By that time you may be fixing somebody else's code, and they may be in Aruba on vacation, in which case, fixing the bug is like science: you have to be slow, methodical, and meticulous, and you can't be sure how long it will take to discover the cure.

    And if you find a bug in code that has already shipped, you're going to incur incredible expense getting it fixed.

    That's one reason to fix bugs right away: because it takes less time. There's another reason, which relates to the fact that it's easier to predict how long it will take to write new code than to fix an existing bug. For example, if I asked you to predict how long it would take to write the code to sort a list, you could give me a pretty good estimate. But if I asked you how to predict how long it would take to fix that bug where your code doesn't work if Internet Explorer 5.5 is installed, you can't even guess, because you don't know (by definition) what's causing the bug. It could take 3 days to track it down, or it could take 2 minutes.

    What this means is that if you have a schedule with a lot of bugs remaining to be fixed, the schedule is unreliable. But if you've fixed all the known bugs, and all that's left is new code, then your schedule will be stunningly more accurate.

    Another great thing about keeping the bug count at zero is that you can respond much faster to competition. Some programmers think of this as keeping the product ready to ship at all times. Then if your competitor introduces a killer new feature that is stealing your customers, you can implement just that feature and ship on the spot, without having to fix a large number of accumulated bugs.

    6. Do you have an up-to-date schedule?
    Which brings us to schedules. If your code is at all important to the business, there are lots of reasons why it's important to the business to know when the code is going to be done. Programmers are notoriously crabby about making schedules. "It will be done when it's done!" they scream at the business people.

    Unfortunately, that just doesn't cut it. There are too many planning decisions that the business needs to make well in advance of shipping the code: demos, trade shows, advertising, etc. And the only way to do this is to have a schedule, and to keep it up to date.

    The other crucial thing about having a schedule is that it forces you to decide what features you are going to do, and then it forces you to pick the least important features and cut them rather than slipping into featuritis (a.k.a. scope creep).

    Keeping schedules does not have to be hard. Read my article Painless Software Schedules, which describes a simple way to make great schedules.

    7. Do you have a spec?
    Writing specs is like flossing: everybody agrees that it's a good thing, but nobody does it. 

    I'm not sure why this is, but it's probably because most programmers hate writing documents. As a result, when teams consisting solely of programmers attack a problem, they prefer to express their solution in code, rather than in documents. They would much rather dive in and write code than produce a spec first.

    At the design stage, when you discover problems, you can fix them easily by editing a few lines of text. Once the code is written, the cost of fixing problems is dramatically higher, both emotionally (people hate to throw away code) and in terms of time, so there's resistance to actually fixing the problems. Software that wasn't built from a spec usually winds up badly designed and the schedule gets out of control.  This seems to have been the problem at Netscape, where the first four versions grew into such a mess that management stupidly decided to throw out the code and start over. And then they made this mistake all over again with Mozilla, creating a monster that spun out of control and took several years to get to alpha stage.

    My pet theory is that this problem can be fixed by teaching programmers to be less reluctant writers by sending them off to take an intensive course in writing. Another solution is to hire smart program managers who produce the written spec. In either case, you should enforce the simple rule "no code without spec".

    Learn all about writing specs by reading my 4-part series.

    8. Do programmers have quiet working conditions?
    There are extensively documented productivity gains provided by giving knowledge workers space, quiet, and privacy. The classic software management book Peopleware documents these productivity benefits extensively.

    Here's the trouble. We all know that knowledge workers work best by getting into "flow", also known as being "in the zone", where they are fully concentrated on their work and fully tuned out of their environment. They lose track of time and produce great stuff through absolute concentration. This is when they get all of their productive work done. Writers, programmers, scientists, and even basketball players will tell you about being in the zone.

    The trouble is, getting into "the zone" is not easy. When you try to measure it, it looks like it takes an average of 15 minutes to start working at maximum productivity. Sometimes, if you're tired or have already done a lot of creative work that day, you just can't get into the zone and you spend the rest of your work day fiddling around, reading the web, playing Tetris.

    The other trouble is that it's so easy to get knocked out of the zone. Noise, phone calls, going out for lunch, having to drive 5 minutes to Starbucks for coffee, and interruptions by coworkers -- especially interruptions by coworkers -- all knock you out of the zone. If a coworker asks you a question, causing a 1 minute interruption, but this knocks you out of the zone badly enough that it takes you half an hour to get productive again, your overall productivity is in serious trouble. If you're in a noisy bullpen environment like the type that caffeinated dotcoms love to create, with marketing guys screaming on the phone next to programmers, your productivity will plunge as knowledge workers get interrupted time after time and never get into the zone.

    With programmers, it's especially hard. Productivity depends on being able to juggle a lot of little details in short term memory all at once. Any kind of interruption can cause these details to come crashing down. When you resume work, you can't remember any of the details (like local variable names you were using, or where you were up to in implementing that search algorithm) and you have to keep looking these things up, which slows you down a lot until you get back up to speed.

    Here's the simple algebra. Let's say (as the evidence seems to suggest) that if we interrupt a programmer, even for a minute, we're really blowing away 15 minutes of productivity. For this example, lets put two programmers, Jeff and Mutt, in open cubicles next to each other in a standard Dilbert veal-fattening farm. Mutt can't remember the name of the Unicode version of the strcpy function. He could look it up, which takes 30 seconds, or he could ask Jeff, which takes 15 seconds. Since he's sitting right next to Jeff, he asks Jeff. Jeff gets distracted and loses 15 minutes of productivity (to save Mutt 15 seconds).

    Now let's move them into separate offices with walls and doors. Now when Mutt can't remember the name of that function, he could look it up, which still takes 30 seconds, or he could ask Jeff, which now takes 45 seconds and involves standing up (not an easy task given the average physical fitness of programmers!). So he looks it up. So now Mutt loses 30 seconds of productivity, but we save 15 minutes for Jeff. Ahhh!

    9. Do you use the best tools money can buy?
    Writing code in a compiled language is one of the last things that still can't be done instantly on a garden variety home computer. If your compilation process takes more than a few seconds, getting the latest and greatest computer is going to save you time. If compiling takes even 15 seconds, programmers will get bored while the compiler runs and switch over to reading The Onion, which will suck them in and kill hours of productivity.

    Debugging GUI code with a single monitor system is painful if not impossible. If you're writing GUI code, two monitors will make things much easier.

    Most programmers eventually have to manipulate bitmaps for icons or toolbars, and most programmers don't have a good bitmap editor available. Trying to use Microsoft Paint to manipulate bitmaps is a joke, but that's what most programmers have to do.

    At my last job, the system administrator kept sending me automated spam complaining that I was using more than ... get this ... 220 megabytes of hard drive space on the server. I pointed out that given the price of hard drives these days, the cost of this space was significantly less than the cost of the toilet paper I used. Spending even 10 minutes cleaning up my directory would be a fabulous waste of productivity.

    Top notch development teams don't torture their programmers. Even minor frustrations caused by using underpowered tools add up, making programmers grumpy and unhappy. And a grumpy programmer is an unproductive programmer.

    To add to all this... programmers are easily bribed by giving them the coolest, latest stuff. This is a far cheaper way to get them to work for you than actually paying competitive salaries!

    10. Do you have testers?
    If your team doesn't have dedicated testers, at least one for every two or three programmers, you are either shipping buggy products, or you're wasting money by having $100/hour programmers do work that can be done by $30/hour testers. Skimping on testers is such an outrageous false economy that I'm simply blown away that more people don't recognize it.

    Read Top Five (Wrong) Reasons You Don't Have Testers, an article I wrote about this subject.

    11. Do new candidates write code during their interview?
    Would you hire a magician without asking them to show you some magic tricks? Of course not.

    Would you hire a caterer for your wedding without tasting their food? I doubt it. (Unless it's Aunt Marge, and she would hate you forever if you didn't let her make her "famous" chopped liver cake).

    Yet, every day, programmers are hired on the basis of an impressive resumé or because the interviewer enjoyed chatting with them. Or they are asked trivia questions ("what's the difference between CreateDialog() and DialogBox()?") which could be answered by looking at the documentation. You don't care if they have memorized thousands of trivia about programming, you care if they are able to produce code. Or, even worse, they are asked "AHA!" questions: the kind of questions that seem easy when you know the answer, but if you don't know the answer, they are impossible.

    Please, just stop doing this. Do whatever you want during interviews, but make the candidate write some code. (For more advice, read my Guerrilla Guide to Interviewing.)

    12. Do you do hallway usability testing?
    A hallway usability test is where you grab the next person that passes by in the hallway and force them to try to use the code you just wrote. If you do this to five people, you will learn 95% of what there is to learn about usability problems in your code.

    Good user interface design is not as hard as you would think, and it's crucial if you want customers to love and buy your product. You can read my free online book on UI design, a short primer for programmers.

    But the most important thing about user interfaces is that if you show your program to a handful of people, (in fact, five or six is enough) you will quickly discover the biggest problems people are having. Read Jakob Nielsen's article explaining why. Even if your UI design skills are lacking, as long as you force yourself to do hallway usability tests, which cost nothing, your UI will be much, much better.

    Four Ways To Use The Joel Test

    1. Rate your own software organization, and tell me how it rates, so I can gossip.
    2. If you're the manager of a programming team, use this as a checklist to make sure your team is working as well as possible. When you start rating a 12, you can leave your programmers alone and focus full time on keeping the business people from bothering them.
    3. If you're trying to decide whether to take a programming job, ask your prospective employer how they rate on this test. If it's too low, make sure that you'll have the authority to fix these things. Otherwise you're going to be frustrated and unproductive.
    4. If you're an investor doing due diligence to judge the value of a programming team, or if your software company is considering merging with another, this test can provide a quick rule of thumb.
    posted @ 2006-02-17 22:02 Raymond的Java筆記 閱讀(476) | 評(píng)論 (0)編輯 收藏
     
    需求: 在lucene索引中建立了很多關(guān)鍵字的索引,想獲得一個(gè)當(dāng)前用戶的關(guān)鍵字列表,并且每個(gè)關(guān)鍵字還帶有使用了多少次的信息。

    解決方法:
    使用自定義的HitCollector對(duì)象,代碼如下
    import java.io.IOException;
    import java.util.ArrayList;
    import java.util.Collections;
    import java.util.HashMap;
    import java.util.Iterator;
    import java.util.Set;

    import org.apache.lucene.document.Document;
    import org.apache.lucene.search.HitCollector;
    import org.apache.lucene.search.IndexSearcher;

    public class TagCollector extends HitCollector {
        
    private IndexSearcher searcher;
        
    private HashMap<String,Integer> tagList=new HashMap<String,Integer>();
        
    public TagCollector(IndexSearcher searcher) {
            
    this.searcher=searcher;
        }

        @Override
        
    public void collect(int docID, float score) {
            
    try {
                Document doc
    =searcher.doc(docID);
                String[] tagValues
    =doc.getValues("tag");
                
    if (tagValues!=null{
                    
    for (int i=0;i<tagValues.length;i++{
                        addTagCount(tagValues[i]);
                    }

                }

            }
     catch (IOException e) {
                e.printStackTrace();
            }


        }

        
        
    private void addTagCount(String tagName) {
            
    int count=1;
            
    if (tagList.containsKey(tagName)) {
                count
    =(Integer)tagList.get(tagName)+1;
            }

            tagList.put(tagName,count);
        }

        
        
    public HashMap<String,Integer> getTagList() {
            
    return tagList;
        }

        
        @SuppressWarnings(
    "unchecked")
        
    public ArrayList<TagSummary> getSortedTagList(boolean ascending) {
            ArrayList
    <TagSummary> list=new ArrayList<TagSummary>();
            Iterator keyIterator
    =tagList.keySet().iterator();
            
    while (keyIterator.hasNext()) {
                String key
    =(String)keyIterator.next();
                
    int value=tagList.get(key);
                list.add(
    new TagSummary(key,value));
            }

            Collections.sort(list);
            
    if (!ascending) {
                Collections.reverse(list);
            }

            
    return list;
        }

        

    }

    功能說明: 每個(gè)搜索到的hits,都會(huì)調(diào)用這個(gè)方法的collect方法,因此可以在這個(gè)對(duì)象當(dāng)中放一個(gè)HashMap,累計(jì)記錄每個(gè)關(guān)鍵字得到的次數(shù)。

    排序部分用另外的一個(gè)TagSummary類來獲得,這里就不詳細(xì)給出了。

    問題: 這是一個(gè)直觀的方法,但是相信頻繁調(diào)用這樣的方法會(huì)造成服務(wù)器的嚴(yán)重負(fù)擔(dān)??梢钥紤]一下用緩存的方法,在沒有關(guān)鍵字未曾發(fā)生改變之前,只在第一次調(diào)用這樣的方法,之后把結(jié)果緩存在數(shù)據(jù)表或者內(nèi)存當(dāng)中。有更新的時(shí)候,通過版本號(hào)對(duì)比以決定是否需要更新。
    posted @ 2006-02-04 14:26 Raymond的Java筆記 閱讀(1738) | 評(píng)論 (0)編輯 收藏
     
    問題:
    使用Struts的ActionForm接收到的中文全部是亂碼,例如提交過去的“測(cè)試”字符串,得到的是“??????è????”。開頭以為是傳統(tǒng)的encoding識(shí)別的問題,但是用各種編碼重新構(gòu)造得到的byte[]數(shù)組,依然無法得到正確的中文。但是如果用普通的jsp來接收form的數(shù)據(jù),中文是完全正常的。
    我開始覺得是struts的流程當(dāng)中,錯(cuò)誤地使用了編碼,以至最后得到的結(jié)果完全亂了。搜索了好多文章,總算找到一個(gè)比較接近的。
    解決方法:
    定義一個(gè)filter,filter只做一件事情,就是:
          request.setCharacterEncoding("UTF-8");
    在web.xml的filter mapping里,設(shè)定和struts的action同樣的mapping。

    解釋: Filter最先攔截web請(qǐng)求,在這里設(shè)置了正確的CharacterEncoding,接下來各個(gè)處理的組件就不會(huì)搞錯(cuò)了。在沒有Filter的情況下,我的resin服務(wù)器上獲得的是null,估計(jì)struts不同的處理組件對(duì)null的解釋和處理不太一致,導(dǎo)致錯(cuò)誤的產(chǎn)生。

    要注意我所有頁(yè)面都是UTF-8編碼,所以在filter里面定義了UTF-8,如果是其它的編碼,這里應(yīng)該相應(yīng)改一下。
    posted @ 2006-01-19 23:28 Raymond的Java筆記 閱讀(1070) | 評(píng)論 (0)編輯 收藏
     
    判斷一個(gè)字符是否中文,今天查API找到一個(gè)方法,代碼如下:   


       System.out.println(Character.UnicodeBlock.of('琴'));
       System.out.println(Character.UnicodeBlock.of('j'));
       System.out.println(Character.UnicodeBlock.of(3267));

    運(yùn)行結(jié)果:
    CJK_UNIFIED_IDEOGRAPHS
    BASIC_LATIN
    KANNADA

    其實(shí)不完全夠用,因?yàn)槿绻玫健癈JK_UNIFIED_IDEOGRAPHS”,還可能是日文或者韓文。不過對(duì)我的需求是足夠了。如果要準(zhǔn)確判斷中文,去查一下unicode代碼就可以了。

    posted @ 2006-01-17 12:09 Raymond的Java筆記 閱讀(808) | 評(píng)論 (0)編輯 收藏
     
    function Queue(size) {
     this.size=size;
     this.data=new Array();
     this.add=function(ele) {
      if (this.data.length<this.size) {
       this.data[this.data.length]=ele;
      } else {
       this.data.shift();
       this.data[this.data.length]=ele;
      }
     };
     this.getData=function() {
      return this.data;
     };
     this.toCookieValue=function(delimiter) {
      var result='';
      for (var i=0;i<this.data.length ;i++ )
      {
       if(i==0) {
        result=escape(this.data[i]);
       } else {
        result+=delimiter+escape(this.data[i]);
       }
      }
      return result;
     };
    }
    posted @ 2006-01-16 15:52 Raymond的Java筆記 閱讀(991) | 評(píng)論 (2)編輯 收藏
     
    使用Resin 3.0開發(fā),很奇怪Eclipse在啟動(dòng)了remote debug,然后加斷點(diǎn)的時(shí)候說我的類沒有加行號(hào)。我找遍了選項(xiàng),明明是加了行號(hào)的呀。甚至我在一個(gè)必定會(huì)走過的類前面加個(gè)log打出來,路照走了,居然在console不見log。百思不得其解,快崩潰之前。終于想起了臨時(shí)目錄。

    Resin默認(rèn)總是在WEB-INF下面生成work和tmp目錄,是放jsp編譯而成的類的。我把這兩個(gè)目錄刪除了。一切正常,斷點(diǎn)也可以加了。

    原因: 應(yīng)該是resin在判斷類是否需要重新編譯時(shí)有點(diǎn)問題,對(duì)于我jsp里面有使用到的類發(fā)生變化以后,調(diào)用它的jsp文件沒有重新編譯。導(dǎo)致類文件不更新,連帶就出了一堆古怪的錯(cuò)誤。

    下次記住了,有問題,先刪臨時(shí)目錄!
    posted @ 2006-01-13 16:05 Raymond的Java筆記 閱讀(914) | 評(píng)論 (0)編輯 收藏
     
    初初接觸Tag的,少有不激動(dòng)的。就因?yàn)樗仁煜び帜吧?,既?jiǎn)單又復(fù)雜。乍看之下覺得兩下子能弄一個(gè)Tag系統(tǒng)出來,再想想又覺得深不可測(cè)。可挖掘的東西似乎還有很多很多......

    基于Tag的RSS訂閱 是個(gè)好主意。不過首先的確讓人想到spam。Tag同樣存在信息過載的問題。最原始的提高搜索引擎排名的方法,已經(jīng)太多人用過了:在meta的keyword里面貼一堆無關(guān)的關(guān)鍵字:二手、超女、手機(jī)、新聞、性感、美女、貼圖、援交、筆記本...... 如何保證不在SPAM Blog上面亂貼Tag?

    限制Tag數(shù)量?沒用,辛苦點(diǎn)多copy幾個(gè)副本就完了。

    技術(shù)手段限制?說到底還是成本,技術(shù)手段有高低之分,有成本大小區(qū)別的。除非對(duì)Spam特別不介意的,否則多數(shù)用戶狂熱過一段之后,要看有效信息的,最終還是回到少數(shù)幾個(gè)“權(quán)威”這里。這些“權(quán)威”不是特定個(gè)人就是公司,前者就不是基于Tag了,后者提供的Tag,其實(shí)還是Web 1.0的SP,再加一個(gè)Tag。

    當(dāng)然沒必要為了2.0而2.0,我們關(guān)心如何更有效獲取自己想要的有效信息,盡量過濾無關(guān)信息(尤其是Spam)。

    Tag最大的特點(diǎn),我以為在“交流”二字。自己貼了個(gè)自我感覺良好的傻冒Tag,完了還想看看誰跟我一樣傻... 這個(gè)將成為Tag存在的最重要的意義之一。

    最有機(jī)會(huì)整合Tag功能,也是最需要整合Tag功能的網(wǎng)站,是那些比較重視用戶之間交互的網(wǎng)站,例如BSP、交友圈等等
    posted @ 2006-01-12 21:48 Raymond的Java筆記 閱讀(273) | 評(píng)論 (0)編輯 收藏
     
    由一個(gè)Document對(duì)象,轉(zhuǎn)換成String,這個(gè)方法我?guī)啄昵皩懙牧耍?BR>
                TransformerFactory tFactory = TransformerFactory.newInstance();
                Transformer transformer 
    = tFactory.newTransformer();
                
    DOMSource source = new DOMSource(inputDoc);
                StringWriter out 
    = new StringWriter();
                StreamResult result 
    = new StreamResult(out);
                transformer.transform(source, result);
                out.flush();
                
    return out.toString();

    一直用是沒有問題的,直到今天在resin上面運(yùn)行,發(fā)現(xiàn)一個(gè)奇怪的現(xiàn)象,寫入數(shù)據(jù)庫(kù)的中文都變成了類似&#XXXX; 這種編碼。更加奇怪的是我用應(yīng)用程序的方式運(yùn)行,是正常沒問題的。我猜想是resin在某個(gè)地方做了設(shè)置,在網(wǎng)上搜索又一時(shí)找不到好方法,不想為了一個(gè)小問題轉(zhuǎn)用jdom之類的包。

    研究了一下,找到了解決的辦法。在Transformer對(duì)象創(chuàng)建之后加一句:
       
       
    transformer.setOutputProperty("encoding","GBK");

    問題解決了。具體的機(jī)制還沒有時(shí)間去了解,有空再回頭研究吧。
    posted @ 2006-01-09 17:39 Raymond的Java筆記 閱讀(3904) | 評(píng)論 (1)編輯 收藏
     
    歷來對(duì)framework的感覺是“夠用就可以”的原則。這次想用struts,主要希望jsp里面的邏輯代碼不要太多。但代價(jià)當(dāng)然是Action類會(huì)多起來。完全用Struts的設(shè)計(jì),也不是不可以,但是復(fù)雜度提高的同時(shí),換了一個(gè)不會(huì)用struts的人來做,要花太多時(shí)間講解。折中了一下,決定只用Struts的Action,并且主要使用DispatchAction,這樣Action的類不用太多。

    至于Error和Message,暫時(shí)還是自己定義,Tag Library雖然是個(gè)好東西,但是讓頁(yè)面更加復(fù)雜了(個(gè)人感覺),暫時(shí)不用。

    posted @ 2006-01-09 13:55 Raymond的Java筆記 閱讀(116) | 評(píng)論 (0)編輯 收藏
     
    用Ant在JDK1.5下運(yùn)行java任務(wù)時(shí),如果涉及jaxp的DOM,會(huì)拋出異常javax.xml.parsers.FactoryConfigurationError

    解決方法:

    把a(bǔ)nt的lib下面的xercesImpl.jar放到你的classpath里面。

    應(yīng)該是ANT對(duì)應(yīng)的classloader出了問題,感覺哪里是硬編碼了必須拿這個(gè)xerces的實(shí)現(xiàn)類。
    posted @ 2006-01-06 15:19 Raymond的Java筆記 閱讀(1567) | 評(píng)論 (0)編輯 收藏
     

    看到一篇文章批評(píng)google reader,說界面用了客戶端的腳本變得有趣,但功能太簡(jiǎn)單。

    也許是實(shí)話,但界面實(shí)在太重要了,有時(shí)甚至比功能重要。好的界面,起碼第一眼吸引人,有多留一會(huì)的欲望。



    posted @ 2005-12-24 22:00 Raymond的Java筆記 閱讀(79) | 評(píng)論 (0)編輯 收藏
     
    寫了個(gè)SlideShow的原型,利用image的complete,判斷圖片是否調(diào)用完全,調(diào)用完全以后才顯示,否則是LOADING的圖片,還考慮的是
    1.每調(diào)用一張圖片之前先出現(xiàn)loading的過程,
    2.調(diào)用圖片中不會(huì)因?yàn)榫W(wǎng)速和圖片過大而未顯示全,直接跳到下一張,要按順序一張一張播放.
    3.第一次 播放的時(shí)候,因?yàn)檎{(diào)用圖片會(huì)慢一點(diǎn),重新播放是調(diào)用CACHE里的,速度就快了

    代碼如下:
    <html>
    <head>
    <title>SlideShow</title>
    <script language="JavaScript1.1">
    <!--
    var yourImages = new Array("http://blog.donews.com/images/blog_donews_com/dodo/79382/o_5540320040330075952.jpg","http://www.iqoo.com/tupian/%D0%C7%D7%F9%B1%DA%D6%BD/iqoo_1113__aries.jpg","http://blog.donews.com/images/blog_donews_com/dodo/79382/o_5540320040330081327.jpg","http://blog.donews.com/images/blog_donews_com/dodo/79382/o_5540320040330081426.jpg")
    var currCount=0
    var stop=false
    function getimg(n){
    preImages= new Image()
    preImages.src = yourImages[n]
    }

    function autoPlay(){
    if(currCount!=yourImages.length){
    document.getElementById("img").style.display="none"
    getimg(currCount)
    document.getElementById("loadingbar").style.display="block"
    setTimeout("loadingImg()",1000)
    }
    else{
    currCount=0;
    if (confirm("播放完畢,是否重新播放?")){
    return autoPlay()
    }
    }
    }
    function loadingImg(){
    if (preImages.complete) {
    document.getElementById("img").src="http://blog.donews.com/images/blog_donews_com/dodo/49134/o_pix.gif"
    document.getElementById("loadingbar").style.display="none"

    document.getElementById("img").style.display="block"

    document.getElementById("img").src=yourImages[currCount]
    currCount=currCount+1
    }
    setTimeout("autoPlay()",4000)
    }
    //-->
    </script>
    </head>
    <body bgcolor="#FFFFFF">
    <div style="width:700px">
    <center>
    <a href="javascript:autoPlay()">自動(dòng)播放</a><br><br>
    <div id="loadingbar" style="display:none;"><img src=http://blog.donews.com/images/blog_donews_com/dodo/49134/o_loading.gif></div>
    <img id="img" src=http://blog.donews.com/images/blog_donews_com/dodo/49134/o_pix.gif >
    <center>
    </div>
    </body>
    </html>


    文章來源:http://blog.itpub.net/post/7956/49057
    posted @ 2005-12-23 09:53 Raymond的Java筆記 閱讀(121) | 評(píng)論 (0)編輯 收藏
     

    cron 是一個(gè)可以用來根據(jù)時(shí)間、日期、月份、星期的組合來調(diào)度對(duì)重復(fù)任務(wù)的執(zhí)行的守護(hù)進(jìn)程。

    cron 假定系統(tǒng)持續(xù)運(yùn)行。如果當(dāng)某任務(wù)被調(diào)度時(shí)系統(tǒng)不在運(yùn)行,該任務(wù)就不會(huì)被執(zhí)行。要調(diào)度一次性的任務(wù),請(qǐng)參閱第 37.2 節(jié)。

    要使用 cron 服務(wù),你必須安裝了 vixie-cron RPM 軟件包,而且必須在運(yùn)行 crond 服務(wù)。要判定該軟件包是否已安裝,使用 rpm -q vixie-cron 命令。要判定該服務(wù)是否在運(yùn)行,使用 /sbin/service crond status 命令。

    37.1.1. 配置 cron 任務(wù)

    cron 的主配置文件是 /etc/crontab,它包括下面幾行:

    SHELL=/bin/bash
    PATH=/sbin:/bin:/usr/sbin:/usr/bin
    MAILTO=root
    HOME=/
    
    # run-parts
    01 * * * * root run-parts /etc/cron.hourly
    02 4 * * * root run-parts /etc/cron.daily
    22 4 * * 0 root run-parts /etc/cron.weekly
    42 4 1 * * root run-parts /etc/cron.monthly

    前四行是用來配置 cron 任務(wù)運(yùn)行環(huán)境的變量。SHELL 變量的值告訴系統(tǒng)要使用哪個(gè) shell 環(huán)境(在這個(gè)例子里是 bash shell);PATH 變量定義用來執(zhí)行命令的路徑。cron 任務(wù)的輸出被郵寄給 MAILTO 變量定義的用戶名。如果 MAILTO 變量被定義為空白字符串(MAILTO=""),電子郵件就不會(huì)被寄出。HOME 變量可以用來設(shè)置在執(zhí)行命令或腳本時(shí)使用的主目錄。

    /etc/crontab 文件中的每一行都代表一項(xiàng)任務(wù),它的格式是:

    minute   hour   day   month   dayofweek   command

    • minute — 分鐘,從 0 到 59 之間的任何整數(shù)

    • hour — 小時(shí),從 0 到 23 之間的任何整數(shù)

    • day — 日期,從 1 到 31 之間的任何整數(shù)(如果指定了月份,必須是該月份的有效日期)

    • month — 月份,從 1 到 12 之間的任何整數(shù)(或使用月份的英文簡(jiǎn)寫如 jan、feb 等等)

    • dayofweek — 星期,從 0 到 7 之間的任何整數(shù),這里的 0 或 7 代表星期日(或使用星期的英文簡(jiǎn)寫如 sun、mon 等等)

    • command — 要執(zhí)行的命令(命令可以是 ls /proc >> /tmp/proc 之類的命令,也可以是執(zhí)行你自行編寫的腳本的命令。)

    在以上任何值中,星號(hào)(*)可以用來代表所有有效的值。譬如,月份值中的星號(hào)意味著在滿足其它制約條件后每月都執(zhí)行該命令。

    整數(shù)間的短線(-)指定一個(gè)整數(shù)范圍。譬如,1-4 意味著整數(shù) 1、2、3、4。

    用逗號(hào)(,)隔開的一系列值指定一個(gè)列表。譬如,3, 4, 6, 8 標(biāo)明這四個(gè)指定的整數(shù)。

    正斜線(/)可以用來指定間隔頻率。在范圍后加上 /<integer> 意味著在范圍內(nèi)可以跳過 integer。譬如,0-59/2 可以用來在分鐘字段定義每?jī)煞昼?。間隔頻率值還可以和星號(hào)一起使用。例如,*/3 的值可以用在月份字段中表示每三個(gè)月運(yùn)行一次任務(wù)。

    開頭為井號(hào)(#)的行是注釋,不會(huì)被處理。

    如你在 /etc/crontab 文件中所見,它使用 run-parts 腳本來執(zhí)行 /etc/cron.hourly、/etc/cron.daily、/etc/cron.weekly/etc/cron.monthly 目錄中的腳本,這些腳本被相應(yīng)地每小時(shí)、每日、每周、或每月執(zhí)行。這些目錄中的文件應(yīng)該是 shell 腳本。

    如果某 cron 任務(wù)需要根據(jù)調(diào)度來執(zhí)行,而不是每小時(shí)、每日、每周、或每月地執(zhí)行,它可以被添加到 /etc/cron.d 目錄中。該目錄中的所有文件使用和 /etc/crontab 中一樣的語(yǔ)法。范例請(qǐng)參見例 37-1。

    # record the memory usage of the system every monday 
    # at 3:30AM in the file /tmp/meminfo
    30 3 * * mon cat /proc/meminfo >> /tmp/meminfo
    # run custom script the first day of every month at 4:10AM
    10 4 1 * * /root/scripts/backup.sh

    例 37-1. crontab 的例子

    根用戶以外的用戶可以使用 crontab 工具來配置 cron 任務(wù)。所有用戶定義的 crontab 都被保存在 /var/spool/cron 目錄中,并使用創(chuàng)建它們的用戶身份來執(zhí)行。要以某用戶身份創(chuàng)建一個(gè) crontab 項(xiàng)目,登錄為該用戶,然后鍵入 crontab -e 命令,使用由 VISUALEDITOR 環(huán)境變量指定的編輯器來編輯該用戶的 crontab。該文件使用的格式和 /etc/crontab 相同。當(dāng)對(duì) crontab 所做的改變被保存后,該 crontab 文件就會(huì)根據(jù)該用戶名被保存,并寫入文件 /var/spool/cron/username 中。

    cron 守護(hù)進(jìn)程每分鐘都檢查 /etc/crontab 文件、etc/cron.d/ 目錄、以及 /var/spool/cron 目錄中的改變。如果發(fā)現(xiàn)了改變,它們就會(huì)被載入內(nèi)存。這樣,當(dāng)某個(gè) crontab 文件改變后就不必重新啟動(dòng)守護(hù)進(jìn)程了。

    37.1.2. 控制對(duì) cron 的使用

    /etc/cron.allow/etc/cron.deny 文件被用來限制對(duì) cron 的使用。這兩個(gè)使用控制文件的格式都是每行一個(gè)用戶。兩個(gè)文件都不允許空格。如果使用控制文件被修改了,cron 守護(hù)進(jìn)程(crond)不必被重啟。使用控制文件在每次用戶添加或刪除一項(xiàng) cron 任務(wù)時(shí)都會(huì)被讀取。

    無論使用控制文件中的規(guī)定如何,根用戶都總是可以使用 cron。

    如果 cron.allow 文件存在,只有其中列出的用戶才被允許使用 cron,并且 cron.deny 文件會(huì)被忽略。

    如果 cron.allow 文件不存在,所有在 cron.deny 中列出的用戶都被禁止使用 cron。

    37.1.3. 啟動(dòng)和停止服務(wù)

    要啟動(dòng) cron 服務(wù),使用 /sbin/service crond start 命令。要停止該服務(wù),使用 /sbin/service crond stop 命令。推薦你在引導(dǎo)時(shí)啟動(dòng)該服務(wù)。



    文章來源:http://blog.itpub.net/post/7956/48958
    posted @ 2005-12-22 09:46 Raymond的Java筆記 閱讀(165) | 評(píng)論 (0)編輯 收藏
     
    主站蜘蛛池模板: 久久亚洲国产成人精品无码区| 亚洲在成人网在线看| 亚洲熟伦熟女专区hd高清| 中国一级毛片视频免费看| 成人免费视频小说| 亚洲Aⅴ无码专区在线观看q| 麻豆va在线精品免费播放| 成视频年人黄网站免费视频| 亚洲精品你懂的在线观看| 美女羞羞免费视频网站| 日韩一区二区a片免费观看 | 免费国产a国产片高清| 亚洲ts人妖网站| 国产精品免费大片| 亚洲精品视频免费| 亚洲丶国产丶欧美一区二区三区| 99re在线精品视频免费| 亚洲日韩av无码| 日韩在线视频免费| 日韩毛片无码永久免费看| 亚洲成无码人在线观看| 国产一级片免费看| 久久国产成人精品国产成人亚洲| 午夜亚洲WWW湿好爽| 成人黄页网站免费观看大全| 亚洲精品高清国产麻豆专区| 免费人成毛片动漫在线播放| 中文字幕亚洲日韩无线码| 男男gay做爽爽的视频免费| 日韩免费高清视频| 亚洲日本国产综合高清| 最近中文字幕免费完整| 亚洲精品视频在线| 中文在线观看永久免费| 久久久久亚洲AV成人网| 成人免费观看男女羞羞视频| 又粗又大又猛又爽免费视频 | 亚洲欧洲国产视频| 最近中文字幕免费mv在线视频| 久久久久久a亚洲欧洲AV| 最近中文字幕大全免费版在线 |