[{"data":1,"prerenderedAt":3834},["ShallowReactive",2],{"/de-de/blog/refactor-code-into-modern-languages-with-ai-powered-gitlab-duo":3,"navigation-de-de":3051,"banner-de-de":3483,"footer-de-de":3491,"blog-post-authors-de-de-Michael Friedrich":3731,"blog-related-posts-de-de-refactor-code-into-modern-languages-with-ai-powered-gitlab-duo":3746,"blog-promotions-de-de":3771,"next-steps-de-de":3824},{"id":4,"title":5,"authors":6,"body":8,"category":3029,"date":3030,"description":3031,"extension":3032,"externalUrl":3033,"faq":3033,"featured":3034,"heroImage":3035,"meta":3036,"navigation":226,"path":3037,"seo":3038,"slug":3042,"stem":3043,"tags":3044,"template":3048,"updatedDate":3049,"__hash__":3050},"blogPosts/de-de/blog/refactor-code-into-modern-languages-with-ai-powered-gitlab-duo.md","Code mit KI-gestütztem GitLab Duo in moderne Sprachen refaktorisieren ",[7],"Michael Friedrich",{"type":9,"value":10,"toc":3012},"minimark",[11,22,42,45,141,146,149,154,157,160,936,939,949,956,979,982,995,1004,1007,1010,1016,1459,1490,1510,1525,1536,1539,1739,1745,1751,1755,1758,1766,1775,1778,1918,1924,1930,1937,1941,1950,1953,1981,1987,1993,2002,2008,2017,2024,2052,2061,2067,2071,2074,2078,2087,2090,2512,2541,2547,2559,2565,2568,2571,2574,2581,2845,2848,2864,2870,2892,2898,2901,2904,2907,2913,2916,2919,2925,2940,2946,2949,2972,2976,2996,2999,3008],[12,13,14,15,21],"p",{},"Egal, ob es deine Aufgabe ist, die Codebase oder das Framework zu modernisieren, indem du zu einer neuen Programmiersprache wechselst, oder ob du mehr über neue Funktionen in dieser Sprache erfahren möchtest: das KI-gestützte ",[16,17,20],"a",{"href":18,"rel":19},"https://about.gitlab.com/gitlab-duo-agent-platform/",[],"GitLab Duo"," kann dir dabei helfen. Hier erfährst du anhand von Beispielen aus meiner 20-jährigen Berufserfahrung als Programmier(in), wie du Herausforderungen beim Code-Refactoring am besten meisterst.",[12,23,24,25,29,30,35,36,41],{},"Die Prompts und Beispiele in diesem Artikel werden in verschiedenen IDEs gezeigt: VS Code und JetBrains (IntelliJ IDEA, PyCharm und CLion) mit den jeweiligen installierten (GitLab-Duo-Erweiterungen/Plugins]",[16,26,27],{"href":27,"rel":28},"https://docs.gitlab.com/user/project/r/",[]," epository/code_suggestions/supported_extensions.html). Die Entwicklungsumgebung nutzt GitLab.com, darunter Updates auf Anthropic Claude 3.5 als großes Sprachmodell (LLM) für ",[16,31,34],{"href":32,"rel":33},"https://docs.gitlab.com/user/gitlab_duo/#code-suggestions",[],"Codevorschläge"," und den ",[16,37,40],{"href":38,"rel":39},"https://docs.gitlab.com/user/gitlab_duo/#gitlab-duo-chat",[],"Chat"," von GitLab Duo. Spoiler: Sie sind noch leistungsstärker und effizienter.",[12,43,44],{},"Du kannst zu den einzelnen Abschnitten dieses Artikels springen oder ihn von Anfang bis Ende lesen. Der Quellcode und die Herausforderungen mit den jeweiligen Übungen sind zum Selbststudium geeignet.",[46,47,48,89,109,135],"ul",{},[49,50,51,55],"li",{},[16,52,54],{"href":53},"#refactor-code-to-modern-programming-language-standards","Code in moderne Programmiersprachen-Standards refaktorieren",[46,56,57,63,83],{},[49,58,59],{},[16,60,62],{"href":61},"#generate-java-7-and-refactor-to-java-8","Java 7 generieren und zu Java 8 refaktorisieren",[49,64,65,69],{},[16,66,68],{"href":67},"#refactor-across-c%2B%2B-standards","Über C++-Standards refaktorisieren",[46,70,71,77],{},[49,72,73],{},[16,74,76],{"href":75},"#migration-refactor-c%2B%2B03-into-c%2B%2B14","Migration: C++03 zu C++14 refaktorisieren",[49,78,79],{},[16,80,82],{"href":81},"#downgrade-refactor-c%2B%2B23-to-c%2B%2B11","Downgrade: C++23 zu C++11 refaktorisieren",[49,84,85],{},[16,86,88],{"href":87},"#explain-and-refactor-cobol","COBOL erklären und refaktorisieren",[49,90,91,95],{},[16,92,94],{"href":93},"#refactor-a-language-into-another-language","Eine Sprache in eine andere refaktorisieren",[46,96,97,103],{},[49,98,99],{},[16,100,102],{"href":101},"#refactor-c-to-rust","C zu Rust refaktorisieren",[49,104,105],{},[16,106,108],{"href":107},"#refactor-perl-to-python","Perl zu Python refaktorisieren",[49,110,111,115],{},[16,112,114],{"href":113},"#more-refactoring-hands-on","Weitere Tipps zum Refaktorisieren",[46,116,117,123,129],{},[49,118,119],{},[16,120,122],{"href":121},"#refactor-javascript","JavaScript refaktorisieren",[49,124,125],{},[16,126,128],{"href":127},"#refactor-bash-to-zsh-or-sh","Bash zu ZSH oder SH refaktorisieren",[49,130,131],{},[16,132,134],{"href":133},"#more-use-cases-and-tutorials","Weitere Anwendungsfälle und Tutorials",[49,136,137],{},[16,138,140],{"href":139},"#key-takeaways","Wichtige Erkenntnisse",[142,143,145],"h2",{"id":144},"code-in-moderne-programmiersprachen-standards-refaktorisieren","Code in moderne Programmiersprachen-Standards refaktorisieren",[12,147,148],{},"Im nächsten Abschnitt erfährst du, wie du die sprachspezifischen Unterschiede einer Programmiersprache refaktorisierst, erklärst und verstehst.",[150,151,153],"h3",{"id":152},"java-7-generieren-und-auf-java-8-refaktorisieren","Java 7 generieren und auf Java 8 refaktorisieren",[12,155,156],{},"Ein Kunde wollte wissen, ob GitLab Duo Java 7 unterstützt. Beim Testen von Codevorschlägen und Chat-Prompts, um spezifischen Code für Java 7 zu erstellen, dachte ich auch über Hilfe bei der Migration nach. Anthropic Claude 3.5 kann die sprachspezifischen Unterschiede verstehen, ebenso wie GitLab Duo.",[12,158,159],{},"Das folgende Beispiel zeigt eine Aufforderung zum Generieren von Java-7-Code mit Codevorschlägen.",[161,162,167],"pre",{"className":163,"code":164,"language":165,"meta":166,"style":166},"language-java shiki shiki-themes github-light","// Generate a new class for a File Manager. Use Java 7 features only.\nimport java.io.*;\nimport java.nio.file.*;\nimport java.util.*;\n\npublic class FileManager {\n    private Path rootDirectory;\n\n    public FileManager(String rootPath) throws IOException {\n        this.rootDirectory = Paths.get(rootPath);\n        if (!Files.exists(rootDirectory)) {\n            Files.createDirectories(rootDirectory);\n        }\n    }\n\n    public void createFile(String fileName, String content) throws IOException {\n        Path filePath = rootDirectory.resolve(fileName);\n        Files.write(filePath, content.getBytes(), StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING);\n    }\n\n    public String readFile(String fileName) throws IOException {\n        Path filePath = rootDirectory.resolve(fileName);\n        return new String(Files.readAllBytes(filePath));\n    }\n\n    public void deleteFile(String fileName) throws IOException {\n        Path filePath = rootDirectory.resolve(fileName);\n        Files.delete(filePath);\n    }\n\n    public List\u003CString> listFiles() throws IOException {\n        List\u003CString> fileList = new ArrayList\u003C>();\n        try (DirectoryStream\u003CPath> stream = Files.newDirectoryStream(rootDirectory)) {\n            for (Path file : stream) {\n                fileList.add(file.getFileName().toString());\n            }\n        }\n        return fileList;\n    }\n\n    public void copyFile(String sourceFileName, String destinationFileName) throws IOException {\n        Path sourcePath = rootDirectory.resolve(sourceFileName);\n        Path destinationPath = rootDirectory.resolve(destinationFileName);\n        Files.copy(sourcePath, destinationPath, StandardCopyOption.REPLACE_EXISTING);\n    }\n\n    public void moveFile(String sourceFileName, String destinationFileName) throws IOException {\n        Path sourcePath = rootDirectory.resolve(sourceFileName);\n        Path destinationPath = rootDirectory.resolve(destinationFileName);\n        Files.move(sourcePath, destinationPath, StandardCopyOption.REPLACE_EXISTING);\n    }\n\n    public long getFileSize(String fileName) throws IOException {\n        Path filePath = rootDirectory.resolve(fileName);\n        return Files.size(filePath);\n    }\n\n    public boolean fileExists(String fileName) {\n        Path filePath = rootDirectory.resolve(fileName);\n        return Files.exists(filePath);\n    }\n}\n","java","",[168,169,170,179,197,209,221,228,244,253,258,282,303,324,336,342,348,353,381,398,416,421,426,447,460,481,486,491,511,524,535,540,545,569,587,612,627,651,657,662,670,675,680,706,721,736,747,752,757,781,794,807,817,822,827,848,861,873,878,883,901,914,925,930],"code",{"__ignoreMap":166},[171,172,175],"span",{"class":173,"line":174},"line",1,[171,176,178],{"class":177},"sAwPA","// Generate a new class for a File Manager. Use Java 7 features only.\n",[171,180,182,186,190,194],{"class":173,"line":181},2,[171,183,185],{"class":184},"sD7c4","import",[171,187,189],{"class":188},"sgsFI"," java.io.",[171,191,193],{"class":192},"sYu0t","*",[171,195,196],{"class":188},";\n",[171,198,200,202,205,207],{"class":173,"line":199},3,[171,201,185],{"class":184},[171,203,204],{"class":188}," java.nio.file.",[171,206,193],{"class":192},[171,208,196],{"class":188},[171,210,212,214,217,219],{"class":173,"line":211},4,[171,213,185],{"class":184},[171,215,216],{"class":188}," java.util.",[171,218,193],{"class":192},[171,220,196],{"class":188},[171,222,224],{"class":173,"line":223},5,[171,225,227],{"emptyLinePlaceholder":226},true,"\n",[171,229,231,234,237,241],{"class":173,"line":230},6,[171,232,233],{"class":184},"public",[171,235,236],{"class":184}," class",[171,238,240],{"class":239},"s7eDp"," FileManager",[171,242,243],{"class":188}," {\n",[171,245,247,250],{"class":173,"line":246},7,[171,248,249],{"class":184},"    private",[171,251,252],{"class":188}," Path rootDirectory;\n",[171,254,256],{"class":173,"line":255},8,[171,257,227],{"emptyLinePlaceholder":226},[171,259,261,264,266,269,273,276,279],{"class":173,"line":260},9,[171,262,263],{"class":184},"    public",[171,265,240],{"class":239},[171,267,268],{"class":188},"(String ",[171,270,272],{"class":271},"sqxcx","rootPath",[171,274,275],{"class":188},") ",[171,277,278],{"class":184},"throws",[171,280,281],{"class":188}," IOException {\n",[171,283,285,288,291,294,297,300],{"class":173,"line":284},10,[171,286,287],{"class":192},"        this",[171,289,290],{"class":188},".rootDirectory ",[171,292,293],{"class":184},"=",[171,295,296],{"class":188}," Paths.",[171,298,299],{"class":239},"get",[171,301,302],{"class":188},"(rootPath);\n",[171,304,306,309,312,315,318,321],{"class":173,"line":305},11,[171,307,308],{"class":184},"        if",[171,310,311],{"class":188}," (",[171,313,314],{"class":184},"!",[171,316,317],{"class":188},"Files.",[171,319,320],{"class":239},"exists",[171,322,323],{"class":188},"(rootDirectory)) {\n",[171,325,327,330,333],{"class":173,"line":326},12,[171,328,329],{"class":188},"            Files.",[171,331,332],{"class":239},"createDirectories",[171,334,335],{"class":188},"(rootDirectory);\n",[171,337,339],{"class":173,"line":338},13,[171,340,341],{"class":188},"        }\n",[171,343,345],{"class":173,"line":344},14,[171,346,347],{"class":188},"    }\n",[171,349,351],{"class":173,"line":350},15,[171,352,227],{"emptyLinePlaceholder":226},[171,354,356,358,361,364,366,369,372,375,377,379],{"class":173,"line":355},16,[171,357,263],{"class":184},[171,359,360],{"class":184}," void",[171,362,363],{"class":239}," createFile",[171,365,268],{"class":188},[171,367,368],{"class":271},"fileName",[171,370,371],{"class":188},", String ",[171,373,374],{"class":271},"content",[171,376,275],{"class":188},[171,378,278],{"class":184},[171,380,281],{"class":188},[171,382,384,387,389,392,395],{"class":173,"line":383},17,[171,385,386],{"class":188},"        Path filePath ",[171,388,293],{"class":184},[171,390,391],{"class":188}," rootDirectory.",[171,393,394],{"class":239},"resolve",[171,396,397],{"class":188},"(fileName);\n",[171,399,401,404,407,410,413],{"class":173,"line":400},18,[171,402,403],{"class":188},"        Files.",[171,405,406],{"class":239},"write",[171,408,409],{"class":188},"(filePath, content.",[171,411,412],{"class":239},"getBytes",[171,414,415],{"class":188},"(), StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING);\n",[171,417,419],{"class":173,"line":418},19,[171,420,347],{"class":188},[171,422,424],{"class":173,"line":423},20,[171,425,227],{"emptyLinePlaceholder":226},[171,427,429,431,434,437,439,441,443,445],{"class":173,"line":428},21,[171,430,263],{"class":184},[171,432,433],{"class":188}," String ",[171,435,436],{"class":239},"readFile",[171,438,268],{"class":188},[171,440,368],{"class":271},[171,442,275],{"class":188},[171,444,278],{"class":184},[171,446,281],{"class":188},[171,448,450,452,454,456,458],{"class":173,"line":449},22,[171,451,386],{"class":188},[171,453,293],{"class":184},[171,455,391],{"class":188},[171,457,394],{"class":239},[171,459,397],{"class":188},[171,461,463,466,469,472,475,478],{"class":173,"line":462},23,[171,464,465],{"class":184},"        return",[171,467,468],{"class":184}," new",[171,470,471],{"class":239}," String",[171,473,474],{"class":188},"(Files.",[171,476,477],{"class":239},"readAllBytes",[171,479,480],{"class":188},"(filePath));\n",[171,482,484],{"class":173,"line":483},24,[171,485,347],{"class":188},[171,487,489],{"class":173,"line":488},25,[171,490,227],{"emptyLinePlaceholder":226},[171,492,494,496,498,501,503,505,507,509],{"class":173,"line":493},26,[171,495,263],{"class":184},[171,497,360],{"class":184},[171,499,500],{"class":239}," deleteFile",[171,502,268],{"class":188},[171,504,368],{"class":271},[171,506,275],{"class":188},[171,508,278],{"class":184},[171,510,281],{"class":188},[171,512,514,516,518,520,522],{"class":173,"line":513},27,[171,515,386],{"class":188},[171,517,293],{"class":184},[171,519,391],{"class":188},[171,521,394],{"class":239},[171,523,397],{"class":188},[171,525,527,529,532],{"class":173,"line":526},28,[171,528,403],{"class":188},[171,530,531],{"class":239},"delete",[171,533,534],{"class":188},"(filePath);\n",[171,536,538],{"class":173,"line":537},29,[171,539,347],{"class":188},[171,541,543],{"class":173,"line":542},30,[171,544,227],{"emptyLinePlaceholder":226},[171,546,548,550,553,556,559,562,565,567],{"class":173,"line":547},31,[171,549,263],{"class":184},[171,551,552],{"class":188}," List\u003C",[171,554,555],{"class":184},"String",[171,557,558],{"class":188},"> ",[171,560,561],{"class":239},"listFiles",[171,563,564],{"class":188},"() ",[171,566,278],{"class":184},[171,568,281],{"class":188},[171,570,572,575,577,580,582,584],{"class":173,"line":571},32,[171,573,574],{"class":188},"        List\u003C",[171,576,555],{"class":184},[171,578,579],{"class":188},"> fileList ",[171,581,293],{"class":184},[171,583,468],{"class":184},[171,585,586],{"class":188}," ArrayList\u003C>();\n",[171,588,590,593,596,599,602,604,607,610],{"class":173,"line":589},33,[171,591,592],{"class":184},"        try",[171,594,595],{"class":188}," (DirectoryStream\u003C",[171,597,598],{"class":184},"Path",[171,600,601],{"class":188},"> stream ",[171,603,293],{"class":184},[171,605,606],{"class":188}," Files.",[171,608,609],{"class":239},"newDirectoryStream",[171,611,323],{"class":188},[171,613,615,618,621,624],{"class":173,"line":614},34,[171,616,617],{"class":184},"            for",[171,619,620],{"class":188}," (Path file ",[171,622,623],{"class":184},":",[171,625,626],{"class":188}," stream) {\n",[171,628,630,633,636,639,642,645,648],{"class":173,"line":629},35,[171,631,632],{"class":188},"                fileList.",[171,634,635],{"class":239},"add",[171,637,638],{"class":188},"(file.",[171,640,641],{"class":239},"getFileName",[171,643,644],{"class":188},"().",[171,646,647],{"class":239},"toString",[171,649,650],{"class":188},"());\n",[171,652,654],{"class":173,"line":653},36,[171,655,656],{"class":188},"            }\n",[171,658,660],{"class":173,"line":659},37,[171,661,341],{"class":188},[171,663,665,667],{"class":173,"line":664},38,[171,666,465],{"class":184},[171,668,669],{"class":188}," fileList;\n",[171,671,673],{"class":173,"line":672},39,[171,674,347],{"class":188},[171,676,678],{"class":173,"line":677},40,[171,679,227],{"emptyLinePlaceholder":226},[171,681,683,685,687,690,692,695,697,700,702,704],{"class":173,"line":682},41,[171,684,263],{"class":184},[171,686,360],{"class":184},[171,688,689],{"class":239}," copyFile",[171,691,268],{"class":188},[171,693,694],{"class":271},"sourceFileName",[171,696,371],{"class":188},[171,698,699],{"class":271},"destinationFileName",[171,701,275],{"class":188},[171,703,278],{"class":184},[171,705,281],{"class":188},[171,707,709,712,714,716,718],{"class":173,"line":708},42,[171,710,711],{"class":188},"        Path sourcePath ",[171,713,293],{"class":184},[171,715,391],{"class":188},[171,717,394],{"class":239},[171,719,720],{"class":188},"(sourceFileName);\n",[171,722,724,727,729,731,733],{"class":173,"line":723},43,[171,725,726],{"class":188},"        Path destinationPath ",[171,728,293],{"class":184},[171,730,391],{"class":188},[171,732,394],{"class":239},[171,734,735],{"class":188},"(destinationFileName);\n",[171,737,739,741,744],{"class":173,"line":738},44,[171,740,403],{"class":188},[171,742,743],{"class":239},"copy",[171,745,746],{"class":188},"(sourcePath, destinationPath, StandardCopyOption.REPLACE_EXISTING);\n",[171,748,750],{"class":173,"line":749},45,[171,751,347],{"class":188},[171,753,755],{"class":173,"line":754},46,[171,756,227],{"emptyLinePlaceholder":226},[171,758,760,762,764,767,769,771,773,775,777,779],{"class":173,"line":759},47,[171,761,263],{"class":184},[171,763,360],{"class":184},[171,765,766],{"class":239}," moveFile",[171,768,268],{"class":188},[171,770,694],{"class":271},[171,772,371],{"class":188},[171,774,699],{"class":271},[171,776,275],{"class":188},[171,778,278],{"class":184},[171,780,281],{"class":188},[171,782,784,786,788,790,792],{"class":173,"line":783},48,[171,785,711],{"class":188},[171,787,293],{"class":184},[171,789,391],{"class":188},[171,791,394],{"class":239},[171,793,720],{"class":188},[171,795,797,799,801,803,805],{"class":173,"line":796},49,[171,798,726],{"class":188},[171,800,293],{"class":184},[171,802,391],{"class":188},[171,804,394],{"class":239},[171,806,735],{"class":188},[171,808,810,812,815],{"class":173,"line":809},50,[171,811,403],{"class":188},[171,813,814],{"class":239},"move",[171,816,746],{"class":188},[171,818,820],{"class":173,"line":819},51,[171,821,347],{"class":188},[171,823,825],{"class":173,"line":824},52,[171,826,227],{"emptyLinePlaceholder":226},[171,828,830,832,835,838,840,842,844,846],{"class":173,"line":829},53,[171,831,263],{"class":184},[171,833,834],{"class":184}," long",[171,836,837],{"class":239}," getFileSize",[171,839,268],{"class":188},[171,841,368],{"class":271},[171,843,275],{"class":188},[171,845,278],{"class":184},[171,847,281],{"class":188},[171,849,851,853,855,857,859],{"class":173,"line":850},54,[171,852,386],{"class":188},[171,854,293],{"class":184},[171,856,391],{"class":188},[171,858,394],{"class":239},[171,860,397],{"class":188},[171,862,864,866,868,871],{"class":173,"line":863},55,[171,865,465],{"class":184},[171,867,606],{"class":188},[171,869,870],{"class":239},"size",[171,872,534],{"class":188},[171,874,876],{"class":173,"line":875},56,[171,877,347],{"class":188},[171,879,881],{"class":173,"line":880},57,[171,882,227],{"emptyLinePlaceholder":226},[171,884,886,888,891,894,896,898],{"class":173,"line":885},58,[171,887,263],{"class":184},[171,889,890],{"class":184}," boolean",[171,892,893],{"class":239}," fileExists",[171,895,268],{"class":188},[171,897,368],{"class":271},[171,899,900],{"class":188},") {\n",[171,902,904,906,908,910,912],{"class":173,"line":903},59,[171,905,386],{"class":188},[171,907,293],{"class":184},[171,909,391],{"class":188},[171,911,394],{"class":239},[171,913,397],{"class":188},[171,915,917,919,921,923],{"class":173,"line":916},60,[171,918,465],{"class":184},[171,920,606],{"class":188},[171,922,320],{"class":239},[171,924,534],{"class":188},[171,926,928],{"class":173,"line":927},61,[171,929,347],{"class":188},[171,931,933],{"class":173,"line":932},62,[171,934,935],{"class":188},"}\n",[12,937,938],{},"Du kannst mit folgenden Schritten in deinem IDE fortfahren:",[940,941,942],"ol",{},[49,943,944,945,948],{},"Lerne und verstehe den generierten Code: Wähle den Code im Editor aus (im Screenshot blau), wechsle zum GitLab-Duo-Chat und sende den Slash-Befehl ",[168,946,947],{},"/explain"," als Prompt.",[12,950,951],{},[952,953],"img",{"alt":954,"src":955},"Validiere den generierten Code mit dem Slash-Befehl /explain im GitLab-Duo-Chat","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749675059/Blog/Content%20Images/intellij_java7_generate_refactor.png",[940,957,958,965,976],{"start":181},[49,959,960,961,964],{},"Wandle den Java-7-Code in Java 8 um: Wähle den Code im Editor aus, wechsle zum Chat und sende ",[168,962,963],{},"/refactor using Java 8 features"," als detaillierteren Prompt.",[49,966,967,968,971,972,975],{},"Übe eine Alternative zum Refactoring: Erstelle die neue Datei ",[168,969,970],{},"java8.java"," und generiere Java-8-spezifischen Code mit Codevorschlägen mit dem Prompt ",[168,973,974],{},"// Generate a new class for a File Manager. Use Java 8 features only.",".",[49,977,978],{},"Schreibe weiter Java-8-Code im gleichen Kontext mit KI-basierter Code-Vervollständigung.",[12,980,981],{},"Du kannst dir alle Schritte in dieser Aufnahme ansehen.",[983,984,987,988],"figure",{"className":985},[986],"video_container","\n  ",[989,990,994],"iframe",{"src":991,"frameBorder":992,"allowFullScreen":993},"https://www.youtube.com/embed/XKRv6uBkD2I","0","true"," ",[12,996,997,998,1003],{},"Der Quellcode ist in der ",[16,999,1002],{"href":1000,"rel":1001},"https://gitlab.com/gitlab-da/use-cases/ai/ai-workflows/gitlab-duo-challenges/code-challenges/challenge-generate-refactor-java-7-to-8",[],"GitLab-Duo-Challenge – Java 7 generieren und auf Java 8 refaktorisieren"," verfügbar.",[150,1005,68],{"id":1006},"über-c-standards-refaktorisieren",[12,1008,1009],{},"Der C++-Standard hat eine lange Geschichte und gilt als stabil und ausgereift. Je nach Zielarchitektur und Plattformen hängt der unterstützte Standard vom Compiler des Host-Betriebssystems ab.",[12,1011,1012,1013,975],{},"In meiner Karriere musste ich bereits 25 verschiedene Linux- und Windows-Distributionen in Open-Source-Projekten supporten und habe unterschiedlichsten Compiler-Support für neuere Sprachfunktionen und C++-Standards erlebt. Im Jahr 2015 haben wir uns für C++11-Funktionen entschieden und später C++14 oder C++17 nie mehr angerührt.\nDie Refaktorisierung von Funktionen und Algorithmen zu einem neuen C++-Standard wäre zu aufwändig gewesen und es wäre Hilfe beim Erklären der Unterschiede nötig gewesen. Damals haben wir in Büchern, über Online-Suche, Stack Overflow und manchmal Tools Hilfe zum Refactoring gesucht.Mit KI-basierten Assistenten und GitLab Duo hat sich das alles geändert: Du kannst Codevorschläge und den Chat nutzen, um Quellcode in einem bestimmten C++-Standard bereitzustellen. Dann ist es auch möglich, die verschiedenen Ausgaben zu vergleichen.\nDas folgende Beispiel verwendet einen Prompt, um speziell Quellcode für den C++03-Standard zu generieren. Es implementiert einen einfachen Konfigurations-Parser für das Konfigurationsformat ",[168,1014,1015],{},".ini",[161,1017,1021],{"className":1018,"code":1019,"language":1020,"meta":166,"style":166},"language-c++ shiki shiki-themes github-light","/* Create a config parser which can parse an ini format\nUse C++03 standard only\n */\n\n#include \u003Ciostream>\n#include \u003Cfstream>\n#include \u003Cstring>\n#include \u003Cmap>\n#include \u003Csstream>\n\nclass ConfigParser {\nprivate:\n    std::map\u003Cstd::string, std::map\u003Cstd::string, std::string> > config;\n\npublic:\n    ConfigParser() {}\n\n    bool parse(const std::string& filename) {\n        std::ifstream file(filename.c_str());\n        if (!file.is_open()) {\n            return false;\n        }\n\n        std::string line;\n        std::string currentSection;\n\n        while (std::getline(file, line)) {\n            // Trim whitespace\n            size_t first = line.find_first_not_of(\" \\t\");\n            size_t last = line.find_last_not_of(\" \\t\");\n            if (first == std::string::npos) continue; // Skip empty lines\n            line = line.substr(first, (last - first + 1));\n\n            if (line[0] == '[' && line[line.length() - 1] == ']') {\n                // This is a section\n                currentSection = line.substr(1, line.length() - 2);\n            } else {\n                // This is a key-value pair\n                size_t delimiterPos = line.find('=');\n                if (delimiterPos != std::string::npos) {\n                    std::string key = line.substr(0, delimiterPos);\n                    std::string value = line.substr(delimiterPos + 1);\n                    config[currentSection][key] = value;\n                }\n            }\n        }\n\n        file.close();\n        return true;\n    }\n\n    std::string getValue(const std::string& section, const std::string& key) const {\n        std::map\u003Cstd::string, std::map\u003Cstd::string, std::string> >::const_iterator sectionIt = config.find(section);\n        if (sectionIt != config.end()) {\n            std::map\u003Cstd::string, std::string>::const_iterator keyIt = sectionIt->second.find(key);\n            if (keyIt != sectionIt->second.end()) {\n                return keyIt->second;\n            }\n        }\n        return \"\";\n    }\n\n    void printConfig() const {\n        std::map\u003Cstd::string, std::map\u003Cstd::string, std::string> >::const_iterator sectionIt;\n        for (sectionIt = config.begin(); sectionIt != config.end(); ++sectionIt) {\n            std::cout \u003C\u003C \"[\" \u003C\u003C sectionIt->first \u003C\u003C \"]\" \u003C\u003C std::endl;\n            std::map\u003Cstd::string, std::string>::const_iterator keyIt;\n            for (keyIt = sectionIt->second.begin(); keyIt != sectionIt->second.end(); ++keyIt) {\n                std::cout \u003C\u003C keyIt->first \u003C\u003C \" = \" \u003C\u003C keyIt->second \u003C\u003C std::endl;\n            }\n            std::cout \u003C\u003C std::endl;\n        }\n    }\n};\n\nint main() {\n    ConfigParser parser;\n    if (parser.parse(\"config.ini\")) {\n        std::cout \u003C\u003C \"Config file parsed successfully.\" \u003C\u003C std::endl;\n        parser.printConfig();\n\n        std::cout \u003C\u003C \"Value of 'key1' in 'section1': \" \u003C\u003C parser.getValue(\"section1\", \"key1\") \u003C\u003C std::endl;\n    } else {\n        std::cout \u003C\u003C \"Failed to parse config file.\" \u003C\u003C std::endl;\n    }\n    return 0;\n}\n","c++",[168,1022,1023,1028,1033,1038,1042,1047,1052,1057,1062,1067,1071,1076,1081,1086,1090,1095,1100,1104,1109,1114,1119,1124,1128,1132,1137,1142,1146,1151,1156,1161,1166,1171,1176,1180,1185,1190,1195,1200,1205,1210,1215,1220,1225,1230,1235,1239,1243,1247,1252,1257,1261,1265,1270,1275,1280,1285,1290,1295,1299,1303,1308,1312,1316,1322,1328,1334,1340,1346,1352,1358,1363,1369,1374,1379,1385,1390,1396,1402,1408,1414,1420,1425,1431,1437,1443,1448,1454],{"__ignoreMap":166},[171,1024,1025],{"class":173,"line":174},[171,1026,1027],{},"/* Create a config parser which can parse an ini format\n",[171,1029,1030],{"class":173,"line":181},[171,1031,1032],{},"Use C++03 standard only\n",[171,1034,1035],{"class":173,"line":199},[171,1036,1037],{}," */\n",[171,1039,1040],{"class":173,"line":211},[171,1041,227],{"emptyLinePlaceholder":226},[171,1043,1044],{"class":173,"line":223},[171,1045,1046],{},"#include \u003Ciostream>\n",[171,1048,1049],{"class":173,"line":230},[171,1050,1051],{},"#include \u003Cfstream>\n",[171,1053,1054],{"class":173,"line":246},[171,1055,1056],{},"#include \u003Cstring>\n",[171,1058,1059],{"class":173,"line":255},[171,1060,1061],{},"#include \u003Cmap>\n",[171,1063,1064],{"class":173,"line":260},[171,1065,1066],{},"#include \u003Csstream>\n",[171,1068,1069],{"class":173,"line":284},[171,1070,227],{"emptyLinePlaceholder":226},[171,1072,1073],{"class":173,"line":305},[171,1074,1075],{},"class ConfigParser {\n",[171,1077,1078],{"class":173,"line":326},[171,1079,1080],{},"private:\n",[171,1082,1083],{"class":173,"line":338},[171,1084,1085],{},"    std::map\u003Cstd::string, std::map\u003Cstd::string, std::string> > config;\n",[171,1087,1088],{"class":173,"line":344},[171,1089,227],{"emptyLinePlaceholder":226},[171,1091,1092],{"class":173,"line":350},[171,1093,1094],{},"public:\n",[171,1096,1097],{"class":173,"line":355},[171,1098,1099],{},"    ConfigParser() {}\n",[171,1101,1102],{"class":173,"line":383},[171,1103,227],{"emptyLinePlaceholder":226},[171,1105,1106],{"class":173,"line":400},[171,1107,1108],{},"    bool parse(const std::string& filename) {\n",[171,1110,1111],{"class":173,"line":418},[171,1112,1113],{},"        std::ifstream file(filename.c_str());\n",[171,1115,1116],{"class":173,"line":423},[171,1117,1118],{},"        if (!file.is_open()) {\n",[171,1120,1121],{"class":173,"line":428},[171,1122,1123],{},"            return false;\n",[171,1125,1126],{"class":173,"line":449},[171,1127,341],{},[171,1129,1130],{"class":173,"line":462},[171,1131,227],{"emptyLinePlaceholder":226},[171,1133,1134],{"class":173,"line":483},[171,1135,1136],{},"        std::string line;\n",[171,1138,1139],{"class":173,"line":488},[171,1140,1141],{},"        std::string currentSection;\n",[171,1143,1144],{"class":173,"line":493},[171,1145,227],{"emptyLinePlaceholder":226},[171,1147,1148],{"class":173,"line":513},[171,1149,1150],{},"        while (std::getline(file, line)) {\n",[171,1152,1153],{"class":173,"line":526},[171,1154,1155],{},"            // Trim whitespace\n",[171,1157,1158],{"class":173,"line":537},[171,1159,1160],{},"            size_t first = line.find_first_not_of(\" \\t\");\n",[171,1162,1163],{"class":173,"line":542},[171,1164,1165],{},"            size_t last = line.find_last_not_of(\" \\t\");\n",[171,1167,1168],{"class":173,"line":547},[171,1169,1170],{},"            if (first == std::string::npos) continue; // Skip empty lines\n",[171,1172,1173],{"class":173,"line":571},[171,1174,1175],{},"            line = line.substr(first, (last - first + 1));\n",[171,1177,1178],{"class":173,"line":589},[171,1179,227],{"emptyLinePlaceholder":226},[171,1181,1182],{"class":173,"line":614},[171,1183,1184],{},"            if (line[0] == '[' && line[line.length() - 1] == ']') {\n",[171,1186,1187],{"class":173,"line":629},[171,1188,1189],{},"                // This is a section\n",[171,1191,1192],{"class":173,"line":653},[171,1193,1194],{},"                currentSection = line.substr(1, line.length() - 2);\n",[171,1196,1197],{"class":173,"line":659},[171,1198,1199],{},"            } else {\n",[171,1201,1202],{"class":173,"line":664},[171,1203,1204],{},"                // This is a key-value pair\n",[171,1206,1207],{"class":173,"line":672},[171,1208,1209],{},"                size_t delimiterPos = line.find('=');\n",[171,1211,1212],{"class":173,"line":677},[171,1213,1214],{},"                if (delimiterPos != std::string::npos) {\n",[171,1216,1217],{"class":173,"line":682},[171,1218,1219],{},"                    std::string key = line.substr(0, delimiterPos);\n",[171,1221,1222],{"class":173,"line":708},[171,1223,1224],{},"                    std::string value = line.substr(delimiterPos + 1);\n",[171,1226,1227],{"class":173,"line":723},[171,1228,1229],{},"                    config[currentSection][key] = value;\n",[171,1231,1232],{"class":173,"line":738},[171,1233,1234],{},"                }\n",[171,1236,1237],{"class":173,"line":749},[171,1238,656],{},[171,1240,1241],{"class":173,"line":754},[171,1242,341],{},[171,1244,1245],{"class":173,"line":759},[171,1246,227],{"emptyLinePlaceholder":226},[171,1248,1249],{"class":173,"line":783},[171,1250,1251],{},"        file.close();\n",[171,1253,1254],{"class":173,"line":796},[171,1255,1256],{},"        return true;\n",[171,1258,1259],{"class":173,"line":809},[171,1260,347],{},[171,1262,1263],{"class":173,"line":819},[171,1264,227],{"emptyLinePlaceholder":226},[171,1266,1267],{"class":173,"line":824},[171,1268,1269],{},"    std::string getValue(const std::string& section, const std::string& key) const {\n",[171,1271,1272],{"class":173,"line":829},[171,1273,1274],{},"        std::map\u003Cstd::string, std::map\u003Cstd::string, std::string> >::const_iterator sectionIt = config.find(section);\n",[171,1276,1277],{"class":173,"line":850},[171,1278,1279],{},"        if (sectionIt != config.end()) {\n",[171,1281,1282],{"class":173,"line":863},[171,1283,1284],{},"            std::map\u003Cstd::string, std::string>::const_iterator keyIt = sectionIt->second.find(key);\n",[171,1286,1287],{"class":173,"line":875},[171,1288,1289],{},"            if (keyIt != sectionIt->second.end()) {\n",[171,1291,1292],{"class":173,"line":880},[171,1293,1294],{},"                return keyIt->second;\n",[171,1296,1297],{"class":173,"line":885},[171,1298,656],{},[171,1300,1301],{"class":173,"line":903},[171,1302,341],{},[171,1304,1305],{"class":173,"line":916},[171,1306,1307],{},"        return \"\";\n",[171,1309,1310],{"class":173,"line":927},[171,1311,347],{},[171,1313,1314],{"class":173,"line":932},[171,1315,227],{"emptyLinePlaceholder":226},[171,1317,1319],{"class":173,"line":1318},63,[171,1320,1321],{},"    void printConfig() const {\n",[171,1323,1325],{"class":173,"line":1324},64,[171,1326,1327],{},"        std::map\u003Cstd::string, std::map\u003Cstd::string, std::string> >::const_iterator sectionIt;\n",[171,1329,1331],{"class":173,"line":1330},65,[171,1332,1333],{},"        for (sectionIt = config.begin(); sectionIt != config.end(); ++sectionIt) {\n",[171,1335,1337],{"class":173,"line":1336},66,[171,1338,1339],{},"            std::cout \u003C\u003C \"[\" \u003C\u003C sectionIt->first \u003C\u003C \"]\" \u003C\u003C std::endl;\n",[171,1341,1343],{"class":173,"line":1342},67,[171,1344,1345],{},"            std::map\u003Cstd::string, std::string>::const_iterator keyIt;\n",[171,1347,1349],{"class":173,"line":1348},68,[171,1350,1351],{},"            for (keyIt = sectionIt->second.begin(); keyIt != sectionIt->second.end(); ++keyIt) {\n",[171,1353,1355],{"class":173,"line":1354},69,[171,1356,1357],{},"                std::cout \u003C\u003C keyIt->first \u003C\u003C \" = \" \u003C\u003C keyIt->second \u003C\u003C std::endl;\n",[171,1359,1361],{"class":173,"line":1360},70,[171,1362,656],{},[171,1364,1366],{"class":173,"line":1365},71,[171,1367,1368],{},"            std::cout \u003C\u003C std::endl;\n",[171,1370,1372],{"class":173,"line":1371},72,[171,1373,341],{},[171,1375,1377],{"class":173,"line":1376},73,[171,1378,347],{},[171,1380,1382],{"class":173,"line":1381},74,[171,1383,1384],{},"};\n",[171,1386,1388],{"class":173,"line":1387},75,[171,1389,227],{"emptyLinePlaceholder":226},[171,1391,1393],{"class":173,"line":1392},76,[171,1394,1395],{},"int main() {\n",[171,1397,1399],{"class":173,"line":1398},77,[171,1400,1401],{},"    ConfigParser parser;\n",[171,1403,1405],{"class":173,"line":1404},78,[171,1406,1407],{},"    if (parser.parse(\"config.ini\")) {\n",[171,1409,1411],{"class":173,"line":1410},79,[171,1412,1413],{},"        std::cout \u003C\u003C \"Config file parsed successfully.\" \u003C\u003C std::endl;\n",[171,1415,1417],{"class":173,"line":1416},80,[171,1418,1419],{},"        parser.printConfig();\n",[171,1421,1423],{"class":173,"line":1422},81,[171,1424,227],{"emptyLinePlaceholder":226},[171,1426,1428],{"class":173,"line":1427},82,[171,1429,1430],{},"        std::cout \u003C\u003C \"Value of 'key1' in 'section1': \" \u003C\u003C parser.getValue(\"section1\", \"key1\") \u003C\u003C std::endl;\n",[171,1432,1434],{"class":173,"line":1433},83,[171,1435,1436],{},"    } else {\n",[171,1438,1440],{"class":173,"line":1439},84,[171,1441,1442],{},"        std::cout \u003C\u003C \"Failed to parse config file.\" \u003C\u003C std::endl;\n",[171,1444,1446],{"class":173,"line":1445},85,[171,1447,347],{},[171,1449,1451],{"class":173,"line":1450},86,[171,1452,1453],{},"    return 0;\n",[171,1455,1457],{"class":173,"line":1456},87,[171,1458,935],{},[12,1460,1461,1462,1467,1468,1473,1474,1479,1480,1467,1483,1467,1486,1489],{},"The same prompts can be applied to ",[16,1463,1466],{"href":1464,"rel":1465},"https://docs.gitlab.com/user/gitlab_duo_chat/examples/#explain-code-in-the-ide",[],"explaining code",", ",[16,1469,1472],{"href":1470,"rel":1471},"https://docs.gitlab.com/user/gitlab_duo_chat/examples/#write-tests-in-the-ide",[],"generating tests",", and even ",[16,1475,1478],{"href":1476,"rel":1477},"https://docs.gitlab.com/user/gitlab_duo_chat/examples/#refactor-code-in-the-ide",[],"refactoring code",": ",[168,1481,1482],{},"/explain focus on C++03 features",[168,1484,1485],{},"/tests for C++03 features",[168,1487,1488],{},"/refactor into C++03",".\nDie folgenden C+ -Standards wurden für die Arbeit mit GitLab Duo Codevorschläge getestet:",[46,1491,1492,1495,1498,1501,1504,1507],{},[49,1493,1494],{},"C++03",[49,1496,1497],{},"C++11",[49,1499,1500],{},"C++14",[49,1502,1503],{},"C++17",[49,1505,1506],{},"C++20",[49,1508,1509],{},"C++23",[12,1511,1512,1513,1518,1519,1524],{},"Den Quellcode findest du in der ",[16,1514,1517],{"href":1515,"rel":1516},"https://gitlab.com/gitlab-da/use-cases/ai/ai-workflows/gitlab-duo-challenges/code-challenges/challenge-refactor-cpp-standards-config-parser",[],"Challenge –  Cpp-Standards Konfigurations-Parser refaktorisieren",".\nEs gibt viele verschiedene Kombinationen, um den Quellcode zwischen den C++-Standards zu refaktorisieren. Die folgenden Beispiele zeigen eine Modernisierung des C++-Codes mit Versionsupgrades, testen aber auch ein Downgrade, als ambitionierte Entwickler(innen) C++20 verwenden wollten, aber C++11 verwenden mussten, um den Umgebungen ihrer Geschäftskund(inn)en zu entsprechen.#### Migration: C++03 in C++14 refaktorisieren\nDas Ziel ist es, den Code zu modernisieren und die Veränderungen zwischen C++03 und C++14 zu verstehen. Öffne den ",[16,1520,1523],{"href":1521,"rel":1522},"https://gitlab.com/gitlab-da/use-cases/ai/ai-workflows/gitlab-duo-challenges/code-challenges/challenge-refactor-cpp-standards-config-parser/-/blob/main/03.cpp?ref_type=heads",[],"03.cpp","-Quellcode in der IDE, wähle ihn aus und gib den folgenden Chat-Prompt ein:",[161,1526,1530],{"className":1527,"code":1528,"language":1529,"meta":166,"style":166},"language-markdown shiki shiki-themes github-light","/refactor into C++14 and explain the changes\n","markdown",[168,1531,1532],{"__ignoreMap":166},[171,1533,1534],{"class":173,"line":174},[171,1535,1528],{"class":188},[12,1537,1538],{},"Potentielle Antwort des Chats:",[161,1540,1542],{"className":1527,"code":1541,"language":1529,"meta":166,"style":166},"…\n\nExplanations of the changes:\n\n1. Default constructor: Changed `ConfigParser() {}` to `ConfigParser() = default;` to use the default constructor.\n2. File opening: Removed `.c_str()` when opening the file, as C++11 and later support `std::string` directly.\n3. Lambda functions: Introduced a lambda function trim to handle string trimming, making the code more readable and reusable.\n4. Auto keyword: Used `auto` for type deduction in various places, improving code readability.\n5. Range-based for loops: In the `printConfig` method, replaced traditional for loops with range-based for loops, which are more concise and less error-prone.\n6. Structured bindings: Used structured bindings in the range-based for loops to directly access key-value pairs.\n7. If statements with initializers: In the `getValue` method, used if statements with initializers to combine the find operation and the check in a single line.\n8. String member functions: Used `front()` and `back()` instead of array-style access for the first and last characters of strings.\n9. Uniform initialization: Used uniform initialization `{}` instead of parentheses `()` for object creation.\n10. Removed `std::endl`: Replaced `std::endl` with `'\\n'` for better performance, as `std::endl` forces a flush of the output buffer.\n\nThese changes make the code more modern, concise, and potentially more efficient while maintaining the same functionality.\n\n",[168,1543,1544,1549,1553,1558,1562,1582,1602,1610,1624,1638,1646,1660,1680,1700,1730,1734],{"__ignoreMap":166},[171,1545,1546],{"class":173,"line":174},[171,1547,1548],{"class":188},"…\n",[171,1550,1551],{"class":173,"line":181},[171,1552,227],{"emptyLinePlaceholder":226},[171,1554,1555],{"class":173,"line":199},[171,1556,1557],{"class":188},"Explanations of the changes:\n",[171,1559,1560],{"class":173,"line":211},[171,1561,227],{"emptyLinePlaceholder":226},[171,1563,1564,1567,1570,1573,1576,1579],{"class":173,"line":223},[171,1565,1566],{"class":271},"1.",[171,1568,1569],{"class":188}," Default constructor: Changed ",[171,1571,1572],{"class":192},"`ConfigParser() {}`",[171,1574,1575],{"class":188}," to ",[171,1577,1578],{"class":192},"`ConfigParser() = default;`",[171,1580,1581],{"class":188}," to use the default constructor.\n",[171,1583,1584,1587,1590,1593,1596,1599],{"class":173,"line":230},[171,1585,1586],{"class":271},"2.",[171,1588,1589],{"class":188}," File opening: Removed ",[171,1591,1592],{"class":192},"`.c_str()`",[171,1594,1595],{"class":188}," when opening the file, as C++11 and later support ",[171,1597,1598],{"class":192},"`std::string`",[171,1600,1601],{"class":188}," directly.\n",[171,1603,1604,1607],{"class":173,"line":246},[171,1605,1606],{"class":271},"3.",[171,1608,1609],{"class":188}," Lambda functions: Introduced a lambda function trim to handle string trimming, making the code more readable and reusable.\n",[171,1611,1612,1615,1618,1621],{"class":173,"line":255},[171,1613,1614],{"class":271},"4.",[171,1616,1617],{"class":188}," Auto keyword: Used ",[171,1619,1620],{"class":192},"`auto`",[171,1622,1623],{"class":188}," for type deduction in various places, improving code readability.\n",[171,1625,1626,1629,1632,1635],{"class":173,"line":260},[171,1627,1628],{"class":271},"5.",[171,1630,1631],{"class":188}," Range-based for loops: In the ",[171,1633,1634],{"class":192},"`printConfig`",[171,1636,1637],{"class":188}," method, replaced traditional for loops with range-based for loops, which are more concise and less error-prone.\n",[171,1639,1640,1643],{"class":173,"line":284},[171,1641,1642],{"class":271},"6.",[171,1644,1645],{"class":188}," Structured bindings: Used structured bindings in the range-based for loops to directly access key-value pairs.\n",[171,1647,1648,1651,1654,1657],{"class":173,"line":305},[171,1649,1650],{"class":271},"7.",[171,1652,1653],{"class":188}," If statements with initializers: In the ",[171,1655,1656],{"class":192},"`getValue`",[171,1658,1659],{"class":188}," method, used if statements with initializers to combine the find operation and the check in a single line.\n",[171,1661,1662,1665,1668,1671,1674,1677],{"class":173,"line":326},[171,1663,1664],{"class":271},"8.",[171,1666,1667],{"class":188}," String member functions: Used ",[171,1669,1670],{"class":192},"`front()`",[171,1672,1673],{"class":188}," and ",[171,1675,1676],{"class":192},"`back()`",[171,1678,1679],{"class":188}," instead of array-style access for the first and last characters of strings.\n",[171,1681,1682,1685,1688,1691,1694,1697],{"class":173,"line":338},[171,1683,1684],{"class":271},"9.",[171,1686,1687],{"class":188}," Uniform initialization: Used uniform initialization ",[171,1689,1690],{"class":192},"`{}`",[171,1692,1693],{"class":188}," instead of parentheses ",[171,1695,1696],{"class":192},"`()`",[171,1698,1699],{"class":188}," for object creation.\n",[171,1701,1702,1705,1708,1711,1714,1716,1719,1722,1725,1727],{"class":173,"line":344},[171,1703,1704],{"class":271},"10.",[171,1706,1707],{"class":188}," Removed ",[171,1709,1710],{"class":192},"`std::endl`",[171,1712,1713],{"class":188},": Replaced ",[171,1715,1710],{"class":192},[171,1717,1718],{"class":188}," with ",[171,1720,1721],{"class":192},"`'\\n'`",[171,1723,1724],{"class":188}," for better performance, as ",[171,1726,1710],{"class":192},[171,1728,1729],{"class":188}," forces a flush of the output buffer.\n",[171,1731,1732],{"class":173,"line":350},[171,1733,227],{"emptyLinePlaceholder":226},[171,1735,1736],{"class":173,"line":355},[171,1737,1738],{"class":188},"These changes make the code more modern, concise, and potentially more efficient while maintaining the same functionality.\n",[12,1740,1741],{},[952,1742],{"alt":1743,"src":1744},"Änderungen im Code","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749675059/Blog/Content%20Images/duo_refactor_cpp_clion_chat_cpp03_to_14_01.png",[12,1746,1747],{},[952,1748],{"alt":1749,"src":1750},"Änderungen im Code 2","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749675060/Blog/Content%20Images/duo_refactor_cpp_clion_chat_cpp03_to_14_02.png",[1752,1753,82],"h4",{"id":1754},"downgrade-c23-zu-c11-refaktorisieren",[12,1756,1757],{},"Manchmal starten Entwickler(innen) einen neuen Proof of Concept in einem modernen C++-Standard wie C++20. Die aktuell unterstützten Versionen für Geschäftskundenumgebungen erfordern ältere Compiler mit C++11-Unterstützung. Ein Downgrade der Versionen ist mit Kosten verbunden und erfordert eine Bewertung, welche Sprachfunktionen noch unterstützt werden und welche anderen Nachteile auftreten könnten.",[12,1759,1760,1761,1524],{},"Öffne den ",[16,1762,1765],{"href":1763,"rel":1764},"https://gitlab.com/gitlab-da/use-cases/ai/ai-workflows/gitlab-duo-challenges/code-challenges/challenge-refactor-cpp-standards-config-parser/-/blob/main/23.cpp?ref_type=heads",[],"23.cpp",[161,1767,1769],{"className":1527,"code":1768,"language":1529,"meta":166,"style":166},"/refactor into C++11, explain the necessary changes and potential problems\n",[168,1770,1771],{"__ignoreMap":166},[171,1772,1773],{"class":173,"line":174},[171,1774,1768],{"class":188},[12,1776,1777],{},"Potenzielle Antwort des Duo Chat:",[161,1779,1781],{"className":1527,"code":1780,"language":1529,"meta":166,"style":166},"The main changes required to make this code compatible with C++11 are:\n\n1. Remove the C++23 standard comment, as it's no longer applicable.\n2. Replace `std::string::find_first_not_of` and `std::string::find_last_not_of` with C++11 compatible alternatives in the trim function.\n3. Use `const auto&` instead of `auto` for loop variables to avoid unnecessary copying.\n\nPotential problems in the original code:\n\n1. The original code used C++23 features, which might not be widely supported yet.\n2. The `trim` function used `std::string::find_first_not_of` and `std::string::find_last_not_of`, which are not available in C++11.\n3. The use of `auto` instead of `const auto&` in some loops could lead to unnecessary copying of complex objects.\n\nThese issues have been addressed in the refactored version. The `trim` function now uses `std::find_if_not` with lambda functions to achieve the same result in a C++11 compatible way. The use of `const auto&` ensures that no unnecessary copying occurs when iterating over the config map.\n",[168,1782,1783,1788,1792,1799,1817,1835,1839,1844,1848,1855,1877,1893,1897],{"__ignoreMap":166},[171,1784,1785],{"class":173,"line":174},[171,1786,1787],{"class":188},"The main changes required to make this code compatible with C++11 are:\n",[171,1789,1790],{"class":173,"line":181},[171,1791,227],{"emptyLinePlaceholder":226},[171,1793,1794,1796],{"class":173,"line":199},[171,1795,1566],{"class":271},[171,1797,1798],{"class":188}," Remove the C++23 standard comment, as it's no longer applicable.\n",[171,1800,1801,1803,1806,1809,1811,1814],{"class":173,"line":211},[171,1802,1586],{"class":271},[171,1804,1805],{"class":188}," Replace ",[171,1807,1808],{"class":192},"`std::string::find_first_not_of`",[171,1810,1673],{"class":188},[171,1812,1813],{"class":192},"`std::string::find_last_not_of`",[171,1815,1816],{"class":188}," with C++11 compatible alternatives in the trim function.\n",[171,1818,1819,1821,1824,1827,1830,1832],{"class":173,"line":223},[171,1820,1606],{"class":271},[171,1822,1823],{"class":188}," Use ",[171,1825,1826],{"class":192},"`const auto&`",[171,1828,1829],{"class":188}," instead of ",[171,1831,1620],{"class":192},[171,1833,1834],{"class":188}," for loop variables to avoid unnecessary copying.\n",[171,1836,1837],{"class":173,"line":230},[171,1838,227],{"emptyLinePlaceholder":226},[171,1840,1841],{"class":173,"line":246},[171,1842,1843],{"class":188},"Potential problems in the original code:\n",[171,1845,1846],{"class":173,"line":255},[171,1847,227],{"emptyLinePlaceholder":226},[171,1849,1850,1852],{"class":173,"line":260},[171,1851,1566],{"class":271},[171,1853,1854],{"class":188}," The original code used C++23 features, which might not be widely supported yet.\n",[171,1856,1857,1859,1862,1865,1868,1870,1872,1874],{"class":173,"line":284},[171,1858,1586],{"class":271},[171,1860,1861],{"class":188}," The ",[171,1863,1864],{"class":192},"`trim`",[171,1866,1867],{"class":188}," function used ",[171,1869,1808],{"class":192},[171,1871,1673],{"class":188},[171,1873,1813],{"class":192},[171,1875,1876],{"class":188},", which are not available in C++11.\n",[171,1878,1879,1881,1884,1886,1888,1890],{"class":173,"line":305},[171,1880,1606],{"class":271},[171,1882,1883],{"class":188}," The use of ",[171,1885,1620],{"class":192},[171,1887,1829],{"class":188},[171,1889,1826],{"class":192},[171,1891,1892],{"class":188}," in some loops could lead to unnecessary copying of complex objects.\n",[171,1894,1895],{"class":173,"line":326},[171,1896,227],{"emptyLinePlaceholder":226},[171,1898,1899,1902,1904,1907,1910,1913,1915],{"class":173,"line":338},[171,1900,1901],{"class":188},"These issues have been addressed in the refactored version. The ",[171,1903,1864],{"class":192},[171,1905,1906],{"class":188}," function now uses ",[171,1908,1909],{"class":192},"`std::find_if_not`",[171,1911,1912],{"class":188}," with lambda functions to achieve the same result in a C++11 compatible way. The use of ",[171,1914,1826],{"class":192},[171,1916,1917],{"class":188}," ensures that no unnecessary copying occurs when iterating over the config map.\n",[12,1919,1920],{},[952,1921],{"alt":1922,"src":1923},"The trim function now uses std::find_if_not with lambda functions to achieve the same result in a C++11 compatible way","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749675059/Blog/Content%20Images/duo_refactor_cpp_clion_chat_cpp23_to_11_01.png",[12,1925,1926],{},[952,1927],{"alt":1928,"src":1929},"The use of const auto& ensures that no unnecessary copying occurs when iterating over the config map","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749675059/Blog/Content%20Images/duo_refactor_cpp_clion_chat_cpp23_to_11_02.png",[12,1931,1932,1936],{},[1933,1934,1935],"strong",{},"Asynchronisierungsübung",": Teste weitere Refactoring-Szenarios.",[150,1938,1940],{"id":1939},"cobol-erklären-und-umgestalten","COBOL erklären und umgestalten",[12,1942,1943,1944,1949],{},"Du kannst GitLab Duo verwenden, um den Quellcode zu erklären, zu analysieren, zu reparieren und für COBOL-Programme zu refaktorisieren. Ich habe COBOL nie geschrieben oder gelernt und fand diesen ",[16,1945,1948],{"href":1946,"rel":1947},"https://github.com/openmainframeproject/cobol-programming-course",[],"COBOL-Programmierkurs"," mit vielen Beispielen hilfreich.",[12,1951,1952],{},"Ich habe dann den Chat gefragt, wie man mit COBOL beginnt, ein COBOL-Programm erstellt und ein COBOL-Programm auf macOS kompiliert.",[161,1954,1956],{"className":1527,"code":1955,"language":1529,"meta":166,"style":166},"Please explain what COBOL is and its syntax\n\nPlease create a COBOL program that shows the first steps\n\nTell me more about the COBOL compiler. Which system do I need? Can I do it on my macOS?\n\n",[168,1957,1958,1963,1967,1972,1976],{"__ignoreMap":166},[171,1959,1960],{"class":173,"line":174},[171,1961,1962],{"class":188},"Please explain what COBOL is and its syntax\n",[171,1964,1965],{"class":173,"line":181},[171,1966,227],{"emptyLinePlaceholder":226},[171,1968,1969],{"class":173,"line":199},[171,1970,1971],{"class":188},"Please create a COBOL program that shows the first steps\n",[171,1973,1974],{"class":173,"line":211},[171,1975,227],{"emptyLinePlaceholder":226},[171,1977,1978],{"class":173,"line":223},[171,1979,1980],{"class":188},"Tell me more about the COBOL compiler. Which system do I need? Can I do it on my macOS?\n",[12,1982,1983],{},[952,1984],{"alt":1985,"src":1986},"Bitte an GitLab Duo Chat, die Sprache und ihre Syntax zu erklären","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749675059/Blog/Content%20Images/vscode_chat_cobol_generate_example.png",[12,1988,1989,1990,1992],{},"Öffne ein COBOL-Programm, wähle den Quellcode aus, gehe zum Duo Chat und sende den Prompt ",[168,1991,947],{},", um Zweck und Funktion des Codes zu erklären.\nDu kannst die Prompts auch verfeinern, um allgemeinere Zusammenfassungen zu erhalten, zum Beispiel:",[161,1994,1996],{"className":1527,"code":1995,"language":1529,"meta":166,"style":166},"/explain like I am five\n",[168,1997,1998],{"__ignoreMap":166},[171,1999,2000],{"class":173,"line":174},[171,2001,1995],{"class":188},[2003,2004,2005],"blockquote",{},[12,2006,2007],{},"Tipp: Programmiersprachen haben ähnliche Algorithmen und Funktionen. Für COBOL bot der Chat an, es mit Python zu erklären. Deshalb habe ich die folgenden Prompts angepasst, um in Python nach einer Erklärung zu fragen.",[161,2009,2011],{"className":1527,"code":2010,"language":1529,"meta":166,"style":166},"/explain in a different programming language\n",[168,2012,2013],{"__ignoreMap":166},[171,2014,2015],{"class":173,"line":174},[171,2016,2010],{"class":188},[12,2018,2019,2020,2023],{},"Du kannst auch den Slash-Befehl ",[168,2021,2022],{},"/refactor"," im Chat verwenden, um die Codequalität zu verbessern, potenzielle Probleme zu beheben und zu versuchen, COBOL in Python zu refaktorisieren.",[161,2025,2027],{"className":1527,"code":2026,"language":1529,"meta":166,"style":166},"/refactor fix the environment error\n\n/refactor fix potential problems\n\n/refactor into Python\n",[168,2028,2029,2034,2038,2043,2047],{"__ignoreMap":166},[171,2030,2031],{"class":173,"line":174},[171,2032,2033],{"class":188},"/refactor fix the environment error\n",[171,2035,2036],{"class":173,"line":181},[171,2037,227],{"emptyLinePlaceholder":226},[171,2039,2040],{"class":173,"line":199},[171,2041,2042],{"class":188},"/refactor fix potential problems\n",[171,2044,2045],{"class":173,"line":211},[171,2046,227],{"emptyLinePlaceholder":226},[171,2048,2049],{"class":173,"line":223},[171,2050,2051],{"class":188},"/refactor into Python\n",[12,2053,2054,2055,2060],{},"Die Aufzeichnung ",[16,2056,2059],{"href":2057,"rel":2058},"https://gitlab.com/gitlab-da/use-cases/ai/ai-workflows/gitlab-duo-challenges/code-challenges/challenge-explain-refactor-cobol-program",[],"GitLab Duo Coffee Chat – Herausforderung: COBOL-Programme erklären und refaktorisieren"," zeigt die Schritte, die ich oben erklärt habe, anhand eines praktischen Beispiels. Hier siehst du auch, wie man einen fehlenden Punkt finden kann:",[983,2062,987,2064],{"className":2063},[986],[989,2065,994],{"src":2066,"frameBorder":992,"allowFullScreen":993},"https://www.youtube.com/embed/pwlDmLQMMPo",[142,2068,2070],{"id":2069},"eine-sprache-in-eine-andere-sprache-refaktorisieren","Eine Sprache in eine andere Sprache refaktorisieren",[12,2072,2073],{},"Modernisierung und Verbesserungen der Codequalität erfordern manchmal den Wechsel einer Programmiersprache. Ähnliche Refactoring-Prompts mit GitLab Duo können den Migrationsprozess beschleunigen. Das COBOL-Beispiel mit Python ist nur eine von vielen Anforderungen in Unternehmensumgebungen. Sehen wir uns nun weitere Anwendungsfälle an.",[150,2075,2077],{"id":2076},"c-in-rust-refaktorisieren","C in Rust refaktorisieren",[12,2079,2080,2081,2086],{},"Anfang 2024 wurden mehrere Programmiersprachen, darunter C, als nicht speichersicher bezeichnet. Die Empfehlungen für zukünftige Projekte umfassen ",[16,2082,2085],{"href":2083,"rel":2084},"https://about.gitlab.com/blog/memory-safe-vs-unsafe/",[],"speichersichere Sprachen"," wie Rust. Aber wie startet man eine Migration und welche Herausforderungen gibt es dabei?",[12,2088,2089],{},"Versuchen wir es mit einem einfachen Beispiel in C. Der Code wurde mithilfe von Codevorschlägen generiert und sollte die grundlegenden Betriebssysteminformationen wie Name, Version und Plattform ausdrucken. Der C-Code kompiliert plattformübergreifend unter Windows, Linux und macOS.",[161,2091,2095],{"className":2092,"code":2093,"language":2094,"meta":166,"style":166},"language-c shiki shiki-themes github-light","// Read OS files to identify the platform, name, versions\n// Print them on the terminal\n#include \u003Cstdio.h>\n#include \u003Cstdlib.h>\n#include \u003Cstring.h>\n\n#ifdef _WIN32\n    #include \u003Cwindows.h>\n#elif __APPLE__\n    #include \u003Csys/utsname.h>\n#else\n    #include \u003Csys/utsname.h>\n#endif\n\nvoid get_os_info() {\n    #ifdef _WIN32\n        OSVERSIONINFOEX info;\n        ZeroMemory(&info, sizeof(OSVERSIONINFOEX));\n        info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);\n        GetVersionEx((OSVERSIONINFO*)&info);\n\n        printf(\"Platform: Windows\\n\");\n        printf(\"Version: %d.%d\\n\", info.dwMajorVersion, info.dwMinorVersion);\n        printf(\"Build: %d\\n\", info.dwBuildNumber);\n    #elif __APPLE__\n        struct utsname sys_info;\n        uname(&sys_info);\n\n        printf(\"Platform: macOS\\n\");\n        printf(\"Name: %s\\n\", sys_info.sysname);\n        printf(\"Version: %s\\n\", sys_info.release);\n    #else\n        struct utsname sys_info;\n        uname(&sys_info);\n\n        printf(\"Platform: %s\\n\", sys_info.sysname);\n        printf(\"Name: %s\\n\", sys_info.nodename);\n        printf(\"Version: %s\\n\", sys_info.release);\n    #endif\n}\n\nint main() {\n    get_os_info();\n    return 0;\n}\n","c",[168,2096,2097,2102,2107,2116,2123,2130,2134,2142,2150,2158,2165,2170,2176,2181,2185,2196,2203,2208,2228,2241,2259,2263,2282,2304,2320,2327,2335,2347,2351,2366,2383,2398,2403,2409,2419,2423,2438,2453,2467,2472,2476,2480,2490,2498,2508],{"__ignoreMap":166},[171,2098,2099],{"class":173,"line":174},[171,2100,2101],{"class":177},"// Read OS files to identify the platform, name, versions\n",[171,2103,2104],{"class":173,"line":181},[171,2105,2106],{"class":177},"// Print them on the terminal\n",[171,2108,2109,2112],{"class":173,"line":199},[171,2110,2111],{"class":184},"#include",[171,2113,2115],{"class":2114},"sYBdl"," \u003Cstdio.h>\n",[171,2117,2118,2120],{"class":173,"line":211},[171,2119,2111],{"class":184},[171,2121,2122],{"class":2114}," \u003Cstdlib.h>\n",[171,2124,2125,2127],{"class":173,"line":223},[171,2126,2111],{"class":184},[171,2128,2129],{"class":2114}," \u003Cstring.h>\n",[171,2131,2132],{"class":173,"line":230},[171,2133,227],{"emptyLinePlaceholder":226},[171,2135,2136,2139],{"class":173,"line":246},[171,2137,2138],{"class":184},"#ifdef",[171,2140,2141],{"class":239}," _WIN32\n",[171,2143,2144,2147],{"class":173,"line":255},[171,2145,2146],{"class":184},"    #include",[171,2148,2149],{"class":2114}," \u003Cwindows.h>\n",[171,2151,2152,2155],{"class":173,"line":260},[171,2153,2154],{"class":184},"#elif",[171,2156,2157],{"class":239}," __APPLE__\n",[171,2159,2160,2162],{"class":173,"line":284},[171,2161,2146],{"class":184},[171,2163,2164],{"class":2114}," \u003Csys/utsname.h>\n",[171,2166,2167],{"class":173,"line":305},[171,2168,2169],{"class":184},"#else\n",[171,2171,2172,2174],{"class":173,"line":326},[171,2173,2146],{"class":184},[171,2175,2164],{"class":2114},[171,2177,2178],{"class":173,"line":338},[171,2179,2180],{"class":184},"#endif\n",[171,2182,2183],{"class":173,"line":344},[171,2184,227],{"emptyLinePlaceholder":226},[171,2186,2187,2190,2193],{"class":173,"line":350},[171,2188,2189],{"class":184},"void",[171,2191,2192],{"class":239}," get_os_info",[171,2194,2195],{"class":188},"() {\n",[171,2197,2198,2201],{"class":173,"line":355},[171,2199,2200],{"class":184},"    #ifdef",[171,2202,2141],{"class":239},[171,2204,2205],{"class":173,"line":383},[171,2206,2207],{"class":188},"        OSVERSIONINFOEX info;\n",[171,2209,2210,2213,2216,2219,2222,2225],{"class":173,"line":400},[171,2211,2212],{"class":239},"        ZeroMemory",[171,2214,2215],{"class":188},"(",[171,2217,2218],{"class":184},"&",[171,2220,2221],{"class":188},"info, ",[171,2223,2224],{"class":184},"sizeof",[171,2226,2227],{"class":188},"(OSVERSIONINFOEX));\n",[171,2229,2230,2233,2235,2238],{"class":173,"line":418},[171,2231,2232],{"class":188},"        info.dwOSVersionInfoSize ",[171,2234,293],{"class":184},[171,2236,2237],{"class":184}," sizeof",[171,2239,2240],{"class":188},"(OSVERSIONINFOEX);\n",[171,2242,2243,2246,2249,2251,2254,2256],{"class":173,"line":423},[171,2244,2245],{"class":239},"        GetVersionEx",[171,2247,2248],{"class":188},"((OSVERSIONINFO",[171,2250,193],{"class":184},[171,2252,2253],{"class":188},")",[171,2255,2218],{"class":184},[171,2257,2258],{"class":188},"info);\n",[171,2260,2261],{"class":173,"line":428},[171,2262,227],{"emptyLinePlaceholder":226},[171,2264,2265,2268,2270,2273,2276,2279],{"class":173,"line":449},[171,2266,2267],{"class":239},"        printf",[171,2269,2215],{"class":188},[171,2271,2272],{"class":2114},"\"Platform: Windows",[171,2274,2275],{"class":192},"\\n",[171,2277,2278],{"class":2114},"\"",[171,2280,2281],{"class":188},");\n",[171,2283,2284,2286,2288,2291,2294,2296,2299,2301],{"class":173,"line":462},[171,2285,2267],{"class":239},[171,2287,2215],{"class":188},[171,2289,2290],{"class":2114},"\"Version: ",[171,2292,2293],{"class":192},"%d",[171,2295,975],{"class":2114},[171,2297,2298],{"class":192},"%d\\n",[171,2300,2278],{"class":2114},[171,2302,2303],{"class":188},", info.dwMajorVersion, info.dwMinorVersion);\n",[171,2305,2306,2308,2310,2313,2315,2317],{"class":173,"line":483},[171,2307,2267],{"class":239},[171,2309,2215],{"class":188},[171,2311,2312],{"class":2114},"\"Build: ",[171,2314,2298],{"class":192},[171,2316,2278],{"class":2114},[171,2318,2319],{"class":188},", info.dwBuildNumber);\n",[171,2321,2322,2325],{"class":173,"line":488},[171,2323,2324],{"class":184},"    #elif",[171,2326,2157],{"class":239},[171,2328,2329,2332],{"class":173,"line":493},[171,2330,2331],{"class":184},"        struct",[171,2333,2334],{"class":188}," utsname sys_info;\n",[171,2336,2337,2340,2342,2344],{"class":173,"line":513},[171,2338,2339],{"class":239},"        uname",[171,2341,2215],{"class":188},[171,2343,2218],{"class":184},[171,2345,2346],{"class":188},"sys_info);\n",[171,2348,2349],{"class":173,"line":526},[171,2350,227],{"emptyLinePlaceholder":226},[171,2352,2353,2355,2357,2360,2362,2364],{"class":173,"line":537},[171,2354,2267],{"class":239},[171,2356,2215],{"class":188},[171,2358,2359],{"class":2114},"\"Platform: macOS",[171,2361,2275],{"class":192},[171,2363,2278],{"class":2114},[171,2365,2281],{"class":188},[171,2367,2368,2370,2372,2375,2378,2380],{"class":173,"line":542},[171,2369,2267],{"class":239},[171,2371,2215],{"class":188},[171,2373,2374],{"class":2114},"\"Name: ",[171,2376,2377],{"class":192},"%s\\n",[171,2379,2278],{"class":2114},[171,2381,2382],{"class":188},", sys_info.sysname);\n",[171,2384,2385,2387,2389,2391,2393,2395],{"class":173,"line":547},[171,2386,2267],{"class":239},[171,2388,2215],{"class":188},[171,2390,2290],{"class":2114},[171,2392,2377],{"class":192},[171,2394,2278],{"class":2114},[171,2396,2397],{"class":188},", sys_info.release);\n",[171,2399,2400],{"class":173,"line":571},[171,2401,2402],{"class":184},"    #else\n",[171,2404,2405,2407],{"class":173,"line":589},[171,2406,2331],{"class":184},[171,2408,2334],{"class":188},[171,2410,2411,2413,2415,2417],{"class":173,"line":614},[171,2412,2339],{"class":239},[171,2414,2215],{"class":188},[171,2416,2218],{"class":184},[171,2418,2346],{"class":188},[171,2420,2421],{"class":173,"line":629},[171,2422,227],{"emptyLinePlaceholder":226},[171,2424,2425,2427,2429,2432,2434,2436],{"class":173,"line":653},[171,2426,2267],{"class":239},[171,2428,2215],{"class":188},[171,2430,2431],{"class":2114},"\"Platform: ",[171,2433,2377],{"class":192},[171,2435,2278],{"class":2114},[171,2437,2382],{"class":188},[171,2439,2440,2442,2444,2446,2448,2450],{"class":173,"line":659},[171,2441,2267],{"class":239},[171,2443,2215],{"class":188},[171,2445,2374],{"class":2114},[171,2447,2377],{"class":192},[171,2449,2278],{"class":2114},[171,2451,2452],{"class":188},", sys_info.nodename);\n",[171,2454,2455,2457,2459,2461,2463,2465],{"class":173,"line":664},[171,2456,2267],{"class":239},[171,2458,2215],{"class":188},[171,2460,2290],{"class":2114},[171,2462,2377],{"class":192},[171,2464,2278],{"class":2114},[171,2466,2397],{"class":188},[171,2468,2469],{"class":173,"line":672},[171,2470,2471],{"class":184},"    #endif\n",[171,2473,2474],{"class":173,"line":677},[171,2475,935],{"class":188},[171,2477,2478],{"class":173,"line":682},[171,2479,227],{"emptyLinePlaceholder":226},[171,2481,2482,2485,2488],{"class":173,"line":708},[171,2483,2484],{"class":184},"int",[171,2486,2487],{"class":239}," main",[171,2489,2195],{"class":188},[171,2491,2492,2495],{"class":173,"line":723},[171,2493,2494],{"class":239},"    get_os_info",[171,2496,2497],{"class":188},"();\n",[171,2499,2500,2503,2506],{"class":173,"line":738},[171,2501,2502],{"class":184},"    return",[171,2504,2505],{"class":192}," 0",[171,2507,196],{"class":188},[171,2509,2510],{"class":173,"line":749},[171,2511,935],{"class":188},[12,2513,2514,2515,2522,2523,2525,2526,2528,2529,2532,2533,2536,2537,2540],{},"Öffne den Quellcode in ",[16,2516,2519],{"href":2517,"rel":2518},"https://gitlab.com/gitlab-da/use-cases/ai/ai-workflows/gitlab-duo-challenges/code-challenges/challenge-refactor-c-to-rust/-/blob/897bf57a14bb7be07d842e7f044f93a61456d611/c/os.c",[],[168,2520,2521],{},"os.c",", beispielsweise in JetBrains CLion. Wähle den Quellcode aus und gib den Chat-Prompt ",[168,2524,947],{}," ein, um Zweck und Funktion erklären zu lassen. Gib als Nächstes ",[168,2527,2022],{}," in den Chat ein, um den C-Code zu refaktorisieren, und gehe dann einen Schritt weiter: ",[168,2530,2531],{},"/refactor into Rust",".\nInitialisiere ein neues Rust-Projekt (Tipp: Frage den Duo Chat) und kopiere den generierten Quellcode in die Datei ",[168,2534,2535],{},"src/main.rs",". Führe ",[168,2538,2539],{},"cargo build"," aus, um den Code zu kompilieren.",[12,2542,2543],{},[952,2544],{"alt":2545,"src":2546},"Initialisiere ein neues Rust-Projekt und kopiere den generierten Quellcode in die Datei src/main.rs. Führe cargo build aus, um den Code zu kompilieren.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749675059/Blog/Content%20Images/jetbrains_clion_c_rust.png",[12,2548,2549,2550,2555,2556,2558],{},"In der Aufzeichnung von ",[16,2551,2554],{"href":2552,"rel":2553},"https://gitlab.com/gitlab-da/use-cases/ai/ai-workflows/gitlab-duo-challenges/code-challenges/challenge-refactor-c-to-rust",[],"GitLab Duo Coffee Chat: Herausforderung – C zu Rust refaktorisieren"," lernst du alle Schritte kennen und siehst außerdem einen Kompilierungsfehler, der mithilfe des Chats und des Slash-Vefehls ",[168,2557,2022],{}," behoben wird. Die Aufzeichnung zeigt auch, wie man die Wartbarkeit des neuen Rust-Codes verbessern kann, indem man mehr Fehlerbehandlung hinzufügt.",[983,2560,987,2562],{"className":2561},[986],[989,2563,994],{"src":2564,"frameBorder":992,"allowFullScreen":993},"https://www.youtube.com/embed/nf8g2ucqvkI",[150,2566,108],{"id":2567},"perl-zu-python-refaktorisieren",[12,2569,2570],{},"Dieses eine Skript, das auf Produktionsservern läuft, seinen Job macht und dessen Autor(in) schon seit zehn Jahren nicht mehr im Unternehmen arbeitet – und das niemand anfassen will. Dieses Problem kann es auch für mehrere Skripte oder sogar für eine ganze Anwendung geben. Dann wird beschlossen, alles auf das moderne Python 3 zu migrieren, mit dem Ziel, den Code zu modernisieren und die Veränderungen zwischen Perl und Python zu verstehen.",[12,2572,2573],{},"Ein(e) Kund(in) hat kürzlich in einem GitLab-Duo-Workshop gefragt, ob eine direkte Migration mit GitLab Duo möglich ist. Die kurze Antwort: Ja, das ist es. Die längere Antwort: Du kannst mithilfe verfeinerter Chat-Prompts Perl-Code in Python refaktorisieren, ähnlich wie bei anderen Beispielen in diesem Artikel.",[12,2575,2576,2577,2580],{},"Öffne den Quellcode ",[168,2578,2579],{},"script.pl"," in der IDE, wähle ihn aus und öffne den Chat.",[161,2582,2586],{"className":2583,"code":2584,"language":2585,"meta":166,"style":166},"language-perl shiki shiki-themes github-light","#!/usr/bin/perl\nuse strict;\nuse warnings;\n\nopen my $md_fh, '\u003C', 'file.md' or die \"Could not open file.md: $!\";\n\nmy $l = 0;\nmy $e = 0;\nmy $h = 0;\n\nwhile (my $line = \u003C$md_fh>) {\n  $l++;\n  if ($line =~ /^\\s*$/) {\n    $e++;\n    next;\n  }\n  if ($line =~ /^#+\\s*(.+)/) {\n    print \"$1\\n\";\n    $h++;   }\n}\n\nprint \"\\nS:\\n\"; print \"L: $l\\n\";\nprint \"E: $e\\n\"; print \"H: $h\\n\";\n","perl",[168,2587,2588,2593,2601,2608,2612,2647,2651,2659,2666,2673,2677,2689,2694,2719,2724,2731,2736,2752,2769,2774,2778,2782,2815],{"__ignoreMap":166},[171,2589,2590],{"class":173,"line":174},[171,2591,2592],{"class":177},"#!/usr/bin/perl\n",[171,2594,2595,2598],{"class":173,"line":181},[171,2596,2597],{"class":184},"use",[171,2599,2600],{"class":188}," strict;\n",[171,2602,2603,2605],{"class":173,"line":199},[171,2604,2597],{"class":184},[171,2606,2607],{"class":188}," warnings;\n",[171,2609,2610],{"class":173,"line":211},[171,2611,227],{"emptyLinePlaceholder":226},[171,2613,2614,2617,2620,2623,2626,2628,2631,2634,2637,2640,2643,2645],{"class":173,"line":223},[171,2615,2616],{"class":192},"open",[171,2618,2619],{"class":184}," my",[171,2621,2622],{"class":188}," $md_fh, ",[171,2624,2625],{"class":2114},"'\u003C'",[171,2627,1467],{"class":188},[171,2629,2630],{"class":2114},"'file.md'",[171,2632,2633],{"class":184}," or",[171,2635,2636],{"class":184}," die",[171,2638,2639],{"class":2114}," \"Could not open file.md: ",[171,2641,2642],{"class":188},"$!",[171,2644,2278],{"class":2114},[171,2646,196],{"class":188},[171,2648,2649],{"class":173,"line":230},[171,2650,227],{"emptyLinePlaceholder":226},[171,2652,2653,2656],{"class":173,"line":246},[171,2654,2655],{"class":184},"my",[171,2657,2658],{"class":188}," $l = 0;\n",[171,2660,2661,2663],{"class":173,"line":255},[171,2662,2655],{"class":184},[171,2664,2665],{"class":188}," $e = 0;\n",[171,2667,2668,2670],{"class":173,"line":260},[171,2669,2655],{"class":184},[171,2671,2672],{"class":188}," $h = 0;\n",[171,2674,2675],{"class":173,"line":284},[171,2676,227],{"emptyLinePlaceholder":226},[171,2678,2679,2682,2684,2686],{"class":173,"line":305},[171,2680,2681],{"class":184},"while",[171,2683,311],{"class":188},[171,2685,2655],{"class":184},[171,2687,2688],{"class":188}," $line = \u003C$md_fh>) {\n",[171,2690,2691],{"class":173,"line":326},[171,2692,2693],{"class":188},"  $l++;\n",[171,2695,2696,2699,2702,2705,2709,2711,2714,2717],{"class":173,"line":338},[171,2697,2698],{"class":184},"  if",[171,2700,2701],{"class":188}," ($line =~ ",[171,2703,2704],{"class":2114},"/^",[171,2706,2708],{"class":2707},"s691h","\\s",[171,2710,193],{"class":2114},[171,2712,2713],{"class":184},"$",[171,2715,2716],{"class":2114},"/",[171,2718,900],{"class":188},[171,2720,2721],{"class":173,"line":344},[171,2722,2723],{"class":188},"    $e++;\n",[171,2725,2726,2729],{"class":173,"line":350},[171,2727,2728],{"class":184},"    next",[171,2730,196],{"class":188},[171,2732,2733],{"class":173,"line":355},[171,2734,2735],{"class":188},"  }\n",[171,2737,2738,2740,2742,2745,2747,2750],{"class":173,"line":383},[171,2739,2698],{"class":184},[171,2741,2701],{"class":188},[171,2743,2744],{"class":2114},"/^#+",[171,2746,2708],{"class":2707},[171,2748,2749],{"class":2114},"*(.+)/",[171,2751,900],{"class":188},[171,2753,2754,2757,2760,2763,2765,2767],{"class":173,"line":400},[171,2755,2756],{"class":192},"    print",[171,2758,2759],{"class":2114}," \"",[171,2761,2762],{"class":188},"$1",[171,2764,2275],{"class":192},[171,2766,2278],{"class":2114},[171,2768,196],{"class":188},[171,2770,2771],{"class":173,"line":418},[171,2772,2773],{"class":188},"    $h++;   }\n",[171,2775,2776],{"class":173,"line":423},[171,2777,935],{"class":188},[171,2779,2780],{"class":173,"line":428},[171,2781,227],{"emptyLinePlaceholder":226},[171,2783,2784,2787,2789,2791,2794,2796,2798,2801,2803,2806,2809,2811,2813],{"class":173,"line":449},[171,2785,2786],{"class":192},"print",[171,2788,2759],{"class":2114},[171,2790,2275],{"class":192},[171,2792,2793],{"class":2114},"S:",[171,2795,2275],{"class":192},[171,2797,2278],{"class":2114},[171,2799,2800],{"class":188},"; ",[171,2802,2786],{"class":192},[171,2804,2805],{"class":2114}," \"L: ",[171,2807,2808],{"class":188},"$l",[171,2810,2275],{"class":192},[171,2812,2278],{"class":2114},[171,2814,196],{"class":188},[171,2816,2817,2819,2822,2825,2827,2829,2831,2833,2836,2839,2841,2843],{"class":173,"line":462},[171,2818,2786],{"class":192},[171,2820,2821],{"class":2114}," \"E: ",[171,2823,2824],{"class":188},"$e",[171,2826,2275],{"class":192},[171,2828,2278],{"class":2114},[171,2830,2800],{"class":188},[171,2832,2786],{"class":192},[171,2834,2835],{"class":2114}," \"H: ",[171,2837,2838],{"class":188},"$h",[171,2840,2275],{"class":192},[171,2842,2278],{"class":2114},[171,2844,196],{"class":188},[12,2846,2847],{},"You can use the following prompts to:",[940,2849,2850,2858],{},[49,2851,2852,2854,2855,2857],{},[168,2853,947],{}," its purpose, and ",[168,2856,2022],{}," to improve the code.",[49,2859,2860,2863],{},[168,2861,2862],{},"/refactor into Python",", um ein funktionierendes Python-Skript zu erhalten.",[12,2865,2866],{},[952,2867],{"alt":2868,"src":2869},"Refaktorisierung in Python","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749675059/Blog/Content%20Images/pycharm_duo_refactor_perl_python.png",[2003,2871,2872,2881],{},[12,2873,2874,2875,2880],{},"Tipp: Du kannst Perl-Code in mehrere Zielsprachen refaktorisieren. Die Aufzeichnung von ",[16,2876,2879],{"href":2877,"rel":2878},"https://gitlab.com/gitlab-da/use-cases/ai/ai-workflows/gitlab-duo-challenges/code-challenges/challenge-refactor-perl-python",[],"GitLab Duo Coffee Chat: Herausforderung – Perl zu Python refaktorisieren"," zeigt Refaktorisierungen zu PHP, Ruby, Rust, Go, Java, VB.NET, C# und mehr.",[2003,2882,2883],{},[12,2884,2885,2886,2891],{},"Wenn du Perl-Skripts weiterhin verwenden möchtest, kannst du ",[16,2887,2890],{"href":2888,"rel":2889},"https://docs.gitlab.com/user/project/repository/code_suggestions/supported_extensions/#add-support-for-more-languages",[],"Perl als zusätzliche Sprache"," in Duo Codevorschläge konfigurieren. Der Chat versteht bereits Perl und kann bei Fragen und Slash-Befehlen helfen, wie du in der folgenden Aufnahme sehen kannst.",[983,2893,987,2895],{"className":2894},[986],[989,2896,994],{"src":2897,"frameBorder":992,"allowFullScreen":993},"https://www.youtube.com/embed/03HGhxXg9lw",[142,2899,114],{"id":2900},"weitere-tipps-zum-refaktorisieren",[150,2902,122],{"id":2903},"javascript-refaktorisieren",[12,2905,2906],{},"Eddie Jaoude zeigt in einem praktischen Beispiel, wie er JavaScript refaktorisiert, um die Codequalität zu verbessern oder Funktionen hinzuzufügen.",[983,2908,987,2910],{"className":2909},[986],[989,2911,994],{"src":2912,"frameBorder":992,"allowFullScreen":993},"https://www.youtube.com/embed/mHn8KOzpPNY",[150,2914,128],{"id":2915},"bash-zu-zsh-oder-sh-refaktorisieren",[12,2917,2918],{},"Ich benutze Bash seit 20 Jahren als Shell und bin zuletzt auf macOS auf ZSH umgestiegen. Dies führte dazu, dass das Skript nicht funktionierte oder unbekannte Fehler in meinem Terminal auftraten. Ein weiterer Anwendungsfall für das Refactoring sind Shell-Einschränkungen – einige Betriebssysteme oder Linux-/Unix-Distributionen bieten kein Bash, sondern nur SH, z. B. Alpine.",[12,2920,2921],{},[952,2922],{"alt":2923,"src":2924},"Shell-Skripte refaktorisieren","https://res.cloudinary.com/about-gitlab-com/image/upload/v1749675059/Blog/Content%20Images/intellj_refactor_shell_scripts.png",[12,2926,2927,2928,2933,2934,2936,2937,2939],{},"Der ",[16,2929,2932],{"href":2930,"rel":2931},"https://gitlab.com/gitlab-da/use-cases/ai/ai-workflows/gitlab-duo-challenges/code-challenges/challenge-refactor-shell-scripts",[],"GitLab Duo Coffee Chat: Herausforderung – Shell-Skripte refaktorisieren"," zeigt ein Beispiel mit einem C-Programm, das Syslog-Dateien bearbeiten kann, und einem in Bash geschriebenen Build-Skript. Während der gesamten Challenge wird der Chat mit den Prompts ",[168,2935,947],{}," und ",[168,2938,2022],{}," abgefragt, um den Code zu verbessern. Es ist auch möglich, Bash in POSIX-konformes SH oder ZSH zu refaktorisieren. Die Sitzung endet mit der Bitte an den Chat, fünf verschiedene Shell-Skriptimplementierungen bereitzustellen und die wichtigsten Zusammenfassungen zu erläutern.",[983,2941,987,2943],{"className":2942},[986],[989,2944,994],{"src":2945,"frameBorder":992,"allowFullScreen":993},"https://www.youtube.com/embed/mssqYjlKGzU",[150,2947,134],{"id":2948},"weitere-anwendungsfälle-und-tutorials",[46,2950,2951,2958,2965],{},[49,2952,2953],{},[16,2954,2957],{"href":2955,"rel":2956},"https://docs.gitlab.com/user/gitlab_duo/use_cases/",[],"Dokumentation: GitLab-Duo-Anwendungsfälle",[49,2959,2960],{},[16,2961,2964],{"href":2962,"rel":2963},"https://about.gitlab.com/blog/top-tips-for-efficient-ai-powered-code-suggestions-with-gitlab-duo/",[],"Tutorial: Top-Tipps für effiziente KI-basierte Codevorschläge mit GitLab Duo",[49,2966,2967],{},[16,2968,2971],{"href":2969,"rel":2970},"https://about.gitlab.com/blog/10-best-practices-for-using-ai-powered-gitlab-duo-chat/",[],"Tutorial: 10 Best Practices für den Einsatz des KI-basierten GitLab Duo Chat",[142,2973,2975],{"id":2974},"wichtigste-erkenntnisse","Wichtigste Erkenntnisse",[940,2977,2978,2981,2984,2987,2990,2993],{},[49,2979,2980],{},"GitLab Duo bietet effiziente Hilfe beim Erklären und Refaktorisieren von Code. 1. Du kannst Code zwischen den Sprachstandards refaktorisieren und im Chat weitere Fragen stellen.",[49,2982,2983],{},"Prompts für Codevorschläge können bestimmte Sprachstandards generieren, und die Code-Vervollständigung geht auf den aktuellen Codekontext ein. 1. Das Refaktorisieren von Code in neue Programmiersprachen hilft bei längerfristigen Migrations- und Modernisierungsvorhaben.",[49,2985,2986],{},"Code kann auf die unterstützten Sprachstandards älterer Systeme „herabgestuft“ werden.",[49,2988,2989],{},"GitLab Duo kann komplexe Code- und Programmiersprachen mit Beispielen in verschiedenen Programmiersprachen erklären.",[49,2991,2992],{},"Das Update auf Anthropic Claude 3.5 auf GitLab.com hat die Qualität und Geschwindigkeit der Codevorschläge und des Chats noch einmal verbessert (Self-Managed-Upgrade auf 17.3 empfohlen).",[49,2994,2995],{},"Es gibt keine Grenzen, außer deiner Vorstellungskraft und deinen Produktionsschwierigkeiten.",[12,2997,2998],{},"Erfahre mehr über effiziente Codevorschläge und Chat-Workflows und beginne jetzt deine KI-basierte Code-Refactoring-Reise mit GitLab Duo!",[2003,3000,3001],{},[12,3002,3003],{},[16,3004,3007],{"href":3005,"rel":3006},"https://about.gitlab.com/sales/?type=free-trial&toggle=gitlab-duo-pro_",[],"Starte deine kostenlose Testversion von GitLab Duo!",[3009,3010,3011],"style",{},"html pre.shiki code .sAwPA, html code.shiki .sAwPA{--shiki-default:#6A737D}html pre.shiki code .sD7c4, html code.shiki .sD7c4{--shiki-default:#D73A49}html pre.shiki code .sgsFI, html code.shiki .sgsFI{--shiki-default:#24292E}html pre.shiki code .sYu0t, html code.shiki .sYu0t{--shiki-default:#005CC5}html pre.shiki code .s7eDp, html code.shiki .s7eDp{--shiki-default:#6F42C1}html pre.shiki code .sqxcx, html code.shiki .sqxcx{--shiki-default:#E36209}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html pre.shiki code .sYBdl, html code.shiki .sYBdl{--shiki-default:#032F62}html pre.shiki code .s691h, html code.shiki .s691h{--shiki-default:#22863A;--shiki-default-font-weight:bold}",{"title":166,"searchDepth":181,"depth":181,"links":3013},[3014,3019,3023,3028],{"id":144,"depth":181,"text":145,"children":3015},[3016,3017,3018],{"id":152,"depth":199,"text":153},{"id":1006,"depth":199,"text":68},{"id":1939,"depth":199,"text":1940},{"id":2069,"depth":181,"text":2070,"children":3020},[3021,3022],{"id":2076,"depth":199,"text":2077},{"id":2567,"depth":199,"text":108},{"id":2900,"depth":181,"text":114,"children":3024},[3025,3026,3027],{"id":2903,"depth":199,"text":122},{"id":2915,"depth":199,"text":128},{"id":2948,"depth":199,"text":134},{"id":2974,"depth":181,"text":2975},"ai","2024-08-26","In diesem detaillierten Tutorial erfahren Entwickler(innen), wie sie Code mithilfe von KI modernisieren können, indem sie zu einer neuen Programmiersprache wechseln und mehr über neue Funktionen in dieser Sprache lernen.","md",null,false,"https://res.cloudinary.com/about-gitlab-com/image/upload/v1749662465/Blog/Hero%20Images/GitLab_Duo_Workflow_Unified_Data_Store__1_.png",{},"/de-de/blog/refactor-code-into-modern-languages-with-ai-powered-gitlab-duo",{"title":5,"description":3031,"ogTitle":5,"ogDescription":3031,"noIndex":3034,"ogImage":3035,"ogUrl":3039,"ogSiteName":3040,"ogType":3041,"canonicalUrls":3039},"https://about.gitlab.com/blog/refactor-code-into-modern-languages-with-ai-powered-gitlab-duo","https://about.gitlab.com","article","refactor-code-into-modern-languages-with-ai-powered-gitlab-duo","de-de/blog/refactor-code-into-modern-languages-with-ai-powered-gitlab-duo",[3045,3046,3047],"AI","tutorial","DevSecOps","BlogPost","2024-11-13","fnJabzgB06q9I7DRK0WXrBwPzptI5OEQk9NzyNmbxIY",{"logo":3052,"freeTrial":3057,"sales":3062,"login":3067,"items":3072,"search":3401,"minimal":3435,"duo":3453,"switchNav":3462,"pricingDeployment":3473},{"config":3053},{"href":3054,"dataGaName":3055,"dataGaLocation":3056},"/de-de/","gitlab logo","header",{"text":3058,"config":3059},"Kostenlose Testversion anfordern",{"href":3060,"dataGaName":3061,"dataGaLocation":3056},"https://gitlab.com/-/trial_registrations/new?glm_source=about.gitlab.com/de-de&glm_content=default-saas-trial/","free trial",{"text":3063,"config":3064},"Demo anfordern",{"href":3065,"dataGaName":3066,"dataGaLocation":3056},"/de-de/sales/?contact-topic=request-demo","sales",{"text":3068,"config":3069},"Anmelden",{"href":3070,"dataGaName":3071,"dataGaLocation":3056},"https://gitlab.com/users/sign_in/","sign in",[3073,3102,3204,3209,3323,3379],{"text":3074,"config":3075,"menu":3077},"Plattform",{"dataNavLevelOne":3076},"platform",{"type":3078,"columns":3079},"cards",[3080,3086,3094],{"title":3074,"description":3081,"link":3082},"Die intelligente Orchestrierungsplattform für DevSecOps",{"text":3083,"config":3084},"Die Plattform erkunden",{"href":3085,"dataGaName":3076,"dataGaLocation":3056},"/de-de/platform/",{"title":3087,"description":3088,"link":3089},"GitLab Duo Agent Platform","Agentische KI für den gesamten Software-Lebenszyklus",{"text":3090,"config":3091},"Lerne GitLab Duo kennen",{"href":3092,"dataGaName":3093,"dataGaLocation":3056},"/de-de/gitlab-duo-agent-platform/","gitlab duo agent platform",{"title":3095,"description":3096,"link":3097},"Warum GitLab?","Erfahre, warum sich Unternehmen für GitLab entscheiden",{"text":3098,"config":3099},"Mehr erfahren",{"href":3100,"dataGaName":3101,"dataGaLocation":3056},"/de-de/why-gitlab/","why gitlab",{"text":3103,"left":226,"config":3104,"menu":3106},"Produkt",{"dataNavLevelOne":3105},"solutions",{"type":3107,"link":3108,"columns":3112,"feature":3183},"lists",{"text":3109,"config":3110},"Alle Lösungen anzeigen",{"href":3111,"dataGaName":3105,"dataGaLocation":3056},"/de-de/solutions/",[3113,3138,3161],{"title":3114,"description":3115,"link":3116,"items":3121},"Automatisierung","CI/CD und Automatisierung zur Beschleunigung der Bereitstellung",{"config":3117},{"icon":3118,"href":3119,"dataGaName":3120,"dataGaLocation":3056},"AutomatedCodeAlt","/de-de/solutions/delivery-automation/","automated software delivery",[3122,3126,3129,3134],{"text":3123,"config":3124},"CI/CD",{"href":3125,"dataGaLocation":3056,"dataGaName":3123},"/de-de/solutions/continuous-integration/",{"text":3087,"config":3127},{"href":3092,"dataGaLocation":3056,"dataGaName":3128},"gitlab duo agent platform - product menu",{"text":3130,"config":3131},"Quellcodeverwaltung",{"href":3132,"dataGaLocation":3056,"dataGaName":3133},"/de-de/solutions/source-code-management/","Source Code Management",{"text":3135,"config":3136},"Automatische Softwarebereitstellung",{"href":3119,"dataGaLocation":3056,"dataGaName":3137},"Automated software delivery",{"title":3139,"description":3140,"link":3141,"items":3146},"Sicherheit","Entwickle Code schneller ohne Abstriche bei der Sicherheit",{"config":3142},{"href":3143,"dataGaName":3144,"dataGaLocation":3056,"icon":3145},"/de-de/solutions/application-security-testing/","security and compliance","ShieldCheckLight",[3147,3151,3156],{"text":3148,"config":3149},"Anwendungssicherheitstests",{"href":3143,"dataGaName":3150,"dataGaLocation":3056},"Application security testing",{"text":3152,"config":3153},"Schutz der Software-Lieferkette",{"href":3154,"dataGaLocation":3056,"dataGaName":3155},"/de-de/solutions/supply-chain/","Software supply chain security",{"text":3157,"config":3158},"Software-Compliance",{"href":3159,"dataGaName":3160,"dataGaLocation":3056},"/de-de/solutions/software-compliance/","software compliance",{"title":3162,"link":3163,"items":3168},"Messung",{"config":3164},{"icon":3165,"href":3166,"dataGaName":3167,"dataGaLocation":3056},"DigitalTransformation","/de-de/solutions/visibility-measurement/","visibility and measurement",[3169,3173,3178],{"text":3170,"config":3171},"Sichtbarkeit und Messung",{"href":3166,"dataGaLocation":3056,"dataGaName":3172},"Visibility and Measurement",{"text":3174,"config":3175},"Wertstrommanagement",{"href":3176,"dataGaLocation":3056,"dataGaName":3177},"/de-de/solutions/value-stream-management/","Value Stream Management",{"text":3179,"config":3180},"Analysen und Einblicke",{"href":3181,"dataGaLocation":3056,"dataGaName":3182},"/de-de/solutions/analytics-and-insights/","Analytics and insights",{"title":3184,"type":3107,"items":3185},"GitLab für",[3186,3192,3198],{"text":3187,"config":3188},"Enterprise",{"icon":3189,"href":3190,"dataGaLocation":3056,"dataGaName":3191},"Building","/de-de/enterprise/","enterprise",{"text":3193,"config":3194},"Kleinunternehmen",{"icon":3195,"href":3196,"dataGaLocation":3056,"dataGaName":3197},"Work","/de-de/small-business/","small business",{"text":3199,"config":3200},"Öffentlicher Sektor",{"icon":3201,"href":3202,"dataGaLocation":3056,"dataGaName":3203},"Organization","/de-de/solutions/public-sector/","public sector",{"text":3205,"config":3206},"Preise",{"href":3207,"dataGaName":3208,"dataGaLocation":3056,"dataNavLevelOne":3208},"/de-de/pricing/","pricing",{"text":3210,"config":3211,"menu":3213},"Ressourcen",{"dataNavLevelOne":3212},"resources",{"type":3107,"link":3214,"columns":3218,"feature":3312},{"text":3215,"config":3216},"Alle Ressourcen anzeigen",{"href":3217,"dataGaName":3212,"dataGaLocation":3056},"/de-de/resources/",[3219,3252,3279],{"title":3220,"items":3221},"Erste Schritte",[3222,3227,3232,3237,3242,3247],{"text":3223,"config":3224},"Installieren",{"href":3225,"dataGaName":3226,"dataGaLocation":3056},"/de-de/install/","install",{"text":3228,"config":3229},"Kurzanleitungen",{"href":3230,"dataGaName":3231,"dataGaLocation":3056},"/de-de/get-started/","quick setup checklists",{"text":3233,"config":3234},"Lernen",{"href":3235,"dataGaLocation":3056,"dataGaName":3236},"https://university.gitlab.com/","learn",{"text":3238,"config":3239},"Produktdokumentation",{"href":3240,"dataGaName":3241,"dataGaLocation":3056},"https://docs.gitlab.com/","product documentation",{"text":3243,"config":3244},"Best-Practice-Videos",{"href":3245,"dataGaName":3246,"dataGaLocation":3056},"/de-de/getting-started-videos/","best practice videos",{"text":3248,"config":3249},"Integrationen",{"href":3250,"dataGaName":3251,"dataGaLocation":3056},"/de-de/integrations/","integrations",{"title":3253,"items":3254},"Entdecken",[3255,3260,3265,3270,3274],{"text":3256,"config":3257},"Kundenerfolge",{"href":3258,"dataGaName":3259,"dataGaLocation":3056},"/de-de/customers/","customer success stories",{"text":3261,"config":3262},"Blog",{"href":3263,"dataGaName":3264,"dataGaLocation":3056},"/de-de/blog/","blog",{"text":3266,"config":3267},"Demo-Hub",{"href":3268,"dataGaName":3269,"dataGaLocation":3056},"/de-de/demo-hub/","demo hub",{"text":3271,"config":3272},"The Source",{"href":3273,"dataGaName":3264,"dataGaLocation":3056},"/de-de/the-source/",{"text":3275,"config":3276},"Remote",{"href":3277,"dataGaName":3278,"dataGaLocation":3056},"https://handbook.gitlab.com/handbook/company/culture/all-remote/","remote",{"title":3280,"items":3281},"Vernetzen",[3282,3287,3292,3297,3302,3307],{"text":3283,"config":3284},"GitLab-Services",{"href":3285,"dataGaName":3286,"dataGaLocation":3056},"/de-de/services/","services",{"text":3288,"config":3289},"Beitragen",{"href":3290,"dataGaName":3291,"dataGaLocation":3056},"https://contributors.gitlab.com","contribute",{"text":3293,"config":3294},"Community",{"href":3295,"dataGaName":3296,"dataGaLocation":3056},"/community/","community",{"text":3298,"config":3299},"Forum",{"href":3300,"dataGaName":3301,"dataGaLocation":3056},"https://forum.gitlab.com/","forum",{"text":3303,"config":3304},"Veranstaltungen",{"href":3305,"dataGaName":3306,"dataGaLocation":3056},"/events/","events",{"text":3308,"config":3309},"Partner",{"href":3310,"dataGaName":3311,"dataGaLocation":3056},"/de-de/partners/","partners",{"config":3313,"title":3316,"text":3317,"link":3318},{"background":3314,"textColor":3315},"url('https://res.cloudinary.com/about-gitlab-com/image/upload/v1777322348/qpq8yrgn8knii57omj0c.png')","#000","Neues bei GitLab","Über die neuesten Funktionen und Verbesserungen auf dem Laufenden bleiben.",{"text":3319,"config":3320},"Aktuelle Nachrichten",{"href":3321,"dataGaName":3322,"dataGaLocation":3056},"/de-de/whats-new/","whats new",{"text":3324,"config":3325,"menu":3327},"Unternehmen",{"dataNavLevelOne":3326},"company",{"type":3107,"columns":3328},[3329],{"items":3330},[3331,3336,3342,3344,3349,3354,3359,3364,3369,3374],{"text":3332,"config":3333},"Über",{"href":3334,"dataGaName":3335,"dataGaLocation":3056},"/de-de/company/","about",{"text":3337,"config":3338,"footerGa":3341},"Karriere",{"href":3339,"dataGaName":3340,"dataGaLocation":3056},"/jobs/","jobs",{"dataGaName":3340},{"text":3303,"config":3343},{"href":3305,"dataGaName":3306,"dataGaLocation":3056},{"text":3345,"config":3346},"Geschäftsführung",{"href":3347,"dataGaName":3348,"dataGaLocation":3056},"/company/team/e-group/","leadership",{"text":3350,"config":3351},"Handbuch",{"href":3352,"dataGaName":3353,"dataGaLocation":3056},"https://handbook.gitlab.com/","handbook",{"text":3355,"config":3356},"Investor Relations",{"href":3357,"dataGaName":3358,"dataGaLocation":3056},"https://ir.gitlab.com/overview/default.aspx","investor relations",{"text":3360,"config":3361},"Trust Center",{"href":3362,"dataGaName":3363,"dataGaLocation":3056},"/de-de/security/","trust center",{"text":3365,"config":3366},"AI Transparency Center",{"href":3367,"dataGaName":3368,"dataGaLocation":3056},"/de-de/ai-transparency-center/","ai transparency center",{"text":3370,"config":3371},"Newsletter",{"href":3372,"dataGaName":3373,"dataGaLocation":3056},"/company/contact/#contact-forms","newsletter",{"text":3375,"config":3376},"Presse",{"href":3377,"dataGaName":3378,"dataGaLocation":3056},"/press/","press",{"text":3380,"config":3381,"menu":3382},"Kontakt",{"dataNavLevelOne":3326},{"type":3107,"columns":3383},[3384],{"items":3385},[3386,3391,3396],{"text":3387,"config":3388},"Vertrieb kontaktieren",{"href":3389,"dataGaName":3390,"dataGaLocation":3056},"/de-de/sales/","talk to sales",{"text":3392,"config":3393},"Support-Portal",{"href":3394,"dataGaName":3395,"dataGaLocation":3056},"https://support.gitlab.com/hc/en-us","support portal",{"text":3397,"config":3398},"Kundenportal",{"href":3399,"dataGaName":3400,"dataGaLocation":3056},"https://customers.gitlab.com/customers/sign_in/","customer portal",{"close":3402,"login":3403,"suggestions":3410},"Schließen",{"text":3404,"link":3405},"Um Repositorys und Projekte zu durchsuchen, melde dich an bei",{"text":3406,"config":3407},"gitlab.com",{"href":3070,"dataGaName":3408,"dataGaLocation":3409},"search login","search",{"text":3411,"default":3412},"Vorschläge",[3413,3415,3420,3422,3427,3432],{"text":3087,"config":3414},{"href":3092,"dataGaName":3087,"dataGaLocation":3409},{"text":3416,"config":3417},"Codevorschläge (KI)",{"href":3418,"dataGaName":3419,"dataGaLocation":3409},"/de-de/solutions/code-suggestions/","Code Suggestions (AI)",{"text":3123,"config":3421},{"href":3125,"dataGaName":3123,"dataGaLocation":3409},{"text":3423,"config":3424},"GitLab auf AWS",{"href":3425,"dataGaName":3426,"dataGaLocation":3409},"/de-de/partners/technology-partners/aws/","GitLab on AWS",{"text":3428,"config":3429},"GitLab auf Google Cloud",{"href":3430,"dataGaName":3431,"dataGaLocation":3409},"/de-de/partners/technology-partners/google-cloud-platform/","GitLab on Google Cloud",{"text":3095,"config":3433},{"href":3100,"dataGaName":3434,"dataGaLocation":3409},"Why GitLab?",{"freeTrial":3436,"mobileIcon":3441,"desktopIcon":3446,"secondaryButton":3449},{"text":3437,"config":3438},"Kostenlos testen",{"href":3439,"dataGaName":3061,"dataGaLocation":3440},"https://gitlab.com/-/trials/new/","nav",{"altText":3442,"config":3443},"GitLab-Symbol",{"src":3444,"dataGaName":3445,"dataGaLocation":3440},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1758203874/jypbw1jx72aexsoohd7x.svg","gitlab icon",{"altText":3442,"config":3447},{"src":3448,"dataGaName":3445,"dataGaLocation":3440},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1758203875/gs4c8p8opsgvflgkswz9.svg",{"text":3220,"config":3450},{"href":3451,"dataGaName":3452,"dataGaLocation":3440},"https://gitlab.com/-/trial_registrations/new?glm_source=about.gitlab.com/de-de/get-started/","get started",{"freeTrial":3454,"mobileIcon":3458,"desktopIcon":3460},{"text":3455,"config":3456},"Mehr über GitLab Duo erfahren",{"href":3092,"dataGaName":3457,"dataGaLocation":3440},"gitlab duo",{"altText":3442,"config":3459},{"src":3444,"dataGaName":3445,"dataGaLocation":3440},{"altText":3442,"config":3461},{"src":3448,"dataGaName":3445,"dataGaLocation":3440},{"button":3463,"mobileIcon":3468,"desktopIcon":3470},{"text":3464,"config":3465},"/Option",{"href":3466,"dataGaName":3467,"dataGaLocation":3440},"#contact","switch",{"altText":3442,"config":3469},{"src":3444,"dataGaName":3445,"dataGaLocation":3440},{"altText":3442,"config":3471},{"src":3472,"dataGaName":3445,"dataGaLocation":3440},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1773335277/ohhpiuoxoldryzrnhfrh.png",{"freeTrial":3474,"mobileIcon":3479,"desktopIcon":3481},{"text":3475,"config":3476},"Zurück zur Preisübersicht",{"href":3207,"dataGaName":3477,"dataGaLocation":3440,"icon":3478},"back to pricing","GoBack",{"altText":3442,"config":3480},{"src":3444,"dataGaName":3445,"dataGaLocation":3440},{"altText":3442,"config":3482},{"src":3448,"dataGaName":3445,"dataGaLocation":3440},{"title":3484,"button":3485,"config":3489},"GitLab Orbit ist da: die Kontextebene für KI-Agenten",{"text":3098,"config":3486},{"href":3487,"dataGaName":3488,"dataGaLocation":3056},"/de-de/gitlab-orbit/","orbit",{"layout":3490,"disabled":3034},"release",{"data":3492},{"text":3493,"source":3494,"edit":3500,"contribute":3505,"config":3510,"items":3515,"minimal":3720},"Git ist eine Marke von Software Freedom Conservancy und unsere Verwendung von „GitLab“ erfolgt unter Lizenz.",{"text":3495,"config":3496},"Quelltext der Seite anzeigen",{"href":3497,"dataGaName":3498,"dataGaLocation":3499},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/","page source","footer",{"text":3501,"config":3502},"Diese Seite bearbeiten",{"href":3503,"dataGaName":3504,"dataGaLocation":3499},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/-/blob/main/content/","web ide",{"text":3506,"config":3507},"Beteilige dich",{"href":3508,"dataGaName":3509,"dataGaLocation":3499},"https://gitlab.com/gitlab-com/marketing/digital-experience/about-gitlab-com/-/blob/main/CONTRIBUTING.md/","please contribute",{"twitter":3511,"facebook":3512,"youtube":3513,"linkedin":3514},"https://twitter.com/gitlab","https://www.facebook.com/gitlab","https://www.youtube.com/channel/UCnMGQ8QHMAnVIsI3xJrihhg","https://www.linkedin.com/company/gitlab-com",[3516,3561,3613,3655,3687],{"title":3205,"links":3517,"subMenu":3532},[3518,3522,3527],{"text":3519,"config":3520},"Tarife anzeigen",{"href":3207,"dataGaName":3521,"dataGaLocation":3499},"view plans",{"text":3523,"config":3524},"Vorteile von Premium",{"href":3525,"dataGaName":3526,"dataGaLocation":3499},"/de-de/pricing/premium/","why premium",{"text":3528,"config":3529},"Vorteile von Ultimate",{"href":3530,"dataGaName":3531,"dataGaLocation":3499},"/de-de/pricing/ultimate/","why ultimate",[3533],{"title":3380,"links":3534},[3535,3537,3539,3541,3546,3551,3556],{"text":3387,"config":3536},{"href":3389,"dataGaName":3066,"dataGaLocation":3499},{"text":3392,"config":3538},{"href":3394,"dataGaName":3395,"dataGaLocation":3499},{"text":3397,"config":3540},{"href":3399,"dataGaName":3400,"dataGaLocation":3499},{"text":3542,"config":3543},"Status",{"href":3544,"dataGaName":3545,"dataGaLocation":3499},"https://status.gitlab.com/","status",{"text":3547,"config":3548},"Nutzungsbedingungen",{"href":3549,"dataGaName":3550,"dataGaLocation":3499},"/terms/","terms of use",{"text":3552,"config":3553},"Datenschutzerklärung",{"href":3554,"dataGaName":3555,"dataGaLocation":3499},"/de-de/privacy/","privacy statement",{"text":3557,"config":3558},"Cookie-Einstellungen",{"dataGaName":3559,"dataGaLocation":3499,"id":3560,"isOneTrustButton":226},"cookie preferences","ot-sdk-btn",{"title":3103,"links":3562,"subMenu":3571},[3563,3567],{"text":3564,"config":3565},"DevSecOps-Plattform",{"href":3085,"dataGaName":3566,"dataGaLocation":3499},"devsecops platform",{"text":3568,"config":3569},"KI-unterstützte Entwicklung",{"href":3092,"dataGaName":3570,"dataGaLocation":3499},"ai-assisted development",[3572],{"title":3573,"links":3574},"Themen",[3575,3579,3584,3589,3594,3598,3603,3608],{"text":3123,"config":3576},{"href":3577,"dataGaName":3578,"dataGaLocation":3499},"/de-de/topics/ci-cd/","cicd",{"text":3580,"config":3581},"GitOps",{"href":3582,"dataGaName":3583,"dataGaLocation":3499},"/de-de/topics/gitops/","gitops",{"text":3585,"config":3586},"DevOps",{"href":3587,"dataGaName":3588,"dataGaLocation":3499},"/de-de/topics/devops/","devops",{"text":3590,"config":3591},"Versionskontrolle",{"href":3592,"dataGaName":3593,"dataGaLocation":3499},"/de-de/topics/version-control/","version control",{"text":3047,"config":3595},{"href":3596,"dataGaName":3597,"dataGaLocation":3499},"/de-de/topics/devsecops/","devsecops",{"text":3599,"config":3600},"Cloud-nativ",{"href":3601,"dataGaName":3602,"dataGaLocation":3499},"/de-de/topics/cloud-native/","cloud native",{"text":3604,"config":3605},"KI für das Programmieren",{"href":3606,"dataGaName":3607,"dataGaLocation":3499},"/de-de/topics/devops/ai-for-coding/","ai for coding",{"text":3609,"config":3610},"Agentische KI",{"href":3611,"dataGaName":3612,"dataGaLocation":3499},"/de-de/topics/agentic-ai/","agentic ai",{"title":3614,"links":3615},"Lösungen",[3616,3619,3621,3626,3630,3633,3636,3639,3641,3643,3645,3650],{"text":3148,"config":3617},{"href":3143,"dataGaName":3618,"dataGaLocation":3499},"Application Security Testing",{"text":3135,"config":3620},{"href":3119,"dataGaName":3120,"dataGaLocation":3499},{"text":3622,"config":3623},"Agile Entwicklung",{"href":3624,"dataGaName":3625,"dataGaLocation":3499},"/de-de/solutions/agile-delivery/","agile delivery",{"text":3627,"config":3628},"SCM",{"href":3132,"dataGaName":3629,"dataGaLocation":3499},"source code management",{"text":3123,"config":3631},{"href":3125,"dataGaName":3632,"dataGaLocation":3499},"continuous integration & delivery",{"text":3174,"config":3634},{"href":3176,"dataGaName":3635,"dataGaLocation":3499},"value stream management",{"text":3580,"config":3637},{"href":3638,"dataGaName":3583,"dataGaLocation":3499},"/de-de/solutions/gitops/",{"text":3187,"config":3640},{"href":3190,"dataGaName":3191,"dataGaLocation":3499},{"text":3193,"config":3642},{"href":3196,"dataGaName":3197,"dataGaLocation":3499},{"text":3199,"config":3644},{"href":3202,"dataGaName":3203,"dataGaLocation":3499},{"text":3646,"config":3647},"Bildungswesen",{"href":3648,"dataGaName":3649,"dataGaLocation":3499},"/de-de/solutions/education/","education",{"text":3651,"config":3652},"Finanzdienstleistungen",{"href":3653,"dataGaName":3654,"dataGaLocation":3499},"/de-de/solutions/finance/","financial services",{"title":3210,"links":3656},[3657,3659,3661,3663,3666,3668,3671,3673,3675,3677,3679,3681,3683,3685],{"text":3223,"config":3658},{"href":3225,"dataGaName":3226,"dataGaLocation":3499},{"text":3228,"config":3660},{"href":3230,"dataGaName":3231,"dataGaLocation":3499},{"text":3233,"config":3662},{"href":3235,"dataGaName":3236,"dataGaLocation":3499},{"text":3238,"config":3664},{"href":3240,"dataGaName":3665,"dataGaLocation":3499},"docs",{"text":3261,"config":3667},{"href":3263,"dataGaName":3264,"dataGaLocation":3499},{"text":3669,"config":3670},"Neuerungen",{"href":3321,"dataGaName":3322,"dataGaLocation":3499},{"text":3256,"config":3672},{"href":3258,"dataGaName":3259,"dataGaLocation":3499},{"text":3275,"config":3674},{"href":3277,"dataGaName":3278,"dataGaLocation":3499},{"text":3283,"config":3676},{"href":3285,"dataGaName":3286,"dataGaLocation":3499},{"text":3288,"config":3678},{"href":3290,"dataGaName":3291,"dataGaLocation":3499},{"text":3293,"config":3680},{"href":3295,"dataGaName":3296,"dataGaLocation":3499},{"text":3298,"config":3682},{"href":3300,"dataGaName":3301,"dataGaLocation":3499},{"text":3303,"config":3684},{"href":3305,"dataGaName":3306,"dataGaLocation":3499},{"text":3308,"config":3686},{"href":3310,"dataGaName":3311,"dataGaLocation":3499},{"title":3324,"links":3688},[3689,3691,3693,3695,3697,3699,3704,3709,3711,3713,3715],{"text":3332,"config":3690},{"href":3334,"dataGaName":3326,"dataGaLocation":3499},{"text":3337,"config":3692},{"href":3339,"dataGaName":3340,"dataGaLocation":3499},{"text":3345,"config":3694},{"href":3347,"dataGaName":3348,"dataGaLocation":3499},{"text":3350,"config":3696},{"href":3352,"dataGaName":3353,"dataGaLocation":3499},{"text":3355,"config":3698},{"href":3357,"dataGaName":3358,"dataGaLocation":3499},{"text":3700,"config":3701},"Nachhaltigkeit",{"href":3702,"dataGaName":3703,"dataGaLocation":3499},"/sustainability/","Sustainability",{"text":3705,"config":3706},"Vielfalt, Inklusion und Zugehörigkeit",{"href":3707,"dataGaName":3708,"dataGaLocation":3499},"/de-de/diversity-inclusion-belonging/","Diversity, inclusion and belonging",{"text":3360,"config":3710},{"href":3362,"dataGaName":3363,"dataGaLocation":3499},{"text":3370,"config":3712},{"href":3372,"dataGaName":3373,"dataGaLocation":3499},{"text":3375,"config":3714},{"href":3377,"dataGaName":3378,"dataGaLocation":3499},{"text":3716,"config":3717},"Transparenzerklärung zu moderner Sklaverei",{"href":3718,"dataGaName":3719,"dataGaLocation":3499},"https://handbook.gitlab.com/handbook/legal/modern-slavery-act-transparency-statement/","modern slavery transparency statement",{"items":3721},[3722,3725,3728],{"text":3723,"config":3724},"Terms",{"href":3549,"dataGaName":3550,"dataGaLocation":3499},{"text":3726,"config":3727},"Cookies",{"dataGaName":3559,"dataGaLocation":3499,"id":3560,"isOneTrustButton":226},{"text":3729,"config":3730},"Datenschutz",{"href":3554,"dataGaName":3555,"dataGaLocation":3499},[3732],{"id":3733,"title":7,"body":3033,"config":3734,"content":3736,"description":3033,"extension":3740,"meta":3741,"navigation":226,"path":3742,"seo":3743,"stem":3744,"__hash__":3745},"blogAuthors/en-us/blog/authors/michael-friedrich.yml",{"template":3735},"BlogAuthor",{"name":7,"config":3737},{"headshot":3738,"ctfId":3739},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1749659879/Blog/Author%20Headshots/dnsmichi-headshot.jpg","dnsmichi","yml",{},"/en-us/blog/authors/michael-friedrich",{},"en-us/blog/authors/michael-friedrich","lJ-nfRIhdG49Arfrxdn1Vv4UppwD51BB13S3HwIswt4",[3747,3755,3763],{"title":3748,"description":3749,"heroImage":3750,"category":3029,"date":3751,"authors":3752,"slug":3754,"externalUrl":3033},"Wie ich einen Demo-Generator mit Duo Agent Platform baute","So sahen Demos nicht immer aus. Ein Rückblick auf ihre Entwicklung, plus ein Tutorial zum Bau einer eigenen Demo und eines eigenen Agenten.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1765809212/noh0mdfn9o94ry9ykura.png","2026-08-13",[3753],"Itzik Gan Baruch","agentic-click-through-demo",{"title":3756,"description":3757,"heroImage":3758,"category":3029,"date":3759,"authors":3760,"slug":3762,"externalUrl":3033},"Governance für agentische KI, MCPs und KI-Code-Assistenten","KI-Agenten schreiben, pushen und deployen, ohne dass jeder Schritt geprüft wird. Ein praktisches Framework für Zugriff, Berechtigungen und Audit-Trails.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1785337625/ifzlc2hyzaxhzmjgyymh.png","2026-07-31",[3761],"Julie Griffin","govern-agentic-ai-mcps-code-assistants",{"title":3764,"description":3765,"heroImage":3766,"category":3029,"date":3767,"authors":3768,"slug":3770,"externalUrl":3033},"Claude Opus 5 auf GitLab: Reasoning für die anspruchsvollsten Aufgaben","Anthropics Claude Opus 5 ist jetzt auf der GitLab Duo Agent Platform verfügbar und bringt tieferes Reasoning für die anspruchsvollsten Aufgaben.","https://res.cloudinary.com/about-gitlab-com/image/upload/v1750099203/Blog/Hero%20Images/Blog/Hero%20Images/blog-image-template-1800x945%20%2820%29_2bJGC5ZP3WheoqzlLT05C5_1750099203484.png","2026-07-27",[3769],"Brittany Lutz","claude-opus-5-on-gitlab-duo-agent-platform",{"promotions":3772},[3773,3786,3798,3810],{"id":3774,"categories":3775,"header":3776,"text":3777,"button":3778,"image":3783},"ai-modernization",[3029],"Hält KI, was uns versprochen wurde?","Das Quiz dauert maximal 5 Minuten.",{"text":3779,"config":3780},"Ermittle deinen KI-Reifegrad",{"href":3781,"dataGaName":3782,"dataGaLocation":3264},"/de-de/assessments/ai-modernization-assessment/","modernization assessment",{"config":3784},{"src":3785},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1772138786/qix0m7kwnd8x2fh1zq49.png",{"id":3787,"categories":3788,"header":3790,"text":3777,"button":3791,"image":3795},"devops-modernization",[3789,3597],"product","Verwaltest du Tool-Chaos oder stellst du Innovationen bereit?",{"text":3792,"config":3793},"Ermittle deinen DevOps-Reifegrad",{"href":3794,"dataGaName":3782,"dataGaLocation":3264},"/de-de/assessments/devops-modernization-assessment/",{"config":3796},{"src":3797},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1772138785/eg818fmakweyuznttgid.png",{"id":3799,"categories":3800,"header":3802,"text":3777,"button":3803,"image":3807},"security-modernization",[3801],"security","Tauschst du Schnelligkeit gegen Sicherheit ein?",{"text":3804,"config":3805},"Ermittle deinen Sicherheitsreifegrad",{"href":3806,"dataGaName":3782,"dataGaLocation":3264},"/de-de/assessments/security-modernization-assessment/",{"config":3808},{"src":3809},"https://res.cloudinary.com/about-gitlab-com/image/upload/v1772138786/p4pbqd9nnjejg5ds6mdk.png",{"id":3811,"paths":3812,"header":3815,"text":3816,"button":3817,"image":3822},"github-azure-migration",[3813,3814],"migration-from-azure-devops-to-gitlab","integrating-azure-devops-scm-and-gitlab","Ist dein Team bereit für den Umzug von GitHub nach Azure?","GitHub stellt bereits auf Azure um. Finde heraus, was das für dich bedeutet.",{"text":3818,"config":3819},"Erfahre, wie GitLab im Vergleich zu GitHub abschneidet",{"href":3820,"dataGaName":3821,"dataGaLocation":3264},"/de-de/compare/gitlab-vs-github/github-azure-migration/","github azure migration",{"config":3823},{"src":3797},{"header":3825,"blurb":3826,"button":3827,"secondaryButton":3832},"Beginne noch heute, schneller zu entwickeln","Entdecke, was dein Team mit der intelligenten Orchestrierungsplattform für DevSecOps erreichen kann.\n",{"text":3828,"config":3829},"Kostenlosen Test starten",{"href":3830,"dataGaName":3061,"dataGaLocation":3831},"https://gitlab.com/-/trial_registrations/new?glm_content=default-saas-trial&glm_source=about.gitlab.com/de-de/","feature",{"text":3387,"config":3833},{"href":3389,"dataGaName":3066,"dataGaLocation":3831},1786803749913]