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è)不同類型的數(shù)據(jù)庫(kù),報(bào)表數(shù)據(jù)源跨數(shù)據(jù)庫(kù)是報(bào)表開發(fā)中的常態(tài)。目前實(shí)現(xiàn)這類跨庫(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ù)中,這種做法在各類應(yīng)用中很常見,目的是使用數(shù)據(jù)庫(kù)(SQL)強(qiáng)大的計(jì)算能力。然而,這種做法會(huì)增加額外的成本開銷,將多個(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)買成本以及管理成本。另外,完成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)是太難寫。很多像Java這樣的高級(jí)語(yǔ)言缺乏對(duì)集合運(yùn)算的有效支持,沒(méi)有相應(yīng)的類庫(kù),導(dǎo)致完成個(gè)簡(jiǎn)單的group也要寫很多(循環(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)源于人力部門的考勤系統(tǒng)(hsql數(shù)據(jù)庫(kù)),基本工資和績(jī)效信息則存儲(chǔ)在財(cái)務(wù)系統(tǒng)(mysql數(shù)據(jù)庫(kù))中。需要將這兩類信息合起來(lái)計(jì)算員工的工資。
            實(shí)現(xiàn)步驟
            編寫腳本(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)
            集算器的類包封裝成標(biāo)準(zhǔn)的JDBC,允許報(bào)表工具以類存儲(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)表采用類存儲(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 閱讀(822) | 評(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
            可見通過(guò)iOS自帶的正則表達(dá)式的類可以達(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的寫法,需要查閱蘋果相關(guān)技術(shù)文檔;如果只關(guān)心第一個(gè)匹配的結(jié)果,第二種匹配較為簡(jiǎn)潔;如果需要匹配多個(gè)結(jié)果,同時(shí)匹配多次,第三種方式效率會(huì)更高。

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

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

           java單元測(cè)試中,經(jīng)常寫單元測(cè)試方法,測(cè)試job任務(wù)。而這些job任務(wù),對(duì)應(yīng)電子商務(wù)等流水系統(tǒng)來(lái)說(shuō),比較常見。 它們常用的特點(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 閱讀(258) | 評(píng)論 (0)編輯 收藏

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

            開局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上開遠(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 閱讀(185) | 評(píng)論 (0)編輯 收藏

          QC缺陷管理常用操作

           1、QC建項(xiàng)目
            使用管理員賬號(hào)登錄,創(chuàng)建項(xiàng)目→然后選擇想創(chuàng)建的項(xiàng)目,點(diǎn)擊下一步。
            輸入項(xià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è)置為開發(fā)組、測(cè)試組、項(xiàng)目管理組然后給予不同的權(quán)限。然后可以根據(jù)分組把不同的用戶歸入相應(yīng)的組內(nèi)。
            
            6、未點(diǎn)擊注銷直接關(guān)掉網(wǎng)頁(yè)
            會(huì)出現(xiàn)問(wèn)題,有時(shí)候是登錄出現(xiàn)問(wèn)題,或者修改的時(shí)候無(wú)法修改。使用qc管理員賬號(hào)登錄→點(diǎn)擊要斷掉連接→點(diǎn)擊斷開連接即可。
            
            Ps、1、登錄時(shí)不用勾選自動(dòng)登錄2、大多數(shù)修改之后注意點(diǎn)擊右下角的保存按鈕。wKioL1PYoE6zacJ4AAAKq4DwI-Y919.gif俺老是忘記保存~~~

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

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

          使用OCUnit測(cè)試框架iOS單元測(cè)試框架
            原則上,是否使用測(cè)試框架都不會(huì)影響單元測(cè)試結(jié)果,但是“工欲善其事,必先利其器”使用單元測(cè)試框架更便于我們測(cè)試和分析結(jié)果。
            主要的iOS單元測(cè)試框架有:
            OCUnit,是開源測(cè)試框架,與Xcode工具集成在一起使用非常方便,測(cè)試報(bào)告以文本形式輸出到輸出窗口;
            GHUnit,是開源測(cè)試框架,它可以將測(cè)試報(bào)告以應(yīng)用形式可視化輸出到設(shè)備或模擬器上,也可以以文本形式輸出到輸出窗口;GHUnit可以測(cè)試OCUnit編寫的測(cè)試用例
            OCMock,是開源測(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è)試類。在右邊的Target欄中多了一個(gè)PITaxTests Target。
            
            但是打開Scheme列表還只有一個(gè)PITax,這是我們需要注意的。運(yùn)行它可以通過(guò):選擇菜單Product→Test或工具欄中Test按鈕(下拉Run按鈕選擇)或快捷鍵command+U等幾種方式。
            如果打開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è)試類。在右邊的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è)試類基本都是一樣的,下面代碼是默認(rèn)生成的LogicTest測(cè)試類中的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è)試類需要引入<SenTestingKit/SenTestingKit.h>頭文件,并繼承 SenTestCase父類。testExample方法是一般的測(cè)試方法,方法名必須test開頭,測(cè)試方法的個(gè)數(shù)沒(méi)有限制,方法中STFail是 OCUnit框架定義的一個(gè)宏,是無(wú)條件斷言失敗,實(shí)際使用時(shí)候要修改這個(gè)方法中的代碼。
            在m文件中需要重新方法setUp和tearDown,我們自己編寫的測(cè)試類一樣,setUp方法是初始化方法,tearDown方法是釋放資源的 方法,setUp和tearDown方法在每次調(diào)用測(cè)試方法之前和之后調(diào)用,因此在測(cè)試類運(yùn)行的生命周期中這兩個(gè)方法可能多次運(yùn)行,它們的時(shí)序圖
            

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

          為什么谷歌要執(zhí)行嚴(yán)格的代碼編寫規(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í)間、影響人們開發(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ī)范的人很多,下面是一些常見的理由,對(duì)于這些理由,我以前是深信不疑。
            這是浪費(fèi)時(shí)間!
            我是一個(gè)優(yōu)秀的程序員,我不愿意浪費(fèi)時(shí)間干這些愚蠢的事。我的技術(shù)很好,我可以寫出清晰的、易于理解的代碼。為什么我要浪費(fèi)時(shí)間遵守這些愚蠢的規(guī)范?答案是:統(tǒng)一是有價(jià)值的。就像我前面說(shuō)的—你看到的任何的一行代碼—不論是由你寫的,還是由你身邊的同事,還是由一個(gè)跟你相差11個(gè)時(shí)區(qū)的距離人寫的—它們都有統(tǒng)一的結(jié)構(gòu),相同的命名規(guī)范—這帶來(lái)的效果是巨大的。你只需要花這么少的功夫就能看懂一個(gè)你不熟悉(或完全未見過(guò))的程序,因?yàn)槟阋灰娝鼈兙蜁?huì)覺得面熟。
            我是個(gè)藝術(shù)家!
            這種話很滑稽,但它反映了一種常見的抱怨。我們程序員對(duì)于自己的編碼風(fēng)格通常懷有很高的自負(fù)。我寫出的的代碼的確能反映出我的一些特質(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)目專門設(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)的好處是巨大的。除此之外,專門針對(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)該是最常見的抱怨類型了。它是其它幾種反對(duì)聲音的混合體,但它卻有自身態(tài)度的直接表現(xiàn)。有一部分反對(duì)者深信,他們是比制定編碼規(guī)范的人更好的程序員,俯身屈從這些小學(xué)生制定的規(guī)范,將會(huì)降低代碼的質(zhì)量。對(duì)于此,客氣點(diǎn)說(shuō),就是胡扯。純屬傲慢自大,荒唐可笑。事實(shí)上他們的意思就是, 沒(méi)有人配得上給他們制定規(guī)范,對(duì)他們的代碼的任何改動(dòng)都是一種破壞。如果參照任何一種合理的編碼規(guī)范,你都不能寫出合格的代碼,那只能說(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)秀的程序員寫出優(yōu)秀的代碼,這需要努力。這需要一個(gè)執(zhí)著的、冷靜的、進(jìn)了水的大腦。如果這群蠢貨能強(qiáng)行頒布不可用的編碼規(guī)范,那他們就能干出其它很多傻事情。如果你為這群蠢貨干活,你的確被糟蹋了—不論你干什么、有沒(méi)有規(guī)范。(我并不是說(shuō)罕有公司被一群蠢貨管理;事實(shí)很不幸,我們這個(gè)世界從來(lái)就不缺蠢貨,而且很多蠢貨都擁有自己的公司。)

          posted @ 2014-08-07 10:44 順其自然EVO 閱讀(157) | 評(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è)試用例都寫得如此詳細(xì)。在我的測(cè)試經(jīng)歷中,對(duì)測(cè)試用例描述的詳細(xì)和復(fù)雜程度也曾有過(guò)很多的彷徨。寫得太簡(jiǎn)單吧,除了自己沒(méi)人能夠執(zhí)行,寫得太詳細(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í)際的資源情況,一定要寫出“沒(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è)試用例成了廢紙一堆,開發(fā)人員在多次被無(wú)效的缺陷報(bào)告打擾后,對(duì)測(cè)試人員不屑一顧。
            這個(gè)例子可能有些極端,但測(cè)試用例與需求和設(shè)計(jì)不同步的情況在實(shí)際開發(fā)過(guò)程中確是屢見不鮮的,測(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)境同步之類的問(wèn)題,關(guān)于這一點(diǎn),《Effective Software Test》一書中提供了詳細(xì)的測(cè)試用例、測(cè)試數(shù)據(jù)的維護(hù)方法,可以參考。
            5、測(cè)試用例中不需要明顯的驗(yàn)證手段;
            我見過(guò)很多測(cè)試工程師編寫的測(cè)試用例中,“預(yù)期輸出”僅描述為程序的可見行為,其實(shí),“預(yù)期結(jié)果”的含義并不只是程序的可見行為。例如,對(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 閱讀(170) | 評(píng)論 (0)編輯 收藏

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

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

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

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

           隔離級(jí)別都與問(wèn)題相對(duì)應(yīng),數(shù)據(jù)庫(kù)操作常見的問(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 閱讀(225) | 評(píng)論 (0)編輯 收藏

          僅列出標(biāo)題
          共394頁(yè): First 上一頁(yè) 70 71 72 73 74 75 76 77 78 下一頁(yè) Last 
          <2025年7月>
          293012345
          6789101112
          13141516171819
          20212223242526
          272829303112
          3456789

          導(dǎo)航

          統(tǒng)計(jì)

          常用鏈接

          留言簿(55)

          隨筆分類

          隨筆檔案

          文章分類

          文章檔案

          搜索

          最新評(píng)論

          閱讀排行榜

          評(píng)論排行榜

          主站蜘蛛池模板: 西藏| 谢通门县| 饶阳县| 泸定县| 东阳市| 南安市| 泽普县| 库伦旗| 英德市| 隆德县| 凤山市| 新营市| 视频| 岢岚县| 安徽省| 武义县| 新巴尔虎右旗| 庆安县| 潜山县| 淮南市| 馆陶县| 肃北| 深圳市| 济宁市| 阿鲁科尔沁旗| 呼和浩特市| 海伦市| 宜宾县| 永修县| 正宁县| 沈阳市| 德格县| 交城县| 乳山市| 噶尔县| 阜康市| 宽甸| 清原| 庆城县| 华阴市| 类乌齐县|