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

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

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

    qileilove

    blog已經(jīng)轉(zhuǎn)移至github,大家請(qǐng)?jiān)L問(wèn) http://qaseven.github.io/

    用集算器實(shí)現(xiàn)跨數(shù)據(jù)庫(kù)關(guān)聯(lián)報(bào)表

    實(shí)際應(yīng)用中很多報(bào)表的數(shù)據(jù)來(lái)源于多個(gè)不同類(lèi)型的數(shù)據(jù)庫(kù),報(bào)表數(shù)據(jù)源跨數(shù)據(jù)庫(kù)是報(bào)表開(kāi)發(fā)中的常態(tài)。目前實(shí)現(xiàn)這類(lèi)跨庫(kù)關(guān)聯(lián)報(bào)表的方式有多種,但都會(huì)存在這樣那樣的問(wèn)題。
      使用報(bào)表工具自身多源關(guān)聯(lián)功能
      現(xiàn)在大多數(shù)主流報(bào)表工具都支持多數(shù)據(jù)源關(guān)聯(lián),這在某些方面確實(shí)為報(bào)表用戶帶來(lái)了便利。然而我們也經(jīng)常會(huì)遇到通過(guò)報(bào)表自身的多源關(guān)聯(lián)功能很難實(shí)現(xiàn)一些跨庫(kù)關(guān)聯(lián)的報(bào)表(由于數(shù)據(jù)結(jié)構(gòu)和業(yè)務(wù)本身決定)。這當(dāng)然容易理解,報(bào)表工具主要是來(lái)做數(shù)據(jù)展現(xiàn)的,而對(duì)數(shù)據(jù)計(jì)算本身來(lái)說(shuō)并不擅長(zhǎng)。
      即使有的能實(shí)現(xiàn),在報(bào)表中做跨庫(kù)關(guān)聯(lián)計(jì)算的效率也較低,遠(yuǎn)遠(yuǎn)不如數(shù)據(jù)庫(kù)的性能,而且經(jīng)常因?yàn)樵趯?shí)現(xiàn)過(guò)程中使用了大量隱藏行列進(jìn)一步降低報(bào)表性能并加大內(nèi)存占用。
      于是一般會(huì)采用下面的兩種方式。
      將數(shù)據(jù)統(tǒng)一到一個(gè)數(shù)據(jù)庫(kù)中
      將不同數(shù)據(jù)庫(kù)的數(shù)據(jù)統(tǒng)一到一個(gè)數(shù)據(jù)庫(kù)中,這種做法在各類(lèi)應(yīng)用中很常見(jiàn),目的是使用數(shù)據(jù)庫(kù)(SQL)強(qiáng)大的計(jì)算能力。然而,這種做法會(huì)增加額外的成本開(kāi)銷(xiāo),將多個(gè)數(shù)據(jù)庫(kù)中的數(shù)據(jù)統(tǒng)一到一個(gè)數(shù)據(jù)庫(kù)中勢(shì)必會(huì)占用昂貴的數(shù)據(jù)庫(kù)空間,并造成該數(shù)據(jù)庫(kù)數(shù)據(jù)過(guò)多、管理困難、壓力增大等問(wèn)題,而且還可能負(fù)擔(dān)額外的數(shù)據(jù)庫(kù)購(gòu)買(mǎi)成本以及管理成本。另外,完成ETL遷移數(shù)據(jù)也是一份不小的工作量,對(duì)實(shí)時(shí)性要求較高的報(bào)表還得用觸發(fā)器方式來(lái)做ETL(一般ETL是定時(shí)的),會(huì)嚴(yán)重影響原數(shù)據(jù)庫(kù)的性能。
      使用高級(jí)語(yǔ)言實(shí)現(xiàn)跨庫(kù)關(guān)聯(lián)為報(bào)表準(zhǔn)備數(shù)據(jù)
      基于上面提到兩種方式中存在的問(wèn)題,有些用戶使用高級(jí)語(yǔ)言(Java等)編程完成跨庫(kù)運(yùn)算,為報(bào)表自定義數(shù)據(jù)源。這種做法的優(yōu)點(diǎn)是靈活,理論上任何運(yùn)算通過(guò)程序都能完成;缺點(diǎn)是太難寫(xiě)。很多像Java這樣的高級(jí)語(yǔ)言缺乏對(duì)集合運(yùn)算的有效支持,沒(méi)有相應(yīng)的類(lèi)庫(kù),導(dǎo)致完成個(gè)簡(jiǎn)單的group也要寫(xiě)很多(循環(huán))代碼,更不用說(shuō)關(guān)聯(lián)以后還要再進(jìn)行分組匯總等其他運(yùn)算了。
      這種情況下,使用集算器來(lái)實(shí)現(xiàn)跨庫(kù)關(guān)聯(lián)報(bào)表就是個(gè)不錯(cuò)的選擇。
      集算器如何實(shí)現(xiàn)跨庫(kù)關(guān)聯(lián)報(bào)表?
      我們通過(guò)一個(gè)例子來(lái)看集算器是如何快速實(shí)現(xiàn)跨庫(kù)關(guān)聯(lián)報(bào)表的。
      業(yè)務(wù)描述
      企業(yè)員工每月應(yīng)發(fā)工資跟員工的基本工資、考勤以及績(jī)效有關(guān),考勤信息來(lái)源于人力部門(mén)的考勤系統(tǒng)(hsql數(shù)據(jù)庫(kù)),基本工資和績(jī)效信息則存儲(chǔ)在財(cái)務(wù)系統(tǒng)(mysql數(shù)據(jù)庫(kù))中。需要將這兩類(lèi)信息合起來(lái)計(jì)算員工的工資。
      實(shí)現(xiàn)步驟
      編寫(xiě)腳本(crossDB.dfx)完成跨庫(kù)關(guān)聯(lián)計(jì)算,為報(bào)表準(zhǔn)備數(shù)據(jù)
      
      在A1、A2中通過(guò)connect分別連接hsql和mysql數(shù)據(jù)源
      在A3、A4、A5中通過(guò)query語(yǔ)句分別從兩個(gè)數(shù)據(jù)庫(kù)中取出用到的數(shù)據(jù),此時(shí)數(shù)據(jù)已全部取出,不再需要與數(shù)據(jù)庫(kù)交互,在A6、A7中關(guān)閉兩個(gè)數(shù)據(jù)庫(kù)連接
      在A8中使用join完成三表的連接
      在A9中計(jì)算應(yīng)發(fā)工資,算法為:基本工資*(1-考勤系數(shù)+績(jī)效系數(shù))
      最后通過(guò)A10的result生成供報(bào)表使用的結(jié)果集
      報(bào)表調(diào)用集算器腳本完成報(bào)表展現(xiàn)
      集算器的類(lèi)包封裝成標(biāo)準(zhǔn)的JDBC,允許報(bào)表工具以類(lèi)存儲(chǔ)過(guò)程的調(diào)用方式調(diào)用集算器腳本,如本例中在報(bào)表工具中像配置數(shù)據(jù)庫(kù)連接一樣配置起好集算器的JDBC,然后建立存儲(chǔ)過(guò)程數(shù)據(jù)集后使用 call crossDB()即可完成調(diào)用。
     這里以BIRT為例說(shuō)明調(diào)用過(guò)程:
      1、 復(fù)制集算器JDBC驅(qū)動(dòng)包到相應(yīng)目錄
      2、 配置報(bào)表數(shù)據(jù)源
      
      3、 設(shè)置DataSet,調(diào)用集算器腳本
      
      簡(jiǎn)單幾步完成調(diào)用,BIRT即可使用集算器的計(jì)算結(jié)果直接展現(xiàn)輸出。
      結(jié)語(yǔ)
      通過(guò)這個(gè)例子可以看到,集算器擅長(zhǎng)完成跨庫(kù)計(jì)算,并將計(jì)算后的結(jié)果以標(biāo)準(zhǔn)ResultSet方式返回為報(bào)表提供數(shù)據(jù)源,而報(bào)表采用類(lèi)存儲(chǔ)過(guò)程調(diào)用的方式調(diào)用集算器腳本非常簡(jiǎn)單。
      還有一個(gè)重點(diǎn)需要關(guān)注,就是價(jià)格。集算器是個(gè)需要付費(fèi)的商業(yè)軟件,好在只針對(duì)大數(shù)據(jù)的集群才收費(fèi),用作報(bào)表數(shù)據(jù)源功能是免費(fèi)的,不需要增加成本就能輕松解決多數(shù)據(jù)庫(kù)關(guān)聯(lián)報(bào)表問(wèn)題。

    posted @ 2014-08-07 12:17 順其自然EVO 閱讀(811) | 評(píng)論 (0)編輯 收藏

    iOS中系統(tǒng)自帶正則表達(dá)式的應(yīng)用

    //組裝一個(gè)字符串,把里面的網(wǎng)址解析出來(lái)
    NSString *urlString = @"sfdshttp://www.baidu.com";
    NSError *error;
    //http+:[^\\s]* 這是檢測(cè)網(wǎng)址的正則表達(dá)式
    NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"http+:[^\\s]*" options:0 error:&error];
    if (regex != nil) {
    NSTextCheckingResult *firstMatch = [regex firstMatchInString:urlString options:0 range:NSMakeRange(0, [urlString length])];
    if (firstMatch) {
    NSRange resultRange = [firstMatch rangeAtIndex:0];
    //從urlString中截取數(shù)據(jù)
    NSString *result = [urlString substringWithRange:resultRange];
    NSLog(@"%@",result);
    }
    }
      輸出結(jié)果為:
      [1302:403] http://www.baidu.com
      可見(jiàn)通過(guò)iOS自帶的正則表達(dá)式的類(lèi)可以達(dá)到過(guò)濾和篩選字符串的功能。
      還有其他兩種正則表達(dá)式的用法:
      1.利用NSPredicate(謂詞)匹配
      例如匹配有效郵箱:
      NSString *email = @“nijino_saki@163.com”;
      NSString *regex = @"[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,4}";
      NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", regex];
      BOOL isValid = [predicate evaluateWithObject:email];
      謂詞匹配比較靈活,但是需要有謂詞的相關(guān)知識(shí)。
      2.利用rangeOfString:option:直接查找
      NSString *searchText = @"http:// Do any additional setup after loading the view, typically from a nib.";
      NSRange range = [searchText rangeOfString:@"(?:[^,])*\\." options:NSRegularExpressionSearch];
      if (range.location != NSNotFound) {
      NSLog(@"%@", [searchText substringWithRange:range]);
      }
      options中設(shè)定NSRegularExpressionSearch就是表示利用正則表達(dá)式匹配,會(huì)返回第一個(gè)匹配結(jié)果的位置。
      小結(jié):
      第一種匹配需要學(xué)習(xí)NSPredicate的寫(xiě)法,需要查閱蘋(píng)果相關(guān)技術(shù)文檔;如果只關(guān)心第一個(gè)匹配的結(jié)果,第二種匹配較為簡(jiǎn)潔;如果需要匹配多個(gè)結(jié)果,同時(shí)匹配多次,第三種方式效率會(huì)更高。

    posted @ 2014-08-07 12:17 順其自然EVO 閱讀(479) | 評(píng)論 (0)編輯 收藏

    自動(dòng)化測(cè)試之java的job任務(wù)

     java單元測(cè)試中,經(jīng)常寫(xiě)單元測(cè)試方法,測(cè)試job任務(wù)。而這些job任務(wù),對(duì)應(yīng)電子商務(wù)等流水系統(tǒng)來(lái)說(shuō),比較常見(jiàn)。 它們常用的特點(diǎn)是:實(shí)現(xiàn)不同系統(tǒng)之間的數(shù)據(jù)庫(kù)的流向。執(zhí)行此job,把系統(tǒng)A的數(shù)據(jù)庫(kù)執(zhí)行到系統(tǒng)B的數(shù)據(jù)庫(kù)的表中。 中間會(huì)有方法進(jìn)行相關(guān)的處理。比如以下是個(gè)單元測(cè)試,測(cè)試生成的job。
    @Test
    public void testCreateSettlement() throws ParseException {
    //createSettlementTask.createSettlement(null);
    Calendar ca = Calendar.getInstance();
    ca.add(Calendar.DAY_OF_MONTH, -17);
    SettlementResult res = createSettlementFacade.createSettlementOrder(ca.getTime());
    System.out.println("res->"+res);
    }
      此提現(xiàn)job的作用是:把某個(gè)系統(tǒng)A的訂單,執(zhí)行此job后,把數(shù)據(jù)處理后,插入到系統(tǒng)B后生成結(jié)算單。
      那么這個(gè)是功能測(cè)試時(shí),需要驗(yàn)證系統(tǒng)A的訂單數(shù)據(jù),是否都生成到了系統(tǒng)B的結(jié)算單呢。
      首先需要準(zhǔn)備各種訂單數(shù)據(jù),生成不同的結(jié)算單。 手工測(cè)試的壓力太大了。
      后來(lái)考慮用junit的單元自動(dòng)化測(cè)試的方法實(shí)現(xiàn)。
    @before
    public void before() {
    執(zhí)行此job之前的數(shù)據(jù)準(zhǔn)備的封裝
    }
    @test
    public void test() {
    equals(request,response)
    }
    @after
    public void after() {
    執(zhí)行此job之后的數(shù)據(jù)變化
    }
      其實(shí)難點(diǎn)還是在于用例設(shè)計(jì)和數(shù)據(jù)準(zhǔn)備這塊。怎么樣的用例可以作為一個(gè)場(chǎng)景。而且能覆蓋到提交的代碼的更新。

    posted @ 2014-08-07 10:50 順其自然EVO 閱讀(256) | 評(píng)論 (0)編輯 收藏

    防火墻的基礎(chǔ)配置管理

      開(kāi)局ASA1
      #/mnt/disk0/lina_monitor ciscoasa
      > enable
      Invalid password
      Password:
      ciscoasa#
      配置IP
    R1(config)#int fa0/0
    R1(config-if)#ip address 11.0.0.1 255.255.255.0
    R1(config-if)#no shut
    ciscoasa(config)# int e0/0
    ciscoasa(config-if)# nameif inside
    INFO: Security level for "inside" set to 100 by default.
    ciscoasa(config-if)# ip address 11.0.0.2 255.255.255.0
    ciscoasa(config-if)# no shut
    ciscoasa(config)# int e0/1
    ciscoasa(config-if)# nameif outside
    INFO: Security level for "outside" set to 0 by default.
    ciscoasa(config-if)# ip address 12.0.0.1 255.255.255.0
    ciscoasa(config-if)# no shut
    R2(config)#int fa0/0
    R2(config-if)#ip address 12.0.0.2 255.255.255.0
    R2(config-if)#no shut
      指定靜態(tài)路由:
      R1(config-if)#ip route 12.0.0.0 255.255.255.0 11.0.0.2
      R2(config)#ip route 11.0.0.0 255.255.255.0 12.0.0.1
      驗(yàn)證靜態(tài)路由:
      默認(rèn)情況下,ASA對(duì)TCP和UDP協(xié)議提供狀態(tài)化連接,ICMP協(xié)議提供非狀態(tài)化的連接(防火墻由于不記錄路由所以將數(shù)據(jù)丟掉);
      由于ping命令使用的是ICMP協(xié)議,所以R1ping外網(wǎng)ping不通。
      在R2上開(kāi)遠(yuǎn)程,驗(yàn)證ASA對(duì)TCP協(xié)議的狀態(tài)化連接:
      R2(config)#line vty 0 4
      R2(config-line)#password abc
      R2(config-line)#login
      在R1上遠(yuǎn)程R2

    結(jié)論:以上表明ASA對(duì)TCP協(xié)議的狀態(tài)化連接;
      外網(wǎng)有時(shí)會(huì)主動(dòng)要求訪問(wèn)內(nèi)網(wǎng),由于接口安全級(jí)別的默認(rèn)規(guī)則,允許出站連接(從高到低級(jí)別允許);禁止入站連接(從低到高級(jí)別禁止)
      ,所以外網(wǎng)主動(dòng)連接內(nèi)網(wǎng)時(shí)防火墻會(huì)阻擋數(shù)據(jù)的傳輸;
      因此用配置ACL解決:
      ciscoasa(config)# access-list asa_acl permit tcp host 12.0.0.2 any
      ciscoasa(config)# access-Group asa_acl in interface outside
      實(shí)驗(yàn)驗(yàn)證:
      在R1上配置遠(yuǎn)程:
      R1(config)#line vty 0 4
      R1(config-line)#password abc
      R1(config-line)#login
      到此R1仍舊可以正常訪問(wèn)R2,如下:
      結(jié)論:證明在R2給R1回包的時(shí)候,防火墻對(duì)ACL列表和Conn表同時(shí)檢測(cè),如果有一個(gè)規(guī)則匹配就過(guò);
      在R2上配置環(huán)回口,驗(yàn)證以上結(jié)論:
      R2(config)#int loo 0
      R2(config-if)#ip address  2.2.2.2 255.255.255.255
      R2(config-if)#no shut
      配置靜態(tài)路由:
      R1(config)#ip route 2.2.2.2 255.255.255.255 11.0.0.2
      ciscoasa(config)# route outside 2.2.2.2 255.255.255.255 12.0.0.2
      在ACL列表“asa_acl”中配置允許host2.2.2.2/24通過(guò)防火墻;
      ciscoasa(config)# access-list asa_acl permit tcp 2.2.2.2 255.255.255.255 any
      ciscoasa(config)# access-group asa_acl in interface outside
      用R1遠(yuǎn)程R2:

    posted @ 2014-08-07 10:49 順其自然EVO 閱讀(183) | 評(píng)論 (0)編輯 收藏

    QC缺陷管理常用操作

     1、QC建項(xiàng)目
      使用管理員賬號(hào)登錄,創(chuàng)建項(xiàng)目→然后選擇想創(chuàng)建的項(xiàng)目,點(diǎn)擊下一步。
      輸入項(xiàng)目名稱(chēng),點(diǎn)擊下一步。會(huì)出現(xiàn)要連接的數(shù)據(jù)庫(kù)和服務(wù)器(可選),點(diǎn)擊下一步即可選擇用戶,再點(diǎn)擊下一步即可創(chuàng)建項(xiàng)目成功。
      2、新建用戶
      系統(tǒng)管理員賬號(hào)登錄,站點(diǎn)用戶→點(diǎn)擊彈出添加用戶窗口,輸入要添加的用戶信息后點(diǎn)擊確定即可;密碼設(shè)置在站點(diǎn)用戶左側(cè)點(diǎn)擊要設(shè)置密碼的用戶,點(diǎn)擊密碼后重設(shè)即可。
      3、選擇項(xiàng)目用戶
      1、如果在創(chuàng)建項(xiàng)目時(shí)未選擇項(xiàng)目用戶,登錄管理員賬號(hào),選擇需要修改用戶的項(xiàng)目,然后項(xiàng)目用戶→可以選擇在列表添加還是從另外一個(gè)項(xiàng)目復(fù)制(如果沒(méi)有太大出入可以復(fù)制然后再進(jìn)行修改)。
      
      添加即可發(fā)現(xiàn)界面左側(cè)有用戶選擇,雙擊或者選中點(diǎn)擊箭頭都可以添加進(jìn)去。
      
      注意項(xiàng)目管理員的勾選,不用勾上了不是管理員的克。
    4、Qc自定義字段
      對(duì)項(xiàng)目用戶進(jìn)行分組和各項(xiàng)字段自定義,用此項(xiàng)目給予了管理員權(quán)限的賬號(hào)登錄此項(xiàng)目。
      工具→自定義→自定義項(xiàng)目實(shí)體,如狀態(tài),可以點(diǎn)擊【轉(zhuǎn)至列表】進(jìn)行添加刪除等操作。
     
      5、給用戶不同權(quán)限
      項(xiàng)目管理員登錄此項(xiàng)目,自定義→設(shè)置組→新建。可以設(shè)置為開(kāi)發(fā)組、測(cè)試組、項(xiàng)目管理組然后給予不同的權(quán)限。然后可以根據(jù)分組把不同的用戶歸入相應(yīng)的組內(nèi)。
      
      6、未點(diǎn)擊注銷(xiāo)直接關(guān)掉網(wǎng)頁(yè)
      會(huì)出現(xiàn)問(wèn)題,有時(shí)候是登錄出現(xiàn)問(wèn)題,或者修改的時(shí)候無(wú)法修改。使用qc管理員賬號(hào)登錄→點(diǎn)擊要斷掉連接→點(diǎn)擊斷開(kāi)連接即可。
      
      Ps、1、登錄時(shí)不用勾選自動(dòng)登錄2、大多數(shù)修改之后注意點(diǎn)擊右下角的保存按鈕。wKioL1PYoE6zacJ4AAAKq4DwI-Y919.gif俺老是忘記保存~~~

    posted @ 2014-08-07 10:48 順其自然EVO 閱讀(332) | 評(píng)論 (0)編輯 收藏

    iOS開(kāi)發(fā)那些事--OCUnit測(cè)試框架

    使用OCUnit測(cè)試框架iOS單元測(cè)試框架
      原則上,是否使用測(cè)試框架都不會(huì)影響單元測(cè)試結(jié)果,但是“工欲善其事,必先利其器”使用單元測(cè)試框架更便于我們測(cè)試和分析結(jié)果。
      主要的iOS單元測(cè)試框架有:
      OCUnit,是開(kāi)源測(cè)試框架,與Xcode工具集成在一起使用非常方便,測(cè)試報(bào)告以文本形式輸出到輸出窗口;
      GHUnit,是開(kāi)源測(cè)試框架,它可以將測(cè)試報(bào)告以應(yīng)用形式可視化輸出到設(shè)備或模擬器上,也可以以文本形式輸出到輸出窗口;GHUnit可以測(cè)試OCUnit編寫(xiě)的測(cè)試用例
      OCMock,是開(kāi)源測(cè)試框架,它主要為測(cè)試提供Mock對(duì)象(偽對(duì)象)。
      添加OCUnit到工程
      添加OCUnit到工程中有兩種方法,一種是在創(chuàng)建工程時(shí)添加,勾選“include Unit Tests”;另一種是在現(xiàn)有工程中添加“Cocoa Touch Unit Testing Bundle”Target來(lái)實(shí)現(xiàn)。下面我們?cè)敿?xì)介紹這兩種添加過(guò)程。
      1、創(chuàng)建工程時(shí)候勾選“include Unit Tests”
      該種方式添加的單元測(cè)試屬于應(yīng)用測(cè)試(Application Testing)。在創(chuàng)建一個(gè)工程時(shí),如果采用“Single View Application”模板,在選項(xiàng)中勾選“include Unit Tests”即可在工程中添加OCUnit框架。
      
      工程創(chuàng)建完,在導(dǎo)航面板中會(huì)多一個(gè)PITaxTests組(<工程名>Tests),包含PITaxTests測(cè)試類(lèi)。在右邊的Target欄中多了一個(gè)PITaxTests Target。
      
      但是打開(kāi)Scheme列表還只有一個(gè)PITax,這是我們需要注意的。運(yùn)行它可以通過(guò):選擇菜單Product→Test或工具欄中Test按鈕(下拉Run按鈕選擇)或快捷鍵command+U等幾種方式。
      如果打開(kāi)Frameworks組會(huì)發(fā)現(xiàn)添加了SenTestingKit.framework,SenTestingKit.framework就 是OCUnit框架。因?yàn)閱卧獪y(cè)試框架一般命名為xUnit,如Java的單元測(cè)試框架是JUnit,.NET單元測(cè)試框架是NUnit等,OCUnit 是Objective-C單元測(cè)試框架之意。
      2、現(xiàn)有工程中添加Target實(shí)現(xiàn)
      該種方式添加的單元測(cè)試,屬于邏輯測(cè)試(Logic Testing)。在一個(gè)現(xiàn)有工程中,選擇菜單File→New→Target…,選擇模板iOS→Other中的 “Cocoa Touch Unit Testing Bundle”。
      
      點(diǎn)擊Next按鈕,在Product Name項(xiàng)目中輸入LogicTest,創(chuàng)建完成后,在導(dǎo)航面板中多出了一個(gè)LogicTest組,包含LogicTest測(cè)試類(lèi)。在右邊的Target欄中多了一個(gè)LogicTest Target。
      
     與上一種添加方式不同的是,在Scheme列表中會(huì)添加一個(gè)LogicTest,這也是我們需要注意的,這也是應(yīng)用單元測(cè)試和邏輯單元測(cè)試的另一個(gè) 不同之處。運(yùn)行它需要選擇Scheme中LogicTest的iPhone 6.0 Simulator(或iPad 6.0 Simulator)運(yùn)行,但是不能選擇iOS Device,邏輯單元測(cè)試只能在模擬器中運(yùn)行。然后再選擇菜單Product→Test、工具欄中Test按鈕(下拉Run按鈕選擇)和快捷鍵 command+U等幾種方式運(yùn)行。
      無(wú)論那種方式添加,默認(rèn)生成的測(cè)試類(lèi)基本都是一樣的,下面代碼是默認(rèn)生成的LogicTest測(cè)試類(lèi)中的LogicTest.h和LogicTest.m文件。
    //
    //  LogicTest.h
    //  LogicTest
    //
    #import <SenTestingKit/SenTestingKit.h>
    @interface LogicTest : SenTestCase
    @end
    //
    //  LogicTest.m
    //  LogicTest
    //
    #import “LogicTest.h”
    @implementation LogicTest
    - (void)setUp
    {
    [super setUp];
    // Set-up code here.
    }
    - (void)tearDown
    {
    // Tear-down code here.
    [super tearDown];
    }
    - (void)testExample
    {
    STFail(@”Unit tests are not implemented yet in LogicTest”);
    }
    @end
      作為OCUnit測(cè)試類(lèi)需要引入<SenTestingKit/SenTestingKit.h>頭文件,并繼承 SenTestCase父類(lèi)。testExample方法是一般的測(cè)試方法,方法名必須test開(kāi)頭,測(cè)試方法的個(gè)數(shù)沒(méi)有限制,方法中STFail是 OCUnit框架定義的一個(gè)宏,是無(wú)條件斷言失敗,實(shí)際使用時(shí)候要修改這個(gè)方法中的代碼。
      在m文件中需要重新方法setUp和tearDown,我們自己編寫(xiě)的測(cè)試類(lèi)一樣,setUp方法是初始化方法,tearDown方法是釋放資源的 方法,setUp和tearDown方法在每次調(diào)用測(cè)試方法之前和之后調(diào)用,因此在測(cè)試類(lèi)運(yùn)行的生命周期中這兩個(gè)方法可能多次運(yùn)行,它們的時(shí)序圖
      

    posted @ 2014-08-07 10:46 順其自然EVO 閱讀(249) | 評(píng)論 (0)編輯 收藏

    為什么谷歌要執(zhí)行嚴(yán)格的代碼編寫(xiě)規(guī)范

    我們?cè)?a target="_self" style="word-break: break-all; color: #202859; line-height: normal !important;">谷歌所做事情中另外一個(gè)讓我感到異常有效、有用的制度是嚴(yán)格的編碼規(guī)范
      在到Google工作之前,我一直認(rèn)為編碼規(guī)范沒(méi)有什么用處。我堅(jiān)信這些規(guī)范都是官僚制度下產(chǎn)生的浪費(fèi)大家的編程時(shí)間、影響人們開(kāi)發(fā)效率的東西。
      我是大錯(cuò)特錯(cuò)了。
      在谷歌,我可以查看任何的代碼,進(jìn)入所有谷歌的代碼庫(kù),我有權(quán)查看它們。事實(shí)上,這種權(quán)限是很少人能擁有的。但是,讓我感到驚訝的卻是,如此多的編碼規(guī)范—縮進(jìn),命名,文件結(jié)構(gòu),注釋風(fēng)格—這一切讓我出乎意料的輕松的閱讀任意一段代碼,并輕易的看懂它們。這讓我震驚—因?yàn)槲乙詾檫@些規(guī)范是微不足道的東西。它們不可能有這么大的作用—但它們卻起到了這么大的作用。當(dāng)你發(fā)現(xiàn)只通過(guò)看程序的基本語(yǔ)法結(jié)構(gòu)就能讀懂一段代碼,這種時(shí)間上的節(jié)省不能不讓人震撼!
      反對(duì)編碼規(guī)范的人很多,下面是一些常見(jiàn)的理由,對(duì)于這些理由,我以前是深信不疑。
      這是浪費(fèi)時(shí)間!
      我是一個(gè)優(yōu)秀的程序員,我不愿意浪費(fèi)時(shí)間干這些愚蠢的事。我的技術(shù)很好,我可以寫(xiě)出清晰的、易于理解的代碼。為什么我要浪費(fèi)時(shí)間遵守這些愚蠢的規(guī)范?答案是:統(tǒng)一是有價(jià)值的。就像我前面說(shuō)的—你看到的任何的一行代碼—不論是由你寫(xiě)的,還是由你身邊的同事,還是由一個(gè)跟你相差11個(gè)時(shí)區(qū)的距離人寫(xiě)的—它們都有統(tǒng)一的結(jié)構(gòu),相同的命名規(guī)范—這帶來(lái)的效果是巨大的。你只需要花這么少的功夫就能看懂一個(gè)你不熟悉(或完全未見(jiàn)過(guò))的程序,因?yàn)槟阋灰?jiàn)它們就會(huì)覺(jué)得面熟。
      我是個(gè)藝術(shù)家!
      這種話很滑稽,但它反映了一種常見(jiàn)的抱怨。我們程序員對(duì)于自己的編碼風(fēng)格通常懷有很高的自負(fù)。我寫(xiě)出的的代碼的確能反映出我的一些特質(zhì),它是我思考的一種體現(xiàn)。它是我的技能和 創(chuàng)造力的印證。如果你強(qiáng)迫我遵守什么愚蠢的規(guī)范,這是在打壓我的創(chuàng)造力。可問(wèn)題是,你的風(fēng)格里的重要的部分,它對(duì)你的思想和創(chuàng)造力的體現(xiàn),并不是藏身于這些微不足道的句法形式里。(如果是的話,那么,你是一個(gè)相當(dāng)糟糕的程序員。)規(guī)范事實(shí)上可以讓人們可以更容易的看出你的創(chuàng)造力—因?yàn)樗麄兛疵靼琢四愕淖髌罚藗儗?duì)你的認(rèn)識(shí)不會(huì)因不熟悉的編碼形式而受到干擾。
      所有人都能穿的鞋不會(huì)合任何人的腳!
      如果你使用的編碼規(guī)范并不是為你的項(xiàng)目專(zhuān)門(mén)設(shè)計(jì)的,它對(duì)你的項(xiàng)目也許并不是最佳方案。這 沒(méi)事。同樣,這只是語(yǔ)法:非最優(yōu)并不表示是 不好。對(duì)你的項(xiàng)目來(lái)說(shuō)它不是最理想的,但并不能表明它不值得遵守。不錯(cuò),對(duì)于你的項(xiàng)目,你并沒(méi)有從中獲得該有的好處,但對(duì)于一個(gè)大型公司來(lái)說(shuō),它帶來(lái)的好處是巨大的。除此之外,專(zhuān)門(mén)針對(duì)某個(gè)項(xiàng)目制定編碼規(guī)范一般效果會(huì)更好。一個(gè)項(xiàng)目擁有自己的編碼風(fēng)格無(wú)可厚非。但是,根據(jù)我的經(jīng)驗(yàn),在一個(gè)大型公司里,你最好有一個(gè)統(tǒng)一的編碼規(guī)范,特定項(xiàng)目可以擴(kuò)展自己特定的項(xiàng)目方言和結(jié)構(gòu)。
      我善長(zhǎng)制定編碼規(guī)范!
      這應(yīng)該是最常見(jiàn)的抱怨類(lèi)型了。它是其它幾種反對(duì)聲音的混合體,但它卻有自身態(tài)度的直接表現(xiàn)。有一部分反對(duì)者深信,他們是比制定編碼規(guī)范的人更好的程序員,俯身屈從這些小學(xué)生制定的規(guī)范,將會(huì)降低代碼的質(zhì)量。對(duì)于此,客氣點(diǎn)說(shuō),就是胡扯。純屬傲慢自大,荒唐可笑。事實(shí)上他們的意思就是, 沒(méi)有人配得上給他們制定規(guī)范,對(duì)他們的代碼的任何改動(dòng)都是一種破壞。如果參照任何一種合理的編碼規(guī)范,你都不能寫(xiě)出合格的代碼,那只能說(shuō)你是個(gè)爛程序員。
      當(dāng)你按照某種編碼規(guī)范進(jìn)行編程時(shí),必然會(huì)有某些地方讓你搖頭不爽。肯定會(huì)在某些地方你的編碼風(fēng)格會(huì)優(yōu)于這些規(guī)范。但是,這不重要。在某些地方,編碼規(guī)范也有優(yōu)于你的編程風(fēng)格的時(shí)候。但是,這也不重要。只要這規(guī)范不是完全的不可理喻,在程序的可理解性上得到的好處會(huì)大大的補(bǔ)償你的損失。
      但是,如果編碼規(guī)范真的是完全不可理喻呢?
      如果是這樣,那就麻煩了:你被糟蹋了。但這并不是因?yàn)檫@荒謬的編碼規(guī)范。這是因?yàn)槟阍诟蝗捍镭浺黄鸸ぷ鳌O胪ㄟ^(guò)把編碼規(guī)范制定的足夠荒謬來(lái)阻止一個(gè)優(yōu)秀的程序員寫(xiě)出優(yōu)秀的代碼,這需要努力。這需要一個(gè)執(zhí)著的、冷靜的、進(jìn)了水的大腦。如果這群蠢貨能強(qiáng)行頒布不可用的編碼規(guī)范,那他們就能干出其它很多傻事情。如果你為這群蠢貨干活,你的確被糟蹋了—不論你干什么、有沒(méi)有規(guī)范。(我并不是說(shuō)罕有公司被一群蠢貨管理;事實(shí)很不幸,我們這個(gè)世界從來(lái)就不缺蠢貨,而且很多蠢貨都擁有自己的公司。)

    posted @ 2014-08-07 10:44 順其自然EVO 閱讀(156) | 評(píng)論 (0)編輯 收藏

    避免測(cè)試用例設(shè)計(jì)的五大誤區(qū)

    1、能發(fā)現(xiàn)到目前為止沒(méi)有發(fā)現(xiàn)的缺陷的用例是好的用例:
      首先要申明,其實(shí)這句話是十分有道理的,但我發(fā)現(xiàn)很多人都曲解了這句話的原意,一心要設(shè)計(jì)出發(fā)現(xiàn)“難于發(fā)現(xiàn)的缺陷”而陷入盲目的片面中去,忘記了測(cè)試的目的所在,這是十分可怕的。我傾向于將測(cè)試用例當(dāng)作一個(gè)集合來(lái)認(rèn)識(shí),對(duì)它的評(píng)價(jià)也只能對(duì)測(cè)試用例的集合來(lái)進(jìn)行,測(cè)試本身是一種“V&amp;V”的活動(dòng),測(cè)試需要保證以下兩點(diǎn):
      * 程序做了它應(yīng)該做的事情
      * 程序沒(méi)有做它不該做的事情
      因此,作為測(cè)試實(shí)施依據(jù)的測(cè)試用例,必須要能完整覆蓋測(cè)試需求,而不應(yīng)該針對(duì)單個(gè)的測(cè)試用例去評(píng)判好壞。
      2、測(cè)試用例應(yīng)該詳細(xì)記錄所有的操作信息,使一個(gè)沒(méi)有接觸過(guò)系統(tǒng)的人員也能進(jìn)行測(cè)試;
      不知道國(guó)內(nèi)有沒(méi)有公司真正做到這點(diǎn),或者說(shuō),不知道有國(guó)內(nèi)沒(méi)有公司能夠?qū)⒚總€(gè)測(cè)試用例都寫(xiě)得如此詳細(xì)。在我的測(cè)試經(jīng)歷中,對(duì)測(cè)試用例描述的詳細(xì)和復(fù)雜程度也曾有過(guò)很多的彷徨。寫(xiě)得太簡(jiǎn)單吧,除了自己沒(méi)人能夠執(zhí)行,寫(xiě)得太詳細(xì)吧,消耗在測(cè)試用例維護(hù)(別忘了,測(cè)試用例是動(dòng)態(tài)的,一旦測(cè)試環(huán)境、需求、設(shè)計(jì)、實(shí)現(xiàn)發(fā)生了變化,測(cè)試用例都需要相應(yīng)發(fā)生變化)上的時(shí)間實(shí)在是太驚人,在目前國(guó)內(nèi)大部分軟件公司的測(cè)試資源都不足的情況下,恐怕很難實(shí)現(xiàn)。但我偏偏就能遇到一些這樣的老總或者是項(xiàng)目負(fù)責(zé)人,甚至是測(cè)試工程師本身,全然不顧實(shí)際的資源情況,一定要寫(xiě)出“沒(méi)有接觸過(guò)系統(tǒng)的人員也能進(jìn)行測(cè)試”的用例。
      在討論這個(gè)問(wèn)題之前,我們可以先考慮一下測(cè)試的目的。測(cè)試的目的是盡可能發(fā)現(xiàn)程序中存在的缺陷,測(cè)試活動(dòng)本身也可以被看作是一個(gè)Project,也需要在給定的資源條件下盡可能達(dá)成目標(biāo),根據(jù)我個(gè)人的經(jīng)驗(yàn),大部分的國(guó)內(nèi)軟件公司在測(cè)試方面配備的資源都是不足夠的,因此我們必須在測(cè)試計(jì)劃階段明確測(cè)試的目標(biāo),一切圍繞測(cè)試的目標(biāo)進(jìn)行。
      除了資源上的約束外,測(cè)試用例的詳細(xì)程度也需要根據(jù)需要確定。如果測(cè)試用例的執(zhí)行者、測(cè)試用例設(shè)計(jì)者、測(cè)試活動(dòng)相關(guān)人對(duì)系統(tǒng)了解都很深刻,那測(cè)試用例就沒(méi)有必要太詳細(xì)了,文檔的作用本來(lái)就在于溝通,只要能達(dá)到溝通的目的就OK。
      在我擔(dān)任測(cè)試經(jīng)理的項(xiàng)目中,在測(cè)試計(jì)劃階段,一般給予測(cè)試設(shè)計(jì)30% - 40%左右的時(shí)間,測(cè)試設(shè)計(jì)工程師能夠根據(jù)項(xiàng)目的需要自行確定用例的詳細(xì)程度,在測(cè)試用例的評(píng)審階段由參與評(píng)審的相關(guān)人對(duì)其把關(guān)。
      3、測(cè)試用例設(shè)計(jì)是一勞永逸的事情;
      這句話擺在這里,我想沒(méi)有一個(gè)人會(huì)認(rèn)可,但在實(shí)際情況中,卻經(jīng)常能發(fā)現(xiàn)這種想法的影子。我曾經(jīng)參與過(guò)一個(gè)項(xiàng)目,軟件需求和設(shè)計(jì)已經(jīng)變更了多次,但測(cè)試用例卻沒(méi)有任何修改。導(dǎo)致的直接結(jié)果是新加入的測(cè)試工程師在執(zhí)行測(cè)試用例時(shí)不知所措,間接的后果是測(cè)試用例成了廢紙一堆,開(kāi)發(fā)人員在多次被無(wú)效的缺陷報(bào)告打擾后,對(duì)測(cè)試人員不屑一顧。
      這個(gè)例子可能有些極端,但測(cè)試用例與需求和設(shè)計(jì)不同步的情況在實(shí)際開(kāi)發(fā)過(guò)程中確是屢見(jiàn)不鮮的,測(cè)試用例文檔是“活的”文檔,這一點(diǎn)應(yīng)該被測(cè)試工程師牢記。
      4、測(cè)試用例不應(yīng)該包含實(shí)際的數(shù)據(jù);
      測(cè)試用例是“一組輸入、執(zhí)行條件、預(yù)期結(jié)果”、毫無(wú)疑問(wèn)地應(yīng)該包括清晰的輸入數(shù)據(jù)和預(yù)期輸出,沒(méi)有測(cè)試數(shù)據(jù)的用例最多只具有指導(dǎo)性的意義,不具有可執(zhí)行性。當(dāng)然,測(cè)試用例中包含輸入數(shù)據(jù)會(huì)帶來(lái)維護(hù)、與測(cè)試環(huán)境同步之類(lèi)的問(wèn)題,關(guān)于這一點(diǎn),《Effective Software Test》一書(shū)中提供了詳細(xì)的測(cè)試用例、測(cè)試數(shù)據(jù)的維護(hù)方法,可以參考。
      5、測(cè)試用例中不需要明顯的驗(yàn)證手段;
      我見(jiàn)過(guò)很多測(cè)試工程師編寫(xiě)的測(cè)試用例中,“預(yù)期輸出”僅描述為程序的可見(jiàn)行為,其實(shí),“預(yù)期結(jié)果”的含義并不只是程序的可見(jiàn)行為。例如,對(duì)一個(gè)訂貨系統(tǒng),輸入訂貨數(shù)據(jù),點(diǎn)擊“確定”按鈕后,系統(tǒng)提示“訂貨成功”,這樣是不是一個(gè)完整的用例呢?是不是系統(tǒng)輸出的“訂貨成功”就應(yīng)該作為我們唯一的驗(yàn)證手段呢?顯然不是。訂貨是否成功還需要查看相應(yīng)的數(shù)據(jù)記錄是否更新,因此,在這樣的一個(gè)用例中,還應(yīng)該包含對(duì)測(cè)試結(jié)果的顯式的驗(yàn)證手段:在數(shù)據(jù)庫(kù)中執(zhí)行查詢語(yǔ)句進(jìn)行查詢,看查詢結(jié)果是否與預(yù)期的一致。

    posted @ 2014-08-07 10:43 順其自然EVO 閱讀(167) | 評(píng)論 (0)編輯 收藏

    .net 碼農(nóng)轉(zhuǎn)戰(zhàn) iOS - 初探

    好久沒(méi)寫(xiě)博客了,之前還打算把畢業(yè)設(shè)計(jì)中涉及到的兩個(gè)算法拿出來(lái)說(shuō)說(shuō)(臉型分析 + 聲音分析),博文都寫(xiě)了一半了,后來(lái)實(shí)在太忙了,那篇隨筆也就沉在草稿列表中沒(méi)動(dòng)過(guò)。
      我原先是專(zhuān)職 .net 開(kāi)發(fā)的,在公司負(fù)責(zé)的項(xiàng)目是內(nèi)部自用的銷(xiāo)售管理系統(tǒng),由于不需要出去"拋頭露臉",所以公司干脆什么也沒(méi)配置(指產(chǎn)品、設(shè)計(jì)、前端等等,開(kāi)發(fā)設(shè)備還是有的),于是所有工作全包了。原本對(duì)自身的計(jì)劃是,后續(xù)會(huì)慢慢轉(zhuǎn)產(chǎn)品方面的。
      后來(lái),也算是一個(gè)契機(jī),公司所有移動(dòng)端的人基本走光了(iOS 全走了,Android 的好像只剩 2 個(gè)!!公司內(nèi)部的事,這里就不多說(shuō)了),于是上頭經(jīng)理就打算讓我們轉(zhuǎn)到移動(dòng)端開(kāi)發(fā)。.net 和 java 一直都是"死對(duì)頭"(自己的理解,求別噴),所以我不會(huì)選 Android,WP 市場(chǎng)還不夠,轉(zhuǎn)過(guò)去對(duì)自己競(jìng)爭(zhēng)力的提升不大,于是乎選擇了 iOS 開(kāi)發(fā),于是乎便有了這篇《.net 碼農(nóng)轉(zhuǎn)戰(zhàn) iOS - 初探》。。。
      大學(xué)時(shí)期有一點(diǎn) C 的基礎(chǔ),但是對(duì) OC 完全不知,這次屬于從 0 開(kāi)始(不選擇 swift 開(kāi)始,其實(shí)是怕它還不夠成熟。語(yǔ)言這東西,其實(shí)說(shuō)到底是相通的,理解了基礎(chǔ)的東西,還怕以后學(xué)不會(huì)其他的么!)。
      我是屬于自學(xué)的,看視頻、查資料一步步慢慢走。
      學(xué)習(xí)真的需要?jiǎng)邮智面I盤(pán),單單只是看一下是記不住理解不了的,至少我還沒(méi)到那個(gè)看看就會(huì)的地步。。。
      · 我從 xcode5 開(kāi)始,這時(shí)候已經(jīng)少了很多內(nèi)存管理的代碼了(基本不用寫(xiě) release 了),但是不需要你寫(xiě),并不代表不需要你了解。所以內(nèi)存管理需要詳看。
      · 命名空間,OC 里是沒(méi)有這個(gè)概念的。區(qū)分兩個(gè)不同的類(lèi),僅僅是依靠類(lèi)名。所以一般都會(huì)在真正類(lèi)名前,加一個(gè)前綴用來(lái)區(qū)分,例如 NSString(NS 開(kāi)頭的代表為 MAC OS X 的核心,即 NeXTSTEP 的縮寫(xiě))、CGPoint。。。許多程序員都會(huì)使用自己名字的縮寫(xiě)做類(lèi)的前綴。
      · OC 大量使用指針,而且需顯性表示(NSString *str; str 是一個(gè)指針變量,前面需加一個(gè) "*" 顯性體現(xiàn),表示它是一個(gè)指向 "字符串" 的變量)。.net 中也有這個(gè)概念,只是不需要顯性表明("*"),參考 .net 中,類(lèi)、string 的聲明。
      · @"",OC 中字符串的寫(xiě)法,前面必須加一個(gè) "@" 表示是 NSString 類(lèi)型;
      · NSLog() 方法,即 .net 中 Console.WriteLine 方法,支持字符串的 Format,例如 NSLog(@"%@, %i,  %f", @"1", 1, 1.0);(@"%@" 功能很強(qiáng)大,類(lèi)似于 .net 中 ToString() 方法)。
      · 類(lèi)的聲明,創(chuàng)建一個(gè)普通的類(lèi),包含一個(gè) .h 文件和一個(gè) .m 文件(例如 SLTest.h & SLTest.m),是成對(duì)出現(xiàn)的,.h 文件為頭文件,一般用來(lái)做類(lèi)的聲明,類(lèi)似 .net 里的抽象類(lèi);.m 文件為實(shí)現(xiàn)文件,用來(lái)實(shí)現(xiàn)對(duì)應(yīng)的"抽象類(lèi)"。
    /**
    SLTest.h
    **/
    //使用import引入頭文件
    //Foundation為基礎(chǔ)框架
    //import表示該頭文件只被包含一次,無(wú)論該命令在整個(gè)程序中出現(xiàn)多少次
    #import<Foundation/Foundation.h>
    //用interface標(biāo)明是類(lèi)的聲明
    //該類(lèi)繼承自NSObject,類(lèi)似.net里的基類(lèi)object
    @interfaceSLTest:NSObject
    {
    //聲明成員變量
    }
    //聲明公有方法
    @end
    /**
    SLTest.m
    **/
    //使用import引入頭文件
    #import"SLTest.h"
    //implementation標(biāo)明是類(lèi)的實(shí)現(xiàn)
    @implementationSLTest
    //定義、實(shí)現(xiàn)私有方法
    //實(shí)現(xiàn)公有方法
    @end
     · OC 中聲明類(lèi)使用 interface 關(guān)鍵字,實(shí)現(xiàn)類(lèi)使用 implementation 關(guān)鍵字。其實(shí) OC 中還有一個(gè)關(guān)鍵字 "class",它并非 "聲明類(lèi)" 的意思,而是 "包含類(lèi)" 的意思。功能與 import 相似,但使用 import,編譯時(shí)會(huì)將 import 的文件整個(gè)包含進(jìn)來(lái),而使用 class,編譯時(shí)只是告訴它已經(jīng)有這個(gè)類(lèi),而不會(huì)整個(gè)包含進(jìn)來(lái),比 import 更輕量級(jí)。多用在只需要知道類(lèi)名,而不需要使用類(lèi)中方法的地方(例如變量聲明等)。使用方法:@class SLTest;。最大好處,例如有兩個(gè)類(lèi):A、B,A 中有一個(gè)變量 B b;,B 中有一個(gè)變量 A a;,如果使用 import,那么編譯時(shí)就是"我中有你你中有我",互相包含,最后造成包含的死循環(huán)。
      · OC 中方法的調(diào)用是使用 "[]",例如 [aaa AAA],在 .net 中即表現(xiàn)為 aaa.AAA(); 。有參數(shù)的方法調(diào)用例如 [aaa BBB:1 CCC:2],在 .net 中表現(xiàn)為 aaa.BBB:CCC:(1, 2); 。注意,OC 中 ":" 也是方法名,有多少個(gè) ":" 表示有多少個(gè)參數(shù),而參數(shù)的傳入是嵌套在方法名中的(怎么定義怎么用,例如剛才有參數(shù)的方法,定義為 -(void)BBB:(NSInteger)i CCC:(NSInteger)j;),這點(diǎn)和 .net 有很大的不同。
      · 實(shí)例化一個(gè)對(duì)象,由于要考慮到內(nèi)存管理問(wèn)題,OC 中基本都是用 alloc + initXXX 方法(也有個(gè)別使用其他工廠模式方法,在此不包括),alloc 表示分配內(nèi)存,initXXX 表示初始化。基本使用方法:[[NSString alloc] initWithFormat:@"this is a string."]。這里的意思是實(shí)例化一個(gè) NSString 對(duì)象,指向 "this is a string." 的內(nèi)存塊(initWithFormat:() 是 NSString 自有方法,其他類(lèi)型也有類(lèi)似的 initXXX() 的方法,也有的只有 init() 方法)。當(dāng)然 OC 也有 new() 方法,但是不建議使用。還是 .net 的 new() 好用!!OC 中沒(méi)有重載,只能用方法名來(lái)區(qū)分。例如 NSString 中的 initWithFormat() 方法和 initWithCoder()。還是 .net 的 new() 好用!!
    · get/set 方法,.net 中我們是使用 { get; set; } 讓編譯器自動(dòng)為我們添加,OC 也有類(lèi)似的:
    // 使用 property 關(guān)鍵字聲明
    // 括號(hào)內(nèi)指定該屬性的形式:
    // nonatomic 表示線程不安全的,在單線程不考慮線程安全的情況,使用 nonatomic 就可以了,對(duì)應(yīng)的 atomic
    // 一般基礎(chǔ)類(lèi)型用 assign,NSString 用 copy,其他用 strong(retain),當(dāng)然,凡事也有例外,具體自行谷哥吧
    // 此外還有 readonly、getter 等等,自行谷哥吧
    @property (nonatomic, assign) BOOL balabalabala;
      只需要這句話,編譯器會(huì)自動(dòng)生成私有的成員變量和對(duì)應(yīng)的 get/set 方法,當(dāng)然也可以自己重寫(xiě) get/set 方法,在 .m 文件中實(shí)現(xiàn)即可。
      · 方法前面,"-" 表示是實(shí)例方法,即由實(shí)例調(diào)用;"+" 表示是類(lèi)方法,即 .net 中類(lèi)的靜態(tài)方法。
      · OC 中的 id 類(lèi)型,弱類(lèi)型,類(lèi)似 js 里的 var,硬要跟 .net 掛鉤的話,很像 dynamic,但貌似又跟 dynamic 有所不同,請(qǐng)?jiān)徫阴磕_的表達(dá)能力。。。
      · self 關(guān)鍵字,即 .net 中的 this 關(guān)鍵字;super 關(guān)鍵字,即 .net 中的 base 關(guān)鍵字。
      · block,也就是 .net 中的匿名函數(shù),定義順序是:返回類(lèi)型、"^"關(guān)鍵字、方法名(若聲明位置是方法參數(shù),可省略)、參數(shù)列表,例如:
    // 返回類(lèi)型為空
    // 方法名為 TEST1
    // 參數(shù)列表為空
    void (^TEST1)(void) = ^ {
    NSLog(@"TEST1");
    };
    TEST1();
    // 返回類(lèi)型為 NSString *
    // 方法名為 TEST2
    // 需傳入一個(gè) NSInteger 類(lèi)型的參數(shù)
    NSString *(^TEST2)(NSInteger) = ^(NSInteger i) {
    NSLog(@"TEST2 parameter: %i", i);
    return @"test2";
    };
    NSString *result = TEST2(10);
    NSLog(@"%@", result);
    // TEST3 方法定義了一個(gè) block 參數(shù),該 block 無(wú)返回值,需傳入一個(gè) NSString 類(lèi)型的參數(shù)
    - (void)TEST3:(void (^)(NSString * parameter))block
    {
    NSLog(@"TEST3");
    // 調(diào)用 block,并傳入?yún)?shù)
    block(@"TEST3 parameter");
    }
    // 調(diào)用 TEST3,傳入 block
    [self TEST3:^(NSString *parameter)
    {
    NSLog(@"parameter: %@", parameter);
    }];
      用法同 .net 的無(wú)異,只是語(yǔ)法不同。
       · category,擴(kuò)展,即 .net 中的類(lèi)擴(kuò)展,例如 public static bool IsValidEmailAddress(this string str);。OC 中,只允許擴(kuò)展方法,寫(xiě)法:
    /**
    NSString+Category.h
    文件命名方法,OC 建議是原類(lèi)名+擴(kuò)展名
    **/
    // 聲明時(shí),原類(lèi)名后加一個(gè)括號(hào),括號(hào)里為擴(kuò)展名,表示這是一個(gè)擴(kuò)展
    @interface NSString (Category)
    // 擴(kuò)展一個(gè)方法,判斷該字符串是否為 Email 地址
    - (BOOL)isValidEmailAddress;
    @end
    /**
    NSString+Category.m
    **/
    @implementation NSString (Category)
    // 實(shí)現(xiàn)方法
    // 請(qǐng)忽略具體方法,這里只做演示
    - (BOOL)isValidEmailAddress
    {
    return [self length] % 2 == 0;
    }
    @end
    // 使用時(shí),引入 .h 文件,即可像普通類(lèi)方法一樣使用
    NSString *str1 = @"1";
    NSString *str2 = @"11";
    NSLog(@"%i", [str1 isValidEmailAddress]);
    NSLog(@"%i", [str2 isValidEmailAddress]);
      · delegate,協(xié)議,注意,這里并不同 .net 中的 delegate,.net 中的 delegate 應(yīng)該更類(lèi)似 OC 中的 block。這里的 delegate 更像是 .net 中的接口。用我自己的理解來(lái)說(shuō),就是我有時(shí)候會(huì)觸發(fā)某個(gè)事件,而你如果需要知道我何時(shí)觸發(fā)了事件,那么我們之間就必須有一種 "約定協(xié)議",即當(dāng)我觸發(fā)事件時(shí),通知你。而你收到我的通知后,要干嘛,那是你的自由了。
      這里所說(shuō)的 "約定協(xié)議",即 OC 中的 delegate。我要通知你,即使用 delegate 中的方法。你只需要實(shí)現(xiàn)這個(gè)方法,我就可以通知到你。這個(gè)在下一篇再進(jìn)行詳細(xì)說(shuō)明。
      OC 的一些基礎(chǔ)的東西就差不多了,接下來(lái)就是結(jié)合到界面的開(kāi)發(fā),形式很像 .net 的 winform 開(kāi)發(fā),iOS 中使用 MVC 框架,所以如果你 .net 會(huì)這兩樣的話,還是比較容易看得懂的。
      做一款像樣的 App,需要各種崗位的同事幫忙,從需求,到設(shè)計(jì)、編碼、測(cè)試、上線,確實(shí)考驗(yàn)一個(gè)團(tuán)隊(duì)的合作能力。

    posted @ 2014-08-06 10:33 順其自然EVO 閱讀(554) | 評(píng)論 (0)編輯 收藏

    數(shù)據(jù)庫(kù)事務(wù)的隔離級(jí)別

     隔離級(jí)別都與問(wèn)題相對(duì)應(yīng),數(shù)據(jù)庫(kù)操作常見(jiàn)的問(wèn)題:
      1 臟讀:   一個(gè)事務(wù)可以讀取另一個(gè)事務(wù)未提交的數(shù)據(jù)
      2 不可重復(fù)讀: 一個(gè)事務(wù)連續(xù)兩次執(zhí)行某個(gè)讀操作,返回的結(jié)果不一致,被修改了
      3 虛讀 :一個(gè)事務(wù)連續(xù)兩次執(zhí)行某個(gè)讀操作,返回的結(jié)果不一致,返回的紀(jì)錄數(shù)目有改變
      不可重復(fù)讀 與 虛讀 的區(qū)別:
      不可重復(fù)讀,強(qiáng)調(diào)的是,第二次返回的結(jié)果中,某個(gè)條目被修改過(guò),比如某些字段被修改
      虛讀,強(qiáng)調(diào)的是,第二次返回結(jié)果中,屬于第一次返回結(jié)果的條目沒(méi)有任何變化,但是返回條目的數(shù)目會(huì)變化
      數(shù)據(jù)庫(kù)事務(wù)隔離級(jí)別
      1 read uncommitted  臟讀的那個(gè)級(jí)別
      2 read committed  解決臟讀問(wèn)題,提交了才能被其它事務(wù)讀到  (大多數(shù)數(shù)據(jù)庫(kù)的默認(rèn)事務(wù)等級(jí))
      3 repeatable read 可重復(fù)讀,如何實(shí)現(xiàn):規(guī)定一個(gè)事務(wù)不能修改被其它事務(wù)讀但是未提交的事務(wù)
      4 serializable 最高的事務(wù)隔離級(jí)別  如何實(shí)現(xiàn):所有的事務(wù)都串行執(zhí)行
      repeatable read是如何實(shí)現(xiàn)?
      規(guī)定一個(gè)事務(wù)不能修改其它事務(wù)讀但是未提交的事務(wù)
      這樣就保證了一個(gè)事務(wù)中第二次讀到的數(shù)據(jù)都是沒(méi)有被修改過(guò)得
      為什么repeatable read隔離級(jí)別,虛讀問(wèn)題沒(méi)有被解決掉?
      只對(duì)修改作了限制,如果兩次讀之間進(jìn)行了插入或者刪除操作,滿足沒(méi)有修改其它事務(wù)讀但未提交的事務(wù),結(jié)果,兩次讀的結(jié)果還是會(huì)不一致,所以虛讀問(wèn)題沒(méi)有被解決
      虛讀問(wèn)題解決,serializable隔離級(jí)別?
      串行化執(zhí)行,很容易理解,我在一個(gè)事務(wù)中,執(zhí)行兩次讀操作,在此期間,沒(méi)有其它事務(wù)在執(zhí)行,必須等我執(zhí)行完以后才會(huì)被執(zhí)行,因?yàn)槭谴校蠹遗抨?duì),所以結(jié)果不可能不一致。

    posted @ 2014-08-06 10:32 順其自然EVO 閱讀(220) | 評(píng)論 (0)編輯 收藏

    僅列出標(biāo)題
    共394頁(yè): First 上一頁(yè) 70 71 72 73 74 75 76 77 78 下一頁(yè) Last 
    <2025年5月>
    27282930123
    45678910
    11121314151617
    18192021222324
    25262728293031
    1234567

    導(dǎo)航

    統(tǒng)計(jì)

    常用鏈接

    留言簿(55)

    隨筆分類(lèi)

    隨筆檔案

    文章分類(lèi)

    文章檔案

    搜索

    最新評(píng)論

    閱讀排行榜

    評(píng)論排行榜

    主站蜘蛛池模板: 国产成人无码精品久久久久免费| 亚洲AV无码一区二区三区牛牛| www国产亚洲精品久久久日本| 日本一道本高清免费| 日本最新免费不卡二区在线| 久久精品国产亚洲AV网站| 亚洲an天堂an在线观看| 亚洲午夜精品在线| 免费播放美女一级毛片| 中文字幕不卡免费高清视频| 日本亚洲欧洲免费天堂午夜看片女人员| 久久国产色AV免费观看| 免费在线观看h片| 国产真人无遮挡作爱免费视频| 国产美女亚洲精品久久久综合| 亚洲一区二区影院| 亚洲AV无码国产一区二区三区| 一级特黄aaa大片免费看| 99蜜桃在线观看免费视频网站| 女性自慰aⅴ片高清免费| 亚洲精品高清在线| 亚洲精品熟女国产| 美女免费视频一区二区| 84pao强力永久免费高清| 亚洲精品无码久久久久去q | 亚洲日韩AV无码一区二区三区人| 男女作爱免费网站| 精品熟女少妇av免费久久| 亚洲精品无码不卡在线播HE| 一区二区免费在线观看| 欧洲一级毛片免费| 亚洲美女中文字幕| 无码的免费不卡毛片视频| 可以免费观看的一级毛片| 久久久久久久亚洲Av无码| 久草视频在线免费看| 亚洲AV无码乱码在线观看富二代| 97在线免费视频| 国产裸模视频免费区无码| 亚洲成熟丰满熟妇高潮XXXXX| 日韩精品无码免费一区二区三区 |