Java單元測試之JUnit4詳解

2019獨角獸企業重金招聘Python工程師標準>>> hot3.png

Java單元測試之JUnit4詳解

與JUnit3不同,JUnit4通過注解的方式來識別測試方法。目前支持的主要注解有:

  • @BeforeClass?全局只會執行一次,而且是第一個運行
  • @Before?在測試方法運行之前運行
  • @Test ?測試方法
  • @After ?在測試方法運行之后允許
  • @AfterClass?全局只會執行一次,而且是最后一個運行
  • @Ignore?忽略此方法

下面舉一個樣例:

  1. import?org.junit.After;??
  2. import?org.junit.AfterClass;??
  3. import?org.junit.Assert;??
  4. import?org.junit.Before;??
  5. import?org.junit.BeforeClass;??
  6. import?org.junit.Ignore;??
  7. import?org.junit.Test;??
  8. ???
  9. public?class?Junit4TestCase?{??
  10. ???
  11. ????@BeforeClass??
  12. ????public?static?void?setUpBeforeClass()?{??
  13. ????????System.out.println("Set?up?before?class");??
  14. ????}??
  15. ???
  16. ????@Before??
  17. ????public?void?setUp()?throws?Exception?{??
  18. ????????System.out.println("Set?up");??
  19. ????}??
  20. ???
  21. ????@Test??
  22. ????public?void?testMathPow()?{??
  23. ????????System.out.println("Test?Math.pow");??
  24. ????????Assert.assertEquals(4.0,?Math.pow(2.0,?2.0),?0.0);??
  25. ????}??
  26. ???
  27. ????@Test??
  28. ????public?void?testMathMin()?{??
  29. ????????System.out.println("Test?Math.min");??
  30. ????????Assert.assertEquals(2.0,?Math.min(2.0,?4.0),?0.0);??
  31. ????}??
  32. ???
  33. ????????//?期望此方法拋出NullPointerException異常??
  34. ????@Test(expected?=?NullPointerException.class)??
  35. ????public?void?testException()?{??
  36. ????????System.out.println("Test?exception");??
  37. ????????Object?obj?=?null;??
  38. ????????obj.toString();??
  39. ????}??
  40. ???
  41. ????????//?忽略此測試方法??
  42. ????@Ignore??
  43. ????@Test??
  44. ????public?void?testMathMax()?{??
  45. ??????????Assert.fail("沒有實現");??
  46. ????}??
  47. ????????//?使用“假設”來忽略測試方法??
  48. ????@Test??
  49. ????public?void?testAssume(){??
  50. ????????System.out.println("Test?assume");??
  51. ????????????????//?當假設失敗時,則會停止運行,但這并不會意味測試方法失敗。??
  52. ????????Assume.assumeTrue(false);??
  53. ????????Assert.fail("沒有實現");??
  54. ????}??
  55. ???
  56. ????@After??
  57. ????public?void?tearDown()?throws?Exception?{??
  58. ????????System.out.println("Tear?down");??
  59. ????}??
  60. ???
  61. ????@AfterClass??
  62. ????public?static?void?tearDownAfterClass()?{??
  63. ????????System.out.println("Tear?down?After?class");??
  64. ????}??
  65. ???
  66. } ?
  67. 單元測試是編寫測試代碼,用來檢測特定的、明確的、細顆粒的功能。單元測試并不一定保證程序功能是正確的,更不保證整體業務是準備的。

    單元測試不僅僅用來保證當前代碼的正確性,更重要的是用來保證代碼修復、改進或重構之后的正確性。

    一般來說,單元測試任務包括

    1. 接口功能測試:用來保證接口功能的正確性。
    2. 局部數據結構測試(不常用):用來保證接口中的數據結構是正確的
      1. 比如變量有無初始值
      2. 變量是否溢出
    3. 邊界條件測試
      1. 變量沒有賦值(即為NULL)
      2. 變量是數值(或字符)
        1. 主要邊界:最小值,最大值,無窮大(對于DOUBLE等)
        2. 溢出邊界(期望異常或拒絕服務):最小值-1,最大值+1
        3. 臨近邊界:最小值+1,最大值-1
      3. 變量是字符串
        1. 引用“字符變量”的邊界
        2. 空字符串
        3. 對字符串長度應用“數值變量”的邊界
      4. 變量是集合
        1. 空集合
        2. 對集合的大小應用“數值變量”的邊界
        3. 調整次序:升序、降序
      5. 變量有規律
        1. 比如對于Math.sqrt,給出n^2-1,和n^2+1的邊界
    4. 所有獨立執行通路測試:保證每一條代碼,每個分支都經過測試
      1. 代碼覆蓋率
        1. 語句覆蓋:保證每一個語句都執行到了
        2. 判定覆蓋(分支覆蓋):保證每一個分支都執行到
        3. 條件覆蓋:保證每一個條件都覆蓋到true和false(即if、while中的條件語句)
        4. 路徑覆蓋:保證每一個路徑都覆蓋到
      2. 相關軟件
        1. Cobertura:語句覆蓋
        2. Emma: Eclipse插件Eclemma
    5. 各條錯誤處理通路測試:保證每一個異常都經過測試

    JUNIT

    JUnit是Java單元測試框架,已經在Eclipse中默認安裝。目前主流的有JUnit3和JUnit4。JUnit3中,測試用例需要繼承TestCase類。JUnit4中,測試用例無需繼承TestCase類,只需要使用@Test等注解。

    Junit3

    先看一個Junit3的樣例

    1. //?測試java.lang.Math??
    2. //?必須繼承TestCase??
    3. public?class?Junit3TestCase?extends?TestCase?{??
    4. ????public?Junit3TestCase()?{??
    5. ????????super();??
    6. ????}??
    7. ????
    8. ????????//?傳入測試用例名稱??
    9. ????public?Junit3TestCase(String?name)?{??
    10. ????????super(name);??
    11. ????}??
    12. ???
    13. ????????//?在每個Test運行之前運行??
    14. ????@Override??
    15. ????protected?void?setUp()?throws?Exception?{??
    16. ????????System.out.println("Set?up");??
    17. ????}??
    18. ????????//?測試方法。??
    19. ????????//?方法名稱必須以test開頭,沒有參數,無返回值,是公開的,可以拋出異常??
    20. ????????//?也即類似public?void?testXXX()?throws?Exception?{}??
    21. ????public?void?testMathPow()?{??
    22. ????????System.out.println("Test?Math.pow");??
    23. ????????Assert.assertEquals(4.0,?Math.pow(2.0,?2.0));??
    24. ????}??
    25. ???
    26. ????public?void?testMathMin()?{??
    27. ????????System.out.println("Test?Math.min");??
    28. ????????Assert.assertEquals(2.0,?Math.min(2.0,?4.0));??
    29. ????}??
    30. ???
    31. ????????//?在每個Test運行之后運行??
    32. ????@Override??
    33. ????protected?void?tearDown()?throws?Exception?{??
    34. ????????System.out.println("Tear?down");??
    35. ????}??
    36. }??

    ?

    如果采用默認的TestSuite,則測試方法必須是public void testXXX() [throws Exception] {}的形式,并且不能存在依賴關系,因為測試方法的調用順序是不可預知的。
    上例執行后,控制臺會輸出

    1. Set?up??
    2. Test?Math.pow??
    3. Tear?down??
    4. Set?up??
    5. Test?Math.min??
    6. Tear?down??

    ?

    從中,可以猜測到,對于每個測試方法,調用的形式是:

    1. testCase.setUp();??
    2. testCase.testXXX();??
    3. testCase.tearDown();?????

    ?

    運行測試方法

    在Eclipse中,可以直接在類名或測試方法上右擊,在彈出的右擊菜單中選擇Run As -> JUnit Test。
    在Mvn中,可以直接通過mvn test命令運行測試用例。
    也可以通過Java方式調用,創建一個TestCase實例,然后重載runTest()方法,在其方法內調用測試方法(可以多個)。

    1. TestCase?test?=?new?Junit3TestCase("mathPow")?{??
    2. ????????//?重載??
    3. ????protected?void?runTest()?throws?Throwable?{??
    4. ????????testMathPow();??
    5. ????};??
    6. };??
    7. test.run();??

    ?

    更加便捷地,可以在創建TestCase實例時直接傳入測試方法名稱,JUnit會自動調用此測試方法,如

    1. TestCase?test?=?new?Junit3TestCase("testMathPow");??
    2. test.run();??

    ?

    Junit TestSuite

    TestSuite是測試用例套件,能夠運行過個測試方法。如果不指定TestSuite,會創建一個默認的TestSuite。默認TestSuite會掃描當前內中的所有測試方法,然后運行。
    如果不想采用默認的TestSuite,則可以自定義TestSuite。在TestCase中,可以通過靜態方法suite()返回自定義的suite。

    1. import?junit.framework.Assert;??
    2. import?junit.framework.Test;??
    3. import?junit.framework.TestCase;??
    4. import?junit.framework.TestSuite;??
    5. ???
    6. public?class?Junit3TestCase?extends?TestCase?{??
    7. ????????//...??
    8. ????public?static?Test?suite()?{??
    9. ????????System.out.println("create?suite");??
    10. ????????TestSuite?suite?=?new?TestSuite();??
    11. ????????suite.addTest(new?Junit3TestCase("testMathPow"));??
    12. ????????return?suite;??
    13. ????}??
    14. }??

    ?

    允許上述方法,控制臺輸出

    寫道
    create suite
    Set up
    Test Math.pow
    Tear down

    ?

    并且只運行了testMathPow測試方法,而沒有運行testMathMin測試方法。通過顯式指定測試方法,可以控制測試執行的順序。

    也可以通過Java的方式創建TestSuite,然后調用TestCase,如

    ?

    1. //?先創建TestSuite,再添加測試方法??
    2. TestSuite?testSuite?=?new?TestSuite();??
    3. testSuite.addTest(new?Junit3TestCase("testMathPow"));??
    4. ???
    5. //?或者?傳入Class,TestSuite會掃描其中的測試方法。??
    6. TestSuite?testSuite?=?new?TestSuite(Junit3TestCase.class,Junit3TestCase2.class,Junit3TestCase3.class);??
    7. ???
    8. //?運行testSuite??
    9. TestResult?testResult?=?new?TestResult();??
    10. testSuite.run(testResult); ?

    testResult中保存了很多測試數據,包括運行測試方法數目(runCount)等。

    如果細心的話,會發現Junit3的package是junit.framework,而Junit4是org.junit
    執行此用例后,控制臺會輸出

    寫道
    Set up before class
    Set up
    Test Math.pow
    Tear down
    Set up
    Test Math.min
    Tear down
    Set up
    Test exception
    Tear down
    Set up
    Test assume
    Tear down
    Tear down After class

    可以看到,執行次序是@BeforeClass?->?@Before?->?@Test?->?@After?->?@Before?->?@Test?->?@After?->?@AfterClass@Ignore會被忽略。

    運行測試方法

    與Junit3類似,可以在Eclipse中運行,也可以通過mvn test命令運行。

    Assert

    Junit3和Junit4都提供了一個Assert類(雖然package不同,但是大致差不多)。Assert類中定義了很多靜態方法來進行斷言。列表如下:

    • assertTrue(String message, boolean condition) 要求condition == true
    • assertFalse(String message, boolean condition) 要求condition == false
    • fail(String message) 必然失敗,同樣要求代碼不可達
    • assertEquals(String message, XXX expected,XXX actual) 要求expected.equals(actual)
    • assertArrayEquals(String message, XXX[] expecteds,XXX [] actuals) 要求expected.equalsArray(actual)
    • assertNotNull(String message, Object object) 要求object!=null
    • assertNull(String message, Object object) 要求object==null
    • assertSame(String message, Object expected, Object actual) 要求expected == actual
    • assertNotSame(String message, Object unexpected,Object actual) 要求expected != actual
    • assertThat(String reason, T actual, Matcher?matcher) 要求matcher.matches(actual) == true

    Mock/Stub

    Mock和Stub是兩種測試代碼功能的方法。Mock測重于對功能的模擬。Stub測重于對功能的測試重現。比如對于List接口,Mock會直接對List進行模擬,而Stub會新建一個實現了List的TestList,在其中編寫測試的代碼。
    強烈建議優先選擇Mock方式,因為Mock方式下,模擬代碼與測試代碼放在一起,易讀性好,而且擴展性、靈活性都比Stub好。
    比較流行的Mock有:

    • JMock
    • EasyMock
    • Mockito
    • powermock

    其中EasyMock和Mockito對于Java接口使用接口代理的方式來模擬,對于Java類使用繼承的方式來模擬(也即會創建一個新的Class類)。Mockito支持spy方式,可以對實例進行模擬。但它們都不能對靜態方法和final類進行模擬,powermock通過修改字節碼來支持了此功能。

    EasyMock

    IBM上有幾篇介紹EasyMock使用方法和原理的文章:EasyMock 使用方法與原理剖析,使用 EasyMock 更輕松地進行測試。
    EasyMock把測試過程分為三步:錄制、運行測試代碼、驗證期望。
    錄制過程大概就是:期望method(params)執行times次(默認一次),返回result(可選),拋出exception異常(可選)。
    驗證期望過程將會檢查方法的調用次數。
    一個簡單的樣例是:

    ?

    1. @Test??
    2. public?void?testListInEasyMock()?{??
    3. ????List?list?=?EasyMock.createMock(List.class);??
    4. ????//?錄制過程??
    5. ???
    6. ????//?期望方法list.set(0,1)執行2次,返回null,不拋出異常??
    7. ????expect1:?EasyMock.expect(list.set(0,?1)).andReturn(null).times(2);??
    8. ????//?期望方法list.set(0,1)執行1次,返回null,不拋出異常??
    9. ????expect2:?EasyMock.expect(list.set(0,?1)).andReturn(1);??
    10. ???
    11. ????//?執行測試代碼??
    12. ????EasyMock.replay(list);??
    13. ????????//?執行list.set(0,1),匹配expect1期望,會返回null??
    14. ????Assert.assertNull(list.set(0,?1));??
    15. ????????//?執行list.set(0,1),匹配expect1(因為expect1期望執行此方法2次),會返回null??
    16. ????Assert.assertNull(list.set(0,?1));??
    17. ????????//?執行list.set(0,1),匹配expect2,會返回1??
    18. ????Assert.assertEquals(1,?list.set(0,?1));??
    19. ???
    20. ????//?驗證期望??
    21. ????EasyMock.verify(list);??
    22. }??

    ?

    ?

    EasyMock還支持嚴格的檢查,要求執行的方法次序與期望的完全一致。

    Mockito

    Mockito是Google Code上的一個開源項目,Api相對于EasyMock更好友好。與EasyMock不同的是,Mockito沒有錄制過程,只需要在“運行測試代碼”之前對接口進行Stub,也即設置方法的返回值或拋出的異常,然后直接運行測試代碼,運行期間調用Mock的方法,會返回預先設置的返回值或拋出異常,最后再對測試代碼進行驗證。可以查看此文章了解兩者的不同。
    官方提供了很多樣例,基本上包括了所有功能,可以去看看。
    這里從官方樣例中摘錄幾個典型的:

    • 驗證調用行為
      1. import?static?org.mockito.Mockito.*;??
      2. ???
      3. //創建Mock??
      4. List?mockedList?=?mock(List.class);??
      5. ???
      6. //使用Mock對象??
      7. mockedList.add("one");??
      8. mockedList.clear();??
      9. ???
      10. //驗證行為??
      11. verify(mockedList).add("one");??
      12. verify(mockedList).clear();??
      ?
    • 對Mock對象進行Stub
      1. //也可以Mock具體的類,而不僅僅是接口??
      2. LinkedList?mockedList?=?mock(LinkedList.class);??
      3. ???
      4. //Stub??
      5. when(mockedList.get(0)).thenReturn("first");?//?設置返回值??
      6. when(mockedList.get(1)).thenThrow(new?RuntimeException());?//?拋出異常??
      7. ???
      8. //第一個會打印?"first"??
      9. System.out.println(mockedList.get(0));??
      10. ???
      11. //接下來會拋出runtime異常??
      12. System.out.println(mockedList.get(1));??
      13. ???
      14. //接下來會打印"null",這是因為沒有stub?get(999)??
      15. System.out.println(mockedList.get(999));??
      16. ????
      17. //?可以選擇性地驗證行為,比如只關心是否調用過get(0),而不關心是否調用過get(1)??
      18. verify(mockedList).get(0);??
      ?

    代碼覆蓋率

    比較流行的工具是Emma和Jacoco,Ecliplse插件有eclemma。eclemma2.0之前采用的是Emma,之后采用的是Jacoco。這里主要介紹一下Jacoco。Eclmama由于是Eclipse插件,所以非常易用,就不多做介紹了。

    Jacoco

    Jacoco可以嵌入到Ant、Maven中,也可以使用Java Agent技術監控任意Java程序,也可以使用Java Api來定制功能。
    Jacoco會監控JVM中的調用,生成監控結果(默認保存在jacoco.exec文件中),然后分析此結果,配合源代碼生成覆蓋率報告。需要注意的是:監控和分析這兩步,必須使用相同的Class文件,否則由于Class不同,而無法定位到具體的方法,導致覆蓋率均為0%。

    Java Agent嵌入

    首先,需要下載jacocoagent.jar文件,然后在Java程序啟動參數后面加上?-javaagent:[yourpath/]jacocoagent.jar=[option1]=[value1],[option2]=[value2],具體的options可以在此頁面找到。默認會在JVM關閉時(注意不能是kill -9),輸出監控結果到jacoco.exec文件中,也可以通過socket來實時地輸出監控報告(可以在Example代碼中找到簡單實現)。

    Java Report

    可以使用Ant、Mvn或Eclipse來分析jacoco.exec文件,也可以通過API來分析。

    1. public?void?createReport()?throws?Exception?{??
    2. ????????????//?讀取監控結果??
    3. ????final?FileInputStream?fis?=?new?FileInputStream(new?File("jacoco.exec"));??
    4. ????final?ExecutionDataReader?executionDataReader?=?new?ExecutionDataReader(fis);??
    5. ????????????//?執行數據信息??
    6. ????ExecutionDataStore?executionDataStore?=?new?ExecutionDataStore();??
    7. ????????????//?會話信息??
    8. ????SessionInfoStore?sessionInfoStore?=?new?SessionInfoStore();??
    9. ???
    10. ????executionDataReader.setExecutionDataVisitor(executionDataStore);??
    11. ????executionDataReader.setSessionInfoVisitor(sessionInfoStore);??
    12. ???
    13. ????while?(executionDataReader.read())?{??
    14. ????}??
    15. ???
    16. ????fis.close();??
    17. ???????????????
    18. ????????????//?分析結構??
    19. ????????????final?CoverageBuilder?coverageBuilder?=?new?CoverageBuilder();??
    20. ????final?Analyzer?analyzer?=?new?Analyzer(executionDataStore,?coverageBuilder);??
    21. ???
    22. ????????????//?傳入監控時的Class文件目錄,注意必須與監控時的一樣??
    23. ????File?classesDirectory?=?new?File("classes");??
    24. ????analyzer.analyzeAll(classesDirectory);??
    25. ???
    26. ????IBundleCoverage?bundleCoverage?=?coverageBuilder.getBundle("Title");??
    27. ????????????//?輸出報告??
    28. ????????File?reportDirectory?=?new?File("report");?//?報告所在的目錄??
    29. ????final?HTMLFormatter?htmlFormatter?=?new?HTMLFormatter();??//?HTML格式??
    30. ????final?IReportVisitor?visitor?=?htmlFormatter.createVisitor(new?FileMultiReportOutput(reportDirectory));??
    31. ????????????//?必須先調用visitInfo??
    32. ????visitor.visitInfo(sessionInfoStore.getInfos(),?executionDataStore.getContents());??
    33. ????File?sourceDirectory?=?new?File("src");?//?源代碼目錄??
    34. ????????????//?遍歷所有的源代碼??
    35. ????????????//?如果不執行此過程,則在報告中只能看到方法名,但是無法查看具體的覆蓋(因為沒有源代碼頁面)??
    36. ????visitor.visitBundle(bundleCoverage,?new?DirectorySourceFileLocator(sourceDirectory,?"utf-8",?4));??
    37. ????????????//?執行完畢??
    38. ????visitor.visitEnd();??
    39. } ?

轉載于:https://my.oschina.net/zhanghaiyang/blog/592971

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/274948.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/274948.shtml
英文地址,請注明出處:http://en.pswp.cn/news/274948.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

我在黑暗中看到你眼中的月光_你好黑暗,我的老朋友

我在黑暗中看到你眼中的月光(Originally published on https://web.dev/prefers-color-scheme/.)(最初發布于https://web.dev/prefers-color-scheme/ 。) 介紹 (Introduction) 📚 I have done a lot of background research on the history and theory of dark mod…

ant 實現批量打包android應用

很多的應用中需要加上應用推廣的統計,如果一個一個的去生成不同渠道包的應用,效率低不說,還有可能不小心弄錯了分發渠道,使用ant可以批量生成應用。一、添加渠道包信息為了統計渠道信息,就不得不在程序的某個地方加入渠…

Element Plus 正式版發布啦!

大家好,我是若川。祝大家新年快樂,開工大吉。公眾號回復「紅包」可以領取源碼共讀紅包封面。持續組織了6個月源碼共讀活動,感興趣的可以點此加我微信 ruochuan12 參與,每周大家一起學習200行左右的源碼,共同進步。同時…

大型網站技術架構(一)大型網站架構演化

2019獨角獸企業重金招聘Python工程師標準>>> 看完了有一本書,就應該有所收獲,有所總結,最近把《大型網站技術架構》一書給看完了,給人的印象實在深刻,再加上之前也搞過書本上講的反向代理和負載均衡以及ses…

永不示弱_永不過時的網頁設計:今天和2000年的在線投資組合

永不示弱重點 (Top highlight)Philippe Starck, a renowned industrial designer, once said:著名的工業設計師Philippe Starck曾經說過: “A designer has a duty to create timeless design. To be timeless you have to think really far into the future, not …

如何使用 React 創建一個作品集網站

大家好,我是若川。持續組織了6個月源碼共讀活動,感興趣的可以點此加我微信 ruochuan12 參與,每周大家一起學習200行左右的源碼,共同進步。同時極力推薦訂閱我寫的《學習源碼整體架構系列》 包含20余篇源碼文章。今天,你…

博弈論入門 HDU 1850

Problem Description 一年在外 父母時刻牽掛春節回家 你能做幾天好孩子嗎寒假里嘗試做做下面的事情吧陪媽媽逛一次菜場悄悄給爸爸買個小禮物主動地 強烈地 要求洗一次碗某一天早起 給爸媽用心地做回早餐如果愿意 你還可以和爸媽說咱們玩個小游戲吧 ACM課上學的呢~下…

新的一年,如何高效學習前端前沿知識~

今天強烈推薦一些互聯網行業內優質技術公眾號,互聯網人大部分都關注了,包括目前主流的公司技術團隊號,技術社區號,個人技術號,這些號行業深耕已久,會給你帶來事半功倍的效果。公眾號那么多,文章…

RabbitMQ學習總結(7)——Spring整合RabbitMQ實例

2019獨角獸企業重金招聘Python工程師標準>>> 1.RabbitMQ簡介 RabbitMQ是流行的開源消息隊列系統,用erlang語言開發。RabbitMQ是AMQP(高級消息隊列協議)的標準實現。 官網:http://www.rabbitmq.com/ 2.Spring集成Rabbi…

UIScrollView實現不全屏分頁的小技巧

瀏覽一系列圖片時,我們會經常使用UIScrollView來進行實現,因為其自帶的pagingEnabled屬性,可以非常方便的自動支持手勢左右輕掃切換切換頁面。pagingEnabled不過最近做的一個產品,設計的效果有所不同,希望每一頁圖片的…

談談對java中分層的理解_讓我們談談網頁設計中的卡片設計

談談對java中分層的理解“I want a card”, this is the first demand point that the customer said in the last issue when talking to me about demand. There is no doubt that the card type is excellent for both PC and mobile phones. From online shopping malls to…

1-jdk的安裝與配置

1- Jvm、jdk、jre之間的關系 JVM:Java虛擬機,保證java程序跨平臺。(Java Virtual Machine)JRE: Java運行環境,包含JVM和核心類庫。如果只是想運行java程序,只要安裝JRE即可。(Java R…

來自未來,2022 年的前端人都在做什么?

大家好,我是若川。持續組織了6個月源碼共讀活動,感興趣的可以點此加我微信 ruochuan12 參與,每周大家一起學習200行左右的源碼,共同進步。同時極力推薦訂閱我寫的《學習源碼整體架構系列》 包含20余篇源碼文章。來自上帝視角的總覽…

模擬

狀態壓縮 uva 12368 - Candles 2011 - Dhaka 1 #include<stdio.h> 2 #include<string.h> 3 #include<iostream> 4 #include<string> 5 #include<algorithm> 6 #include<math.h> 7 #include<map> 8 #include<queue> 9 using…

qt ui指針和本類對象_您需要了解的有關UI設計的形狀和對象的所有信息

qt ui指針和本類對象重點 (Top highlight)第1部分 (Part 1) So you’re thinking about becoming a UX/UI designer, but are afraid to start? Don’t worry. It’s easier than you think. You only need a solid foundation and a lot of dedication. I can’t help you wi…

移動端h5頁面復制粘貼(兼容到ios9安卓4.0.0)

項目使用jquery框架純h5復制粘貼解決了iscroll4阻止所有默認事件&#xff0c;長按無法彈出復制菜單項目需要寫一個上拉加載頁面&#xff0c;頁面中的物流信息需要可復制粘貼&#xff0c;同時需要兼容到ios9和安卓4.0.0, 經過大量搜索&#xff0c;最終使用clipboard。代碼如下 &…

2021 大前端技術回顧及未來展望

大家好&#xff0c;我是若川。持續組織了6個月源碼共讀活動&#xff0c;感興趣的可以點此加我微信 ruochuan12 參與&#xff0c;每周大家一起學習200行左右的源碼&#xff0c;共同進步。同時極力推薦訂閱我寫的《學習源碼整體架構系列》 包含20余篇源碼文章。歷史面試系列2021 …

最近想讀的書想做的事

越來越多了&#xff0c;但是總是還沒開始&#xff0c;一天拿出一小時&#xff0c;周末拿出一上午。加油加油 2012/3/27 C標準庫 C專家編程Expert C Programming Deep C Secrets CodeCraft編程匠藝&#xff1a;編寫卓越的代碼 代碼之美 重看 編程珠璣 編程卓越之道 卷1 卷2 代碼…

skysat重訪周期_重訪小惡夢

skysat重訪周期You awaken with a start, the nightmare still fogging your mind with terror. Rain falls through cracks in the ceiling above you. The room is sparse, metallic, desolate. Searching the pockets of your yellow raincoat, you find only a cigarette l…

Python這些位運算的妙用,絕對讓你大開眼界

位運算的性能大家想必是清楚的&#xff0c;效率絕對高。相信愛好源碼的同學&#xff0c;在學習閱讀源碼的過程中會發現不少源碼使用了位運算。但是為啥在實際編程過程中應用少呢&#xff1f;想必最大的原因&#xff0c;是較為難懂。不過&#xff0c;在面試的過程中&#xff0c;…