Sql優化是一項復雜的工作,以下的一些基本原則是本人看書時所記錄下來的,很明確且沒什么廢話:
1. 索引的使用:
(1).當插入的數據為數據表中的記錄數量的10%以上,首先需要刪除該表的索引來提高數據的插入效率,當數據插入后,再建立索引。
(2).避免在索引列上使用函數或計算,在where子句中,如果索引是函數的一部分,優化器將不再使用索引而使用全表掃描。如:
低效:select * from dept where sal*12 >2500;
高效:select * from dept where sal>2500/12;
(3).避免在索引列上使用not和 “!=”,索引只能告訴什么存在于表中,而不能告訴什么不存在于表中,當數據庫遇到not 和 “!=”時,就會停止使用索引而去執行全表掃描。
(4).索引列上>=代替>
低效:select * from emp where deptno > 3
高效:select * from emp where deptno >=4
兩者的區別在于,前者dbms將直接跳到第一個deptno等于4的記錄,而后者將首先定位到deptno等于3的記錄并且向前掃描到第一個deptno大于3的。
(5).非要對一個使用函數的列啟用索引,基于函數的索引是一個較好的方案。
2. 游標的使用:
當在海量的數據表中進行數據的刪除、更新、插入操作時,用游標處理的效率是最慢的,但是游標又是必不可少的,所以正確使用游標十分重要:
(1). 在數據抽取的源表中使用時間戳,這樣每天的維表數據維護只針對更新日期為最新時間的數據來進行,大大減少需要維護的數據記錄數。
(2). 在insert和update維表時都加上一個條件來過濾維表中已經存在的記錄,例如:
insert into dim_customer select * from ods_customer where ods_customer.code not exists (dim_customer.code)
ods_customer為數據源表。dim_customer為維表。
(3). 使用顯式的游標,因為隱式的游標將會執行兩次操作,第一次檢索記錄,第二次檢查too many rows這個exception,而顯式游標不執行第二次操作。
3. 據抽取和上載時的sql優化:
(1). Where 子句中的連接順序:
oracle采用自下而上的順序解析where子句,根據這個原理,表之間的連接必須寫在其他where條件之前,那些可以過濾掉大量記錄的條件必須寫在where子句的末尾。如:
低效:select * from emp e where sal>5000 and job = ‘manager’ and 25<(select count (*) from emp where mgr=e.empno);
高效:select * from emp e where 25<(select count(*) from emp where mgr=e.empno) and sal>5000 and job=’manager’;
(2). 刪除全表時,用truncate 替代 delete,同時注意truncate只能在刪除全表時適用,因為truncate是ddl而不是dml。
(3). 盡量多使用commit
只要有可能就在程序中對每個delete,insert,update操作盡量多使用commit,這樣系統性能會因為commit所釋放的資源而大大提高。
(4). 用exists替代in ,可以提高查詢的效率。
(5). 用not exists 替代 not in
(6). 優化group by
提高group by語句的效率,可以將不需要的記錄在group by之前過濾掉。如:
低效:select job, avg(sal) from emp group by job having job = ‘president’ or job=’manager’;
高效: select job, avg(sal) from emp having job=’president’ or job=’manager’ group by job;
(7). 有條件的使用union-all 替代 union:這樣做排序就不必要了,效率會提高3到5倍。
(8). 分離表和索引
總是將你的表和索引建立在不同的表空間內,決不要將不屬于oracle內部系統的對象存放到system表空間內。同時確保數據表空間和索引表空間置于不同的硬盤控制卡控制的硬盤上。
轉自:
http://blog.csdn.net/eigo/archive/2006/03/02/614157.aspx
posted @
2006-03-04 20:34 風蕭蕭 閱讀(464) |
評論 (0) |
編輯 收藏
/*
建表:
dept:
deptno(primary key),dname,loc
emp:
empno(primary key),ename,job,mgr,sal,deptno
*/
1 列出emp表中各部門的部門號,最高工資,最低工資
select max(sal) as 最高工資,min(sal) as 最低工資,deptno from emp group by deptno;
2 列出emp表中各部門job為'CLERK'的員工的最低工資,最高工資
select max(sal) as 最高工資,min(sal) as 最低工資,deptno as 部門號 from emp where job = 'CLERK' group by deptno;
3 對于emp中最低工資小于1000的部門,列出job為'CLERK'的員工的部門號,最低工資,最高工資
select max(sal) as 最高工資,min(sal) as 最低工資,deptno as 部門號 from emp as b
where job='CLERK' and 1000>(select min(sal) from emp as a where a.deptno=b.deptno) group by b.deptno
4 根據部門號由高而低,工資有低而高列出每個員工的姓名,部門號,工資
select deptno as 部門號,ename as 姓名,sal as 工資 from emp order by deptno desc,sal asc
5 寫出對上題的另一解決方法
(請補充)
6 列出'張三'所在部門中每個員工的姓名與部門號
select ename,deptno from emp where deptno = (select deptno from emp where ename = '張三')
7 列出每個員工的姓名,工作,部門號,部門名
select ename,job,emp.deptno,dept.dname from emp,dept where emp.deptno=dept.deptno
8 列出emp中工作為'CLERK'的員工的姓名,工作,部門號,部門名
select ename,job,dept.deptno,dname from emp,dept where dept.deptno=emp.deptno and job='CLERK'
9 對于emp中有管理者的員工,列出姓名,管理者姓名(管理者外鍵為mgr)
select a.ename as 姓名,b.ename as 管理者 from emp as a,emp as b where a.mgr is not null and a.mgr=b.empno
10 對于dept表中,列出所有部門名,部門號,同時列出各部門工作為'CLERK'的員工名與工作
select dname as 部門名,dept.deptno as 部門號,ename as 員工名,job as 工作 from dept,emp
where dept.deptno *= emp.deptno and job = 'CLERK'
11 對于工資高于本部門平均水平的員工,列出部門號,姓名,工資,按部門號排序
select a.deptno as 部門號,a.ename as 姓名,a.sal as 工資 from emp as a
where a.sal>(select avg(sal) from emp as b where a.deptno=b.deptno) order by a.deptno
12 對于emp,列出各個部門中平均工資高于本部門平均水平的員工數和部門號,按部門號排序
select count(a.sal) as 員工數,a.deptno as 部門號 from emp as a
where a.sal>(select avg(sal) from emp as b where a.deptno=b.deptno) group by a.deptno order by a.deptno
13 對于emp中工資高于本部門平均水平,人數多與1人的,列出部門號,人數,按部門號排序
select count(a.empno) as 員工數,a.deptno as 部門號,avg(sal) as 平均工資 from emp as a
where (select count(c.empno) from emp as c where c.deptno=a.deptno and c.sal>(select avg(sal) from emp as b where c.deptno=b.deptno))>1
group by a.deptno order by a.deptno
14 對于emp中低于自己工資至少5人的員工,列出其部門號,姓名,工資,以及工資少于自己的人數
select a.deptno,a.ename,a.sal,(select count(b.ename) from emp as b where b.sal<a.sal) as 人數 from emp as a
where (select count(b.ename) from emp as b where b.sal<a.sal)>5
轉自:http://blog.csdn.net/woolceo/archive/2006/03/02/614094.aspx
posted @
2006-03-04 20:31 風蕭蕭 閱讀(2043) |
評論 (1) |
編輯 收藏
在開發部署PORTAL項目時,遇到異常:
Exception:weblogic.management.ApplicationException: prepare failed for content_repo.jar Module: content_repo.jar Error: Exception preparing module: EJBModule(content_repo.jar,status=NEW) Unable to deploy EJB: content_repo.jar from content_repo.jar: Class not found: com.bea.content.repo.i18n.RepoExceptionTextFormatter java.lang.NoClassDefFoundError: Class not found: com.bea.content.repo.i18n.RepoExceptionTextFormatter at weblogic.ejb20.compliance.EJBComplianceChecker.check([Ljava.lang.Object;)V(EJBComplianceChecker.java:287)
我在weblogic81 sp3的doc中沒有發現com.bea.content.repo.i18n這個package.
重新安裝了weblogic sp4,就不再出現這個錯誤了。
posted @
2006-02-15 23:14 風蕭蕭 閱讀(618) |
評論 (0) |
編輯 收藏
Problem Statement |
|
When editing a single line of text, there are four keys that can be used to move the cursor: end, home, left-arrow and right-arrow. As you would expect, left-arrow and right-arrow move the cursor one character left or one character right, unless the cursor is at the beginning of the line or the end of the line, respectively, in which case the keystrokes do nothing (the cursor does not wrap to the previous or next line). The home key moves the cursor to the beginning of the line, and the end key moves the cursor to the end of the line.
You will be given a int, N, representing the number of character in a line of text. The cursor is always between two adjacent characters, at the beginning of the line, or at the end of the line. It starts before the first character, at position 0. The position after the last character on the line is position N. You should simulate a series of keystrokes and return the final position of the cursor. You will be given a String where characters of the String represent the keystrokes made, in order. 'L' and 'R' represent left and right, while 'H' and 'E' represent home and end. |
Definition |
|
Class: |
CursorPosition |
Method: |
getPosition |
Parameters: |
String, int |
Returns: |
int |
Method signature: |
int getPosition(String keystrokes, int N) |
(be sure your method is public) | |
|
|
Constraints |
- |
keystrokes will be contain between 1 and 50 'L', 'R', 'H', and 'E' characters, inclusive. |
- |
N will be between 1 and 100, inclusive. |
Examples |
0) |
|
|
|
Returns: 7 |
First, we go to the end of the line at position 10. Then, the right-arrow does nothing because we are already at the end of the line. Finally, three left-arrows brings us to position 7. | | |
1) |
|
|
|
Returns: 2 |
All the right-arrows at the end ensure that we end up at the end of the line. | | |
2) |
|
|
"ELLLELLRRRRLRLRLLLRLLLRLLLLRLLRRRL" |
10 | |
Returns: 3 |
| |
3) |
|
|
"RRLEERLLLLRLLRLRRRLRLRLRLRLLLLL" |
19 | |
Returns: 12 |
| |
This problem statement is the exclusive and proprietary property of TopCoder, Inc. Any unauthorized use or reproduction of this information without the prior written consent of TopCoder, Inc. is strictly prohibited. (c)2003, TopCoder, Inc. All rights reserved.
答案:
1
2
public class CursorPosition
{
3
public int getPosition(String keystrokes, int N)
{
4
int position = 0;
5
String s = "";
6
for(int i = 0; i < keystrokes.length(); i++)
{
7
s = keystrokes.substring(i, i+1);
8
if("L".equals(s))
{
9
if(position == 0) continue;
10
position--;
11
}
12
if("R".equals(s))
{
13
if(position == N) continue;
14
position++;
15
}
16
if("H".equals(s))
{
17
position = 0;
18
}
19
if("E".equals(s))
{
20
position = N;
21
}
22
23
}
24
25
return position;
26
27
}
28
/** *//**
29
* @param args
30
*/
31
public static void main(String[] args)
{
32
CursorPosition cursorPosition = new CursorPosition();
33
int cursor = cursorPosition.getPosition("ERLLL", 10);
34
System.out.println("cursor:" + cursor);
35
}
36
37
}
38
posted @
2005-11-27 23:42 風蕭蕭 閱讀(935) |
評論 (2) |
編輯 收藏
Problem Statement |
|
A square matrix is a grid of NxN numbers. For example, the following is a 3x3 matrix: 4 3 5
2 4 5
0 1 9 One way to represent a matrix of numbers, each of which is between 0 and 9 inclusive, is as a row-major String. To generate the String, simply concatenate all of the elements from the first row followed by the second row and so on, without any spaces. For example, the above matrix would be represented as "435245019".
You will be given a square matrix as a row-major String. Your task is to convert it into a String[], where each element represents one row of the original matrix. Element i of the String[] represents row i of the matrix. You should not include any spaces in your return. Hence, for the above String, you would return {"435","245","019"}. If the input does not represent a square matrix because the number of characters is not a perfect square, return an empty String[], {}. |
Definition |
|
Class: |
MatrixTool |
Method: |
convert |
Parameters: |
String |
Returns: |
String[] |
Method signature: |
String[] convert(String s) |
(be sure your method is public) | |
|
|
Constraints |
- |
s will contain between 1 and 50 digits, inclusive. |
Examples |
0) |
|
|
|
Returns: {"435", "245", "019" } |
| |
1) |
|
|
|
2) |
|
|
|
Returns: { } |
This input has 10 digits, and 10 is not a perfect square. | | |
3) |
|
|
"3357002966366183191503444273807479559869883303524" | |
Returns: {"3357002", "9663661", "8319150", "3444273", "8074795", "5986988", "3303524" } |
| |
This problem statement is the exclusive and proprietary property of TopCoder, Inc. Any unauthorized use or reproduction of this information without the prior written consent of TopCoder, Inc. is strictly prohibited. (c)2003, TopCoder, Inc. All rights reserved.
答案:
1
public class MatrixTool
{
2
3
public String[] convert(String s)
{
4
if (s == null || s.length() == 0 || s.length() > 50)
{
5
return new String[]
{};
6
}
7
int length = s.length();
8
int n = (int)Math.sqrt(length);
9
if(n*n == length)
{
10
String[] result = new String[n];
11
for(int i = 0; i < n; i++)
{
12
result[i] = s.substring(i*n, i*n + n);
13
}
14
return result;
15
}else
{
16
return new String[]
{};
17
}
18
}
19
20
/** *//**
21
* @param args
22
*/
23
public static void main(String[] args)
{
24
MatrixTool matrix = new MatrixTool();
25
String[] result = matrix.convert("3357002966366183191503444273807479559869883303524");
26
for(int i = 0; i < result.length; i++)
{
27
System.out.println(result[i]);
28
}
29
}
30
31
}
32
posted @
2005-11-27 23:40 風蕭蕭 閱讀(735) |
評論 (0) |
編輯 收藏
摘要: Problem Statement
A simple line drawing program uses a blank 20 x 20 pixel canvas and a directional cursor that starts at the upper left corner pointing straight down. T...
閱讀全文
posted @
2005-11-27 23:37 風蕭蕭 閱讀(1157) |
評論 (0) |
編輯 收藏
經典面試題
一、面向對象的三個基本特征
2、方法重載和方法重寫的概念和區別
3、接口和內部類、抽象類的特性
4、文件讀寫的基本類
**5、串行化的注意事項以及如何實現串行化
6、線程的基本概念、線程的基本狀態以及狀態之間的關系
7、線程的同步、如何實現線程的同步
8、幾種常用的數據結構及內部實現原理。
9、Socket通信(TCP、UDP區別及Java實現方式)
**10、Java的事件委托機制和垃圾回收機制
11、JDBC調用數據庫的基本步驟
**12、解析XML文件的幾種方式和區別
13、Java四種基本權限的定義
14、Java的國際化
二、JSP
1、至少要能說出7個隱含對象以及他們的區別
** 2、forward 和redirect的區別
3、JSP的常用指令
三、servlet
1、什么情況下調用doGet()和doPost()?
2、servlet的init()方法和service()方法的區別
3、servlet的生命周期
4、如何現實servlet的單線程模式
5、servlet的配置
6、四種會話跟蹤技術
四、EJB
**1、EJB容器提供的服務
主要提供聲明周期管理、代碼產生、持續性管理、安全、事務管理、鎖和并發行管理等服務。
2、EJB的角色和三個對象
EJB角色主要包括Bean開發者 應用組裝者 部署者 系統管理員 EJB容器提供者 EJB服務器提供者
三個對象是Remote(Local)接口、Home(LocalHome)接口,Bean類
2、EJB的幾種類型
會話(Session)Bean ,實體(Entity)Bean 消息驅動的(Message Driven)Bean
會話Bean又可分為有狀態(Stateful)和無狀態(Stateless)兩種
實體Bean可分為Bean管理的持續性(BMP)和容器管理的持續性(CMP)兩種
3、bean 實例的生命周期
對于Stateless Session Bean、Entity Bean、Message Driven Bean一般存在緩沖池管理,而對于Entity Bean和Statefull Session Bean存在Cache管理,通常包含創建實例,設置上下文、創建EJB Object(create)、業務方法調用、remove等過程,對于存在緩沖池管理的Bean,在create之后實例并不從內存清除,而是采用緩沖池調度機制不斷重用實例,而對于存在Cache管理的Bean則通過激活和去激活機制保持Bean的狀態并限制內存中實例數量。
4、激活機制
以Statefull Session Bean 為例:其Cache大小決定了內存中可以同時存在的Bean實例的數量,根據MRU或NRU算法,實例在激活和去激活狀態之間遷移,激活機制是當客戶端調用某個EJB實例業務方法時,如果對應EJB Object發現自己沒有綁定對應的Bean實例則從其去激活Bean存儲中(通過序列化機制存儲實例)回復(激活)此實例。狀態變遷前會調用對應的ejbActive和ejbPassivate方法。
5、remote接口和home接口主要作用
remote接口定義了業務方法,用于EJB客戶端調用業務方法
home接口是EJB工廠用于創建和移除查找EJB實例
6、客服端調用EJB對象的幾個基本步驟
一、 設置JNDI服務工廠以及JNDI服務地址系統屬性
二、 查找Home接口
三、 從Home接口調用Create方法創建Remote接口
四、 通過Remote接口調用其業務方法
五、數據庫
1、存儲過程的編寫
2、基本的SQL語句
六、weblogic
1、 如何給weblogic指定大小的內存?
在啟動Weblogic的腳本中(位于所在Domian對應服務器目錄下的startServerName),增加set MEM_ARGS=-Xms32m -Xmx200m,可以調整最小內存為32M,最大200M
2、 如何設定的weblogic的熱啟動模式(開發模式)與產品發布模式?
可以在管理控制臺中修改對應服務器的啟動模式為開發或產品模式之一?;蛘咝薷姆盏膯游募蛘遚ommenv文件,增加set PRODUCTION_MODE=true。
3、 如何啟動時不需輸入用戶名與密碼?
修改服務啟動文件,增加 WLS_USER和WLS_PW項。也可以在boot.properties文件中增加加密過的用戶名和密碼.
4、 在weblogic管理制臺中對一個應用域(或者說是一個網站,Domain)進行jms及ejb或連接池等相關信息進行配置后,實際保存在什么文件中?
保存在此Domain的config.xml文件中,它是服務器的核心配置文件。
5、 說說weblogic中一個Domain的缺省目錄結構?比如要將一個簡單的helloWorld.jsp放入何目錄下,然的在瀏覽器上就可打入http://主機:端口號//helloword.jsp就可以看到運行結果了? 又比如這其中用到了一個自己寫的javaBean該如何辦?
Domain目錄\服務器目錄\applications,將應用目錄放在此目錄下將可以作為應用訪問,如果是Web應用,應用目錄需要滿足Web應用目錄要求,jsp文件可以直接放在應用目錄中,Javabean需要放在應用目錄的WEB-INF目錄的classes目錄中,設置服務器的缺省應用將可以實現在瀏覽器上無需輸入應用名。
6、 如何查看在weblogic中已經發布的EJB?
可以使用管理控制臺,在它的Deployment中可以查看所有已發布的EJB
7、 如何在weblogic中進行ssl配置與客戶端的認證配置或說說j2ee(標準)進行ssl的配置
缺省安裝中使用DemoIdentity.jks和DemoTrust.jks KeyStore實現SSL,需要配置服務器使用Enable SSL,配置其端口,在產品模式下需要從CA獲取私有密鑰和數字證書,創建identity和trust keystore,裝載獲得的密鑰和數字證書??梢耘渲么薙SL連接是單向還是雙向的。
8、在weblogic中發布ejb需涉及到哪些配置文件
不同類型的EJB涉及的配置文件不同,都涉及到的配置文件包括ejb-jar.xml,weblogic-ejb-jar.xmlCMP實體Bean一般還需要weblogic-cmp-rdbms-jar.xml
9、EJB需直接實現它的業務接口或Home接口嗎,請簡述理由.
遠程接口和Home接口不需要直接實現,他們的實現代碼是由服務器產生的,程序運行中對應實現類會作為對應接口類型的實例被使用。
10、說說在weblogic中開發消息Bean時的persistent與non-persisten的差別
persistent方式的MDB可以保證消息傳遞的可靠性,也就是如果EJB容器出現問題而JMS服務器依然會將消息在此MDB可用的時候發送過來,而non-persistent方式的消息將被丟棄。
11、說說你所熟悉或聽說過的j2ee中的幾種常用模式?及對設計模式的一些看法
Session Facade Pattern:使用SessionBean訪問EntityBean
Message Facade Pattern:實現異步調用
EJB Command Pattern:使用Command JavaBeans取代SessionBean,實現輕量級訪問
Data Transfer Object Factory:通過DTO Factory簡化EntityBean數據提供特性
Generic Attribute Access:通過AttibuteAccess接口簡化EntityBean數據提供特性
Business Interface:通過遠程(本地)接口和Bean類實現相同接口規范業務邏輯一致性
EJB架構的設計好壞將直接影響系統的性能、可擴展性、可維護性、組件可重用性及開發效率。項目越復雜,項目隊伍越龐大則越能體現良好設計的重要性。
轉載自:http://blog.csdn.net/laou2008/archive/2005/11/15/529519.aspx
西門子的一道筆試題
設計一個函數,形式如: int func(unsigned int),要求求出不大于輸入參數的最大的素數,比如輸入12,返回11。
轉載自:http://community.csdn.net/Expert/topic/4368/4368551.xml?temp=.4177057
微軟MSN在南大的筆試題
羅馬數字共有七個,即
I(1),V(5),X(10),L(50),C(100),D(500),M(1000)。
按照下面三條規則可以表示任意正整數。
重復數次:一個羅馬數字重復幾次,就表示這個數的幾倍。
右加左減:在一個較大的羅馬數字的右邊記上一個較小的羅馬數字,
表示大數字加小數字。在一個較大的數字的左邊記上一個較小的羅
馬數字,表示大數字減小數字。但是,左減不能跨越等級。
比如,99不可以用IC表示,用XCIX表示
基本數字Ⅰ、X 、C 中的任何一個,自身連用構成數目,或者放在大數的右邊連用構成數目,都不能超過三個,比如40不能用XXXX,而用XL表示
設計一個函數,將100(包括100)以內的整數轉換成羅馬數字,超過100不考慮
int itor(int n,char* buf,int bufLength)
其中,n是要轉換的整數,buf是要輸出的字符串,bufLength是buf的字符長度
成功,返回0,否則,返回 -1;
比如:
char buf[256];
result = itor(n,buf,sizeof(buf));
when n = 28; result = 0, 輸出"XXVIII";
when n = 72; result = 0, 輸出"LXXII";
轉載自:http://community.csdn.net/Expert/topic/4386/4386877.xml?temp=.411175
posted @
2005-11-16 09:59 風蕭蕭 閱讀(1061) |
評論 (0) |
編輯 收藏
Google文件系統
GFS是一個可擴展的分布式文件系統,用于大型的、分布式的、對大量數據進行訪問的應用。它運行于廉價的普通硬件上,但可以提供容錯功能。它可以給大量的用戶提供總體性能較高的服務。
1、設計概覽
(1)設計想定
GFS與過去的分布式文件系統有很多相同的目標,但GFS的設計受到了當前及預期的應用方面的工作量及技術環境的驅動,這反映了它與早期的文件系統明顯不同的設想。這就需要對傳統的選擇進行重新檢驗并進行完全不同的設計觀點的探索。
GFS與以往的文件系統的不同的觀點如下:
1、部件錯誤不再被當作異常,而是將其作為常見的情況加以處理。因為文件系統由成百上千個用于存儲的機器構成,而這些機器是由廉價的普通部件組成并被大量的客戶機訪問。部件的數量和質量使得一些機器隨時都有可能無法工作并且有一部分還可能無法恢復。所以實時地監控、錯誤檢測、容錯、自動恢復對系統來說必不可少。
2、按照傳統的標準,文件都非常大。長度達幾個GB的文件是很平常的。每個文件通常包含很多應用對象。當經常要處理快速增長的、包含數以萬計的對象、長度達TB的數據集時,我們很難管理成千上萬的KB規模的文件塊,即使底層文件系統提供支持。因此,設計中操作的參數、塊的大小必須要重新考慮。對大型的文件的管理一定要能做到高效,對小型的文件也必須支持,但不必優化。
3、大部分文件的更新是通過添加新數據完成的,而不是改變已存在的數據。在一個文件中隨機的操作在實踐中幾乎不存在。一旦寫完,文件就只可讀,很多數據都有這些特性。一些數據可能組成一個大倉庫以供數據分析程序掃描。有些是運行中的程序連續產生的數據流。有些是檔案性質的數據,有些是在某個機器上產生、在另外一個機器上處理的中間數據。由于這些對大型文件的訪問方式,添加操作成為性能優化和原子性保證的焦點。而在客戶機中緩存數據塊則失去了吸引力。
4、工作量主要由兩種讀操作構成:對大量數據的流方式的讀操作和對少量數據的隨機方式的讀操作。在前一種讀操作中,可能要讀幾百KB,通常達 1MB和更多。來自同一個客戶的連續操作通常會讀文件的一個連續的區域。隨機的讀操作通常在一個隨機的偏移處讀幾個KB。性能敏感的應用程序通常將對少量數據的讀操作進行分類并進行批處理以使得讀操作穩定地向前推進,而不要讓它來來回回的讀。
5、工作量還包含許多對大量數據進行的、連續的、向文件添加數據的寫操作。所寫的數據的規模和讀相似。一旦寫完,文件很少改動。在隨機位置對少量數據的寫操作也支持,但不必非常高效。
6、系統必須高效地實現定義完好的大量客戶同時向同一個文件的添加操作的語義。
(2)系統接口
GFS提供了一個相似地文件系統界面,雖然它沒有向POSIX那樣實現標準的API。文件在目錄中按層次組織起來并由路徑名標識。
(3)體系結構:
一個GFS集群由一個master和大量的chunkserver構成,并被許多客戶(Client)訪問。如圖1所示。Master和 chunkserver通常是運行用戶層服務進程的Linux機器。只要資源和可靠性允許,chunkserver和client可以運行在同一個機器上。
文件被分成固定大小的塊。每個塊由一個不變的、全局唯一的64位的chunk-handle標識,chunk-handle是在塊創建時由 master分配的。ChunkServer將塊當作Linux文件存儲在本地磁盤并可以讀和寫由chunk-handle和位區間指定的數據。出于可靠性考慮,每一個塊被復制到多個chunkserver上。默認情況下,保存3個副本,但這可以由用戶指定。
Master維護文件系統所以的元數據(metadata),包括名字空間、訪問控制信息、從文件到塊的映射以及塊的當前位置。它也控制系統范圍的活動,如塊租約(lease)管理,孤兒塊的垃圾收集,chunkserver間的塊遷移。Master定期通過HeartBeat消息與每一個 chunkserver通信,給chunkserver傳遞指令并收集它的狀態。
與每個應用相聯的GFS客戶代碼實現了文件系統的API并與master和chunkserver通信以代表應用程序讀和寫數據??蛻襞cmaster的交換只限于對元數據(metadata)的操作,所有數據方面的通信都直接和chunkserver聯系。
客戶和chunkserver都不緩存文件數據。因為用戶緩存的益處微乎其微,這是由于數據太多或工作集太大而無法緩存。不緩存數據簡化了客戶程序和整個系統,因為不必考慮緩存的一致性問題。但用戶緩存元數據(metadata)。Chunkserver也不必緩存文件,因為塊時作為本地文件存儲的。
(4)單master。
只有一個master也極大的簡化了設計并使得master可以根據全局情況作出先進的塊放置和復制決定。但是我們必須要將master對讀和寫的參與減至最少,這樣它才不會成為系統的瓶頸。Client從來不會從master讀和寫文件數據。Client只是詢問master它應該和哪個 chunkserver聯系。Client在一段限定的時間內將這些信息緩存,在后續的操作中Client直接和chunkserver交互。
以圖1解釋一下一個簡單的讀操作的交互。
1、client使用固定的塊大小將應用程序指定的文件名和字節偏移轉換成文件的一個塊索引(chunk index)。
2、給master發送一個包含文件名和塊索引的請求。
3、master回應對應的chunk handle和副本的位置(多個副本)。
4、client以文件名和塊索引為鍵緩存這些信息。(handle和副本的位置)。
5、Client 向其中一個副本發送一個請求,很可能是最近的一個副本。請求指定了chunk handle(chunkserver以chunk handle標識chunk)和塊內的一個字節區間。
6、除非緩存的信息不再有效(cache for a limited time)或文件被重新打開,否則以后對同一個塊的讀操作不再需要client和master間的交互。
通常Client可以在一個請求中詢問多個chunk的地址,而master也可以很快回應這些請求。
(5)塊規模:
塊規模是設計中的一個關鍵參數。我們選擇的是64MB,這比一般的文件系統的塊規模要大的多。每個塊的副本作為一個普通的Linux文件存儲,在需要的時候可以擴展。
塊規模較大的好處有:
1、減少client和master之間的交互。因為讀寫同一個塊只是要在開始時向master請求塊位置信息。對于讀寫大型文件這種減少尤為重要。即使對于訪問少量數據的隨機讀操作也可以很方便的為一個規模達幾個TB的工作集緩緩存塊位置信息。
2、Client在一個給定的塊上很可能執行多個操作,和一個chunkserver保持較長時間的TCP連接可以減少網絡負載。
3、這減少了master上保存的元數據(metadata)的規模,從而使得可以將metadata放在內存中。這又會帶來一些別的好處。
不利的一面:
一個小文件可能只包含一個塊,如果很多Client訪問改文件的話,存儲這些塊的chunkserver將成為訪問的熱點。但在實際應用中,應用程序通常順序地讀包含多個塊的文件,所以這不是一個主要問題。
(6)元數據(metadata):
master存儲了三中類型的metadata:文件的名字空間和塊的名字空間,從文件到塊的映射,塊的副本的位置。所有的metadata都放在內存中。前兩種類型的metadata通過向操作日志登記修改而保持不變,操作日志存儲在master的本地磁盤并在幾個遠程機器上留有副本。使用日志使得我們可以很簡單地、可靠地更新master的狀態,即使在master崩潰的情況下也不會有不一致的問題。相反,mater在每次啟動以及當有 chuankserver加入的時候詢問每個chunkserver的所擁有的塊的情況。
A、內存數據結構:
因為metadata存儲在內存中,所以master的操作很快。進一步,master可以輕易而且高效地定期在后臺掃描它的整個狀態。這種定期地掃描被用于實現塊垃圾收集、chunkserver出現故障時的副本復制、為平衡負載和磁盤空間而進行的塊遷移。
這種方法的一個潛在的問題就是塊的數量也即整個系統的容量是否受限與master的內存。實際上,這并不是一個嚴重的問題。Master為每個 64MB的塊維護的metadata不足64個字節。除了最后一塊,文件所有的塊都是滿的。類似的,每個文件的名字空間數據也不足64個字節,因為文件名是以一種事先確定的壓縮方式存儲的.如果要支持更大的文件系統,那么增加一些內存的方法對于我們將元數據(metadata)保存在內存種所獲得的簡單性、可靠性、高性能和靈活性來說,這只是一個很小的代價。
B、塊位置:
master并不為chunkserver所擁有的塊的副本的保存一個不變的記錄。它在啟動時通過簡單的查詢來獲得這些信息。Master可以保持這些信息的更新,因為它控制所有塊的放置并通過HeartBeat消息來監控chunkserver的狀態。
這樣做的好處:因為chunkserver可能加入或離開集群、改變路徑名、崩潰、重啟等,一個集群重有成百個server,這些事件經常發生,這種方法就排除了master與chunkserver之間的同步問題。
另一個原因是:只有chunkserver才能確定它自己到底有哪些塊,由于錯誤,chunkserver中的一些塊可能會很自然的消失,這樣在master中就沒有必要為此保存一個不變的記錄。
C、操作日志:
操作日志包含了對metadata所作的修改的歷史記錄。它作為邏輯時間線定義了并發操作的執行順序。文件、塊以及它們的版本號都由它們被創建時的邏輯時間而唯一地、永久地被標識。
操作日志是如此的重要,我們必須要將它可靠地保存起來,并且只有在metadata的改變固定下來之后才將變化呈現給用戶。所以我們將操作日志復制到數個遠程的機器上,并且只有在將相應的日志記錄寫到本地和遠程的磁盤上之后才回答用戶的請求。
Master可以用操作日志來恢復它的文件系統的狀態。為了將啟動時間減至最小,日志就必須要比較小。每當日志的長度增長到超過一定的規模后,master就要檢查它的狀態,它可以從本地磁盤裝入最近的檢查點來恢復狀態。
創建一個檢查點比較費時,master的內部狀態是以一種在創建一個檢查點時并不耽誤即將到來的修改操作的方式來組織的。Master切換到一個新的日子文件并在一個單獨的線程中創建檢查點。這個新的檢查點記錄了切換前所有的修改。在一個有數十萬文件的集群中用一分鐘左右就能完成。創建完后,將它寫入本地和遠程的磁盤。
(7)數據完整性
名字空間的修改必須是原子性的,它們只能有master處理:名字空間鎖保證了操作的原子性和正確性,而master的操作日志在全局范圍內定義了這些操作的順序。
文件區間的狀態在修改之后依賴于修改的類型,不論操作成功還是失敗,也不論是不是并發操作。如果不論從哪個副本上讀,所有的客戶都看到同樣的數據,那么文件的這個區域就是一致的。如果文件的區域是一致的并且用戶可以看到修改操作所寫的數據,那么它就是已定義的。如果修改是在沒有并發寫操作的影響下完成的,那么受影響的區域是已定義的,所有的client都能看到寫的內容。成功的并發寫操作是未定義但卻是一致的。失敗的修改將使區間處于不一致的狀態。
Write操作在應用程序指定的偏移處寫入數據,而record append操作使得數據(記錄)即使在有并發修改操作的情況下也至少原子性的被加到GFS指定的偏移處,偏移地址被返回給用戶。
在一系列成功的修改操作后,最后的修改操作保證文件區域是已定義的。GFS通過對所有的副本執行同樣順序的修改操作并且使用塊版本號檢測過時的副本(由于chunkserver退出而導致丟失修改)來做到這一點。
因為用戶緩存了會位置信息,所以在更新緩存之前有可能從一個過時的副本中讀取數據。但這有緩存的截止時間和文件的重新打開而受到限制。
在修改操作成功后,部件故障仍可以是數據受到破壞。GFS通過master和chunkserver間定期的handshake,借助校驗和來檢測對數據的破壞。一旦檢測到,就從一個有效的副本盡快重新存儲。只有在GFS檢測前,所有的副本都失效,這個塊才會丟失。
2、系統交互
(1)租約(lease)和修改順序:
(2)數據流
我們的目標是充分利用每個機器的網絡帶寬,避免網絡瓶頸和延遲
為了有效的利用網絡,我們將數據流和控制流分離。數據是以流水線的方式在選定的chunkerserver鏈上線性的傳遞的。每個機器的整個對外帶寬都被用作傳遞數據。為避免瓶頸,每個機器在收到數據后,將它收到數據盡快傳遞給離它最近的機器。
(3)原子性的record Append:
GFS提供了一個原子性的添加操作:record append。在傳統的寫操作中,client指定被寫數據的偏移位置,向同一個區間的并發的寫操作是不連續的:區間有可能包含來自多個client的數據碎片。在record append中, client只是指定數據。GFS在其選定的偏移出將數據至少原子性的加入文件一次,并將偏移返回給client。
在分布式的應用中,不同機器上的許多client可能會同時向一個文件執行添加操作,添加操作被頻繁使用。如果用傳統的write操作,可能需要額外的、復雜的、開銷較大的同步,例如通過分布式鎖管理。在我們的工作量中,這些文件通常以多個生產者單個消費者隊列的方式或包含從多個不同 client的綜合結果。
Record append和前面講的write操作的控制流差不多,只是在primary上多了一些邏輯判斷。首先,client將數據發送到文件最后一塊的所有副本上。然后向primary發送請求。Primary檢查添加操作是否會導致該塊超過最大的規模(64M)。如果這樣,它將該塊擴充到最大規模,并告訴其它副本做同樣的事,同時通知client該操作需要在下一個塊上重新嘗試。如果記錄滿足最大規模的要求,primary就會將數據添加到它的副本上,并告訴其它的副本在在同樣的偏移處寫數據,最后primary向client報告寫操作成功。如果在任何一個副本上record append操作失敗,client將重新嘗試該操作。這時候,同一個塊的副本可能包含不同的數據,因為有的可能復制了全部的數據,有的可能只復制了部分。GFS不能保證所有的副本每個字節都是一樣的。它只保證每個數據作為一個原子單元被寫過至少一次。這個是這樣得出的:操作要是成功,數據必須在所有的副本上的同樣的偏移處被寫過。進一步,從這以后,所有的副本至少和記錄一樣長,所以后續的記錄將被指定到更高的偏移處或者一個不同的塊上,即使另一個副本成了primary。根據一致性保證,成功的record append操作的區間是已定義的。而受到干擾的區間是不一致的。
(4)快照(snapshot)
快照操作幾乎在瞬間構造一個文件和目錄樹的副本,同時將正在進行的其他修改操作對它的影響減至最小。
我們使用copy-on-write技術來實現snapshot。當master受到一個snapshot請求時,它首先將要snapshot的文件上塊上的lease。這使得任何一個向這些塊寫數據的操作都必須和master交互以找到擁有lease的副本。這就給master一個創建這個塊的副本的機會。
副本被撤銷或終止后,master在磁盤上登記執行的操作,然后復制源文件或目錄樹的metadata以對它的內存狀態實施登記的操作。這個新創建的snapshot文件和源文件(其metadata)指向相同的塊(chunk)。
Snapshot之后,客戶第一次向chunk c寫的時候,它發一個請求給master以找到擁有lease的副本。Master注意到chunk c的引用記數比1大,它延遲對用戶的響應,選擇一個chunk handle C’,然后要求每一有chunk c的副本的chunkserver創建一個塊C’。每個chunkserver在本地創建chunk C’避免了網絡開銷。從這以后和對別的塊的操作沒有什么區別。
3、MASTER操作
MASTER執行所有名字空間的操作,除此之外,他還在系統范圍管理數據塊的復制:決定數據塊的放置方案,產生新數據塊并將其備份,和其他系統范圍的操作協同來確保數據備份的完整性,在所有的數據塊服務器之間平衡負載并收回沒有使用的存儲空間。
3.1 名字空間管理和加鎖
與傳統文件系統不同的是,GFS沒有與每個目錄相關的能列出其所有文件的數據結構,它也不支持別名(unix中的硬連接或符號連接),不管是對文件或是目錄。GFS的名字空間邏輯上是從文件元數據到路徑名映射的一個查用表。
MASTER在執行某個操作前都要獲得一系列鎖,例如,它要對/d1/d2…/dn/leaf執行操作,則它必須獲得/d1,/d1/d2,…, /d1/d2/…/dn的讀鎖,/d1/d2…/dn/leaf的讀鎖或寫鎖(其中leaf可以使文件也可以是目錄)。MASTER操作的并行性和數據的一致性就是通過這些鎖來實現的。
3.2 備份存儲放置策略
一個GFS集群文件系統可能是多層分布的。一般情況下是成千上萬個文件塊服務器分布于不同的機架上,而這些文件塊服務器又被分布于不同機架上的客戶來訪問。因此,不同機架上的兩臺機器之間的通信可能通過一個或多個交換機。數據塊冗余配置策略要達到連個目的:最大的數據可靠性和可用性,最大的網絡帶寬利用率。因此,如果僅僅把數據的拷貝置于不同的機器上很難滿足這兩個要求,必須在不同的機架上進行數據備份。這樣即使整個機架被毀或是掉線,也能確保數據的正常使用。這也使數據傳輸,尤其是讀數據,可以充分利用帶寬,訪問到多個機架,而寫操作,則不得不涉及到更多的機架。
3.3 產生、重復制、重平衡數據塊
當MASTER產生新的數據塊時,如何放置新數據塊,要考慮如下幾個因素:(1)盡量放置在磁盤利用率低的數據塊服務器上,這樣,慢慢地各服務器的磁盤利用率就會達到平衡。(2)盡量控制在一個服務器上的“新創建”的次數。(3)由于上一小節討論的原因,我們需要把數據塊放置于不同的機架上。
MASTER在可用的數據塊備份低于用戶設定的數目時需要進行重復制。這種情況源于多種原因:服務器不可用,數據被破壞,磁盤被破壞,或者備份數目被修改。每個被需要重復制的數據塊的優先級根據以下幾項確定:第一是現在的數目距目標的距離,對于能阻塞用戶程序的數據塊,我們也提高它的優先級。最后, MASTER按照產生數據塊的原則復制數據塊,并把它們放到不同的機架內的服務器上。
MASTER周期性的平衡各服務器上的負載:它檢查chunk分布和負載平衡,通過這種方式來填充一個新的服務器而不是把其他的內容統統放置到它上面帶來大量的寫數據。數據塊放置的原則與上面討論的相同,此外,MASTER還決定那些數據塊要被移除,原則上他會清除那些空閑空間低于平均值的那些服務器。
3.4 垃圾收集
在一個文件被刪除之后,GFS并不立即收回磁盤空間,而是等到垃圾收集程序在文件和數據塊級的的檢查中收回。
當一個文件被應用程序刪除之后,MASTER會立即記錄下這些變化,但文件所占用的資源卻不會被立即收回,而是重新給文件命了一個隱藏的名字,并附上了刪除的時間戳。在MASTER定期檢查名字空間時,它刪除超過三天(可以設定)的隱藏的文件。在此之前,可以以一個新的名字來讀文件,還可以以前的名字恢復。當隱藏的文件在名字空間中被刪除以后,它在內存中的元數據即被擦除,這就有效地切斷了他和所有數據塊的聯系。
在一個相似的定期的名字空間檢查中,MASTER確認孤兒數據塊(不屬于任何文件)并擦除他的元數據,在和MASTER的心跳信息交換中,每個服務器報告他所擁有的數據塊,MASTER返回元數據不在內存的數據塊,服務器即可以刪除這些數據塊。
3.5 過時數據的探測
在數據更新時如果服務器停機了,那么他所保存的數據備份就會過時。對每個數據塊,MASTER設置了一個版本號來區別更新過的數據塊和過時的數據塊。
當MASTER授權一個新的lease時,他會增加數據塊的版本號并會通知更新數據備份。MASTER和備份都會記錄下當前的版本號,如果一個備份當時不可用,那么他的版本號不可能提高,當ChunkServer重新啟動并向MASTER報告他的數據塊集時,MASTER就會發現過時的數據。
MASTER在定期的垃圾收集程序中清除過時的備份,在此以前,處于效率考慮,在各客戶及英大使,他會認為根本不存在過時的數據。作為另一個安全措施, MASTER在給客戶及關于數據塊的應答或是另外一個讀取數據的服務器數據是都會帶上版本信息,在操作前客戶機和服務器會驗證版本信息以確保得到的是最新的數據。
4、容錯和診斷
4.1 高可靠性
4.1.1 快速恢復
不管如何終止服務,MASTER和數據塊服務器都會在幾秒鐘內恢復狀態和運行。實際上,我們不對正常終止和不正常終止進行區分,服務器進程都會被切斷而終止??蛻魴C和其他的服務器會經歷一個小小的中斷,然后它們的特定請求超時,重新連接重啟的服務器,重新請求。
4.1.2 數據塊備份
如上文所討論的,每個數據塊都會被備份到放到不同機架上的不同服務器上。對不同的名字空間,用戶可以設置不同的備份級別。在數據塊服務器掉線或是數據被破壞時,MASTER會按照需要來復制數據塊。
4.1.3 MASTER備份
為確??煽啃?,MASTER的狀態、操作記錄和檢查點都在多臺機器上進行了備份。一個操作只有在數據塊服務器硬盤上刷新并被記錄在MASTER和其備份的上之后才算是成功的。如果MASTER或是硬盤失敗,系統監視器會發現并通過改變域名啟動它的一個備份機,而客戶機則僅僅是使用規范的名稱來訪問,并不會發現MASTER的改變。
4.2 數據完整性
每個數據塊服務器都利用校驗和來檢驗存儲數據的完整性。原因:每個服務器隨時都有發生崩潰的可能性,并且在兩個服務器間比較數據塊也是不現實的,同時,在兩臺服務器間拷貝數據并不能保證數據的一致性。
每個Chunk按64kB的大小分成塊,每個塊有32位的校驗和,校驗和和日志存儲在一起,和用戶數據分開。
在讀數據時,服務器首先檢查與被讀內容相關部分的校驗和,因此,服務器不會傳播錯誤的數據。如果所檢查的內容和校驗和不符,服務器就會給數據請求者返回一個錯誤的信息,并把這個情況報告給MASTER??蛻魴C就會讀其他的服務器來獲取數據,而MASTER則會從其他的拷貝來復制數據,等到一個新的拷貝完成時,MASTER就會通知報告錯誤的服務器刪除出錯的數據塊。
附加寫數據時的校驗和計算優化了,因為這是主要的寫操作。我們只是更新增加部分的校驗和,即使末尾部分的校驗和數據已被損壞而我們沒有檢查出來,新的校驗和與數據會不相符,這種沖突在下次使用時將會被檢查出來。
相反,如果是覆蓋現有數據的寫,在寫以前,我們必須檢查第一和最后一個數據塊,然后才能執行寫操作,最后計算和記錄校驗和。如果我們在覆蓋以前不先檢查首位數據塊,計算出的校驗和則會因為沒被覆蓋的數據而產生錯誤。
在空閑時間,服務器會檢查不活躍的數據塊的校驗和,這樣可以檢查出不經常讀的數據的錯誤。一旦錯誤被檢查出來,服務器會拷貝一個正確的數據塊來代替錯誤的。
4.3 診斷工具
廣泛而細致的診斷日志以微小的代價換取了在問題隔離、診斷、性能分析方面起到了重大的作用。GFS服務器用日志來記錄顯著的事件(例如服務器停機和啟動)和遠程的應答。遠程日志記錄機器之間的請求和應答,通過收集不同機器上的日志記錄,并對它們進行分析恢復,我們可以完整地重現活動的場景,并用此來進行錯誤分析。
6 測量
6.1 測試環境
一臺主控機,兩臺主控機備份,16臺數據塊服務器,16臺客戶機。
每臺機器:2塊PIII1.4G處理器,2G內存,2塊80G5400rpm的硬盤,1塊100Mbps全雙工網卡
19臺服務器連接到一個HP2524交換機上,16臺客戶機倆接到領外一臺交換機上,兩臺交換機通過1G的鏈路相連。
Google 2003年關于Google File System的論文原文出處:
http://www.irunnet.com/viewtopic.php?p=913&sid=4f05f5b8a26e7d0b0e2586190c175d0b#913
posted @
2005-11-09 09:29 風蕭蕭 閱讀(585) |
評論 (0) |
編輯 收藏
Confluence 是個Wiki服務器,很不錯,安裝也很簡單。
下載:
http://www.atlassian.com/software/confluence/破解和jira一樣。參考我的另外一篇隨筆:
《破解JIRA》。
posted @
2005-11-08 13:37 風蕭蕭 閱讀(3365) |
評論 (0) |
編輯 收藏
轉自:http://www.softboss.com
10月底,Google在美國《麻省技術評論》、《LinuxJournal》、《Mensa》、《今日物理》等幾本專業雜志上,刊登了一份“Google實驗室能力傾向測試”。 試卷開頭,蠱惑地寫著“試試看!把答案寄回Google,你有希望去Google總部參觀,并成為我們其中一員”。
我看了這些題目,雖然古怪,但是也不算有困難,有興趣的人可以做完了郵寄給google公司,也許會得到一個工作機會呢。
注:不要向我要答案。
1. Solve this cryptic equation, realizing of course that values for M and E could be interchanged. No leading zeros are allowed.
WWWDOT - GOOGLE = DOTCOM
2. Write a haiku describing possible methods for predicting search traffic seasonality.
3. 1 1 1 2 1 1 2 1 1 1 1 1 2 2 1
What is the next line?
4. You are in a maze of twisty little passages, all alike. There is a dusty laptop here with a weak wireless connection. There are dull, lifeless gnomes strolling about. What dost thou do?
A) Wander aimlessly, bumping into obstacles until you are eaten by a grue. B) Use the laptop as a digging device to tunnel to the next level. C) Play MPoRPG until the battery dies along with your hopes. D) Use the computer to map the nodes of the maze and discover an exit path. E) Email your resume to Google, tell the lead gnome you quit and find yourself in whole different world.
5. What's broken with Unix? How would you fix it?
6. On your first day at Google, you discover that your cubicle mate wrote the textbook you used as a primary resource in your first year of graduate school. Do you:
A) Fawn obsequiously and ask if you can have an autograph. B) Sit perfectly still and use only soft keystrokes to avoid disturbing her concentration. C) Leave her daily offerings of granola and English toffee from the food bins.
D) Quote your favorite formula from the textbook and explain how it's now your mantra. E) Show her how example 17b could have been solved with 34 fewer lines of code. 7. Which of the following expresses Google□ over-arching philosophy?
A) "I'm feeling lucky" B) "Don't be evil" C) "Oh, I already fixed that" D) "You should never be more than 50 feet from food" E) All of the above
8. How many different ways can you color an icosahedron with one of three colors on each face?
What colors would you choose?
9. This space left intentionally blank. Please fill it with something that improves upon emptiness.
10.On an infinite, two-dimensional, rectangular lattice of 1-ohm resistors, what is the resistance between two nodes that are a knight's move away?
11.It's 2 PM on a sunny Sunday afternoon in the Bay Area. You're minutes from the Pacific Ocean, redwood forest hiking trails and world class cultural attractions. What do you do?
12.In your opinion, what is the most beautiful math equation ever derived?
13. Which of the following is NOT an actual interest group formed by Google employees?
A. Women's basketball B. Buffy fans C. Cricketeers D. Nobel winners E. Wine club
14.What will be the next great improvement in search technology?
15.What is the optimal size of a project team, above which additional members do not contribute productivity equivalent to the percentage increase in the staff size? A) 1 B) 3 C) 5 D) 11 E) 24
16.Given a triangle ABC, how would you use only a compass and straight edge to find a point P such that triangles ABP, ACP and BCP have equal perimeters? (Assume that ABC is constructed so that a solution does exist.)
17.Consider a function which, for a given whole number n, returns the number of ones required when writing out all numbers between 0 and n. For example, f(13)=6. Notice that f(1)=1. What is the next largest n such that f(n)=n?
18.What's the coolest hack you've ever written?
19.'Tis known in refined company, that choosing K things out of N can be done in ways as many as choosing N minus K from N: I pick K, you the remaining.
Find though a cooler bijection, where you show a knack uncanny, of making your choices contain all K of mine. Oh, for pedantry: let K be no more than half N.
20.What number comes next in the sequence: 10, 9, 60, 90, 70, 66,?
A)96 B) 1000000000000000000000000000000000 0000000000000000000000000000000000 000000000000000000000000000000000 C) Either of the above D) None of the above
21.In 29 words or fewer, describe what you would strive to accomplish if you worked at Google Labs. |
posted @
2005-11-07 09:36 風蕭蕭 閱讀(663) |
評論 (2) |
編輯 收藏
昨天發現缺陷管理工具JIRA,目前版本是3.3.3,安裝使用了一下。感覺很好。
下載地址:
http://www.atlassian.com/software/jira/我下載的是JIRA Enterprise: Evaluation版本,同時申請一個30的Licence。
破解比較簡單,有關Licence的代碼在atlassian-extras-0.7.10.jar中。
1、反編譯包中的文件:com.atlassian.license.DefaultLicense.class。改成下面:
// Decompiled by DJ v3.8.8.85 Copyright 2005 Atanas Neshkov Date: 2005-11-5 17:41:28
// Home Page : http://members.fortunecity.com/neshkov/dj.html - Check often for new version!
// Decompiler options: packimports(3)
// Source File Name: DefaultLicense.java

package com.atlassian.license;

import java.util.*;

// Referenced classes of package com.atlassian.license:
// License, LicenseType

public class DefaultLicense
implements License


{

public DefaultLicense(Date dateCreated, Date datePurchased, String organisation, LicenseType licenseType, int users)

{
this.dateCreated = dateCreated;
this.datePurchased = datePurchased;
this.organisation = organisation;
this.licenseType = licenseType;
this.users = users;
}

public Date getDateCreated()

{
return dateCreated;
}

public Date getDatePurchased()

{
return datePurchased;
}

public String getOrganisation()

{
return organisation;
}

public LicenseType getLicenseType()

{
return licenseType;
}

public String toString()

{
return licenseType.getNiceName() + " licensed to " + organisation;
}

public boolean isExpired()

{
return false;

}

public Date getExpiryDate()

{
return null;
}

public boolean isLicenseLevel(Collection levels)

{
for(Iterator iterator = levels.iterator(); iterator.hasNext();)

{
String level = (String)iterator.next();
if(getLicenseType().getDescription().toLowerCase().indexOf(level.toLowerCase()) != -1)
return true;
}

return false;
}

public int getUsers()

{
if(licenseType.requiresUserLimit())
return users;
else
return -1;
}

public static long EVALUATION_PERIOD = 0x9fa52400L;
protected Date dateCreated;
protected Date datePurchased;
protected String organisation;
protected LicenseType licenseType;
private int users;

}
其實就該了兩個方法:
public boolean isExpired()

{
return false;

}

public Date getExpiryDate()

{
return null;
}
2、把編譯好的class文件復制到atlassian-extras-0.7.10.jar中,覆蓋原來文件。
3、啟動服務器,成功。
我把我破解后的class附上:http://www.tkk7.com/Files/freddychu/DefaultLicense.zip。
如果不能下,請留下email.
posted @
2005-11-05 18:18 風蕭蕭 閱讀(7544) |
評論 (51) |
編輯 收藏
Apache的網站
http://www.apache.org/ 訪問不了,我正在看xmlBean啊。難道沒錢請網管?呵呵 ^_^
posted @
2005-10-27 20:30 風蕭蕭 閱讀(1120) |
評論 (0) |
編輯 收藏
這周嘗試使用了一下Acegi安全框架,有了些膚淺的認識。
1、這個框架還需要不斷完善,而且這個項目也在不斷進行中。比如:看到以前的例子,版本是0.6的,需要在web.xml里配置多個filter,到了0.8.3,就只要配置一個filter,把以前的多個filter移到了spring的配置文件中實現了。還有userCache的實現也變化了。
2、配置還是有些復雜。在spring的配置文件里要寫不少bean。參見
整合前臺技術acegi+spring+struts 。
3、如何實現角色的動態定義,我還沒找到相關實現,似乎目前不支持。
4、存放用戶信息在表users,授權信息放在authorities表。在我們實際開發當中往往這兩個表非常大,字段很多。這里就需要做些適當的擴展咯。
這個框架整體還是非常靈活的,值得我們在些輕量級的應用中使用。
posted @
2005-10-27 12:58 風蕭蕭 閱讀(1459) |
評論 (3) |
編輯 收藏