偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

他們?cè)趯W(xué)校里不會(huì)教你的編程原則

開發(fā) 前端
本文總結(jié)了軟件編程中的黃金原則,KISS?原則,DRY?原則,SOLID原則。這些原則不僅僅適用于編程,也可以指導(dǎo)我們?cè)诩軜?gòu)設(shè)計(jì)上。雖然其中有些原則很抽象,但是大家多多實(shí)踐和思考,會(huì)體會(huì)到這些原則的精妙。

前言

在大學(xué)的時(shí)候,學(xué)校一般只會(huì)教你你寫編程語言,比如C、C++、JAVA等編程語言。但是當(dāng)你離開大學(xué)進(jìn)入這個(gè)行業(yè)開始工作時(shí),才知道編程不只是知道編程語言、語法等,要想寫好代碼,必須還要了解一些編程原則才行。本文主要討論KISS、DRY和SOLID這些常見的編程原則,而且你會(huì)發(fā)現(xiàn)隨著工作時(shí)間越久,越能感受這些編程原則的精妙之處,歷久彌香。

KISS原則

Keep It Simple, Stupid!

你是不是有過接手同事的代碼感到十分頭疼的經(jīng)歷,明明可以有更加簡(jiǎn)單、明白的寫法,非要繞來繞去,看不明白?

其實(shí),我們?cè)趯懘a的時(shí)候應(yīng)該要遵守KISS原則,核心思想就是盡量保持簡(jiǎn)單。代碼的可讀性和可維護(hù)性是衡量代碼質(zhì)量非常重要的兩個(gè)標(biāo)準(zhǔn)。而 KISS 原則就是保持代碼可讀和可維護(hù)的重要手段。代碼足夠簡(jiǎn)單,也就意味著很容易讀懂,bug 比較難隱藏。即便出現(xiàn) bug,修復(fù)起來也比較簡(jiǎn)單。

我們寫代碼的的時(shí)候要站在別人的角度出發(fā),就像馬丁·福勒說的,我們寫的代碼不是給機(jī)器看的,而是給人看的。

“任何傻瓜都可以編寫計(jì)算機(jī)可以理解的代碼。優(yōu)秀的程序員編寫出人類可以理解的代碼?!?— 馬丁·福勒

那么如何才能寫出滿足KISS原則的代碼呢?

如何寫出KISS原則的代碼?

我們直接上例子,下面的校驗(yàn)IP是否合法的3種實(shí)現(xiàn)方式,大家覺得哪個(gè)最KISS?

寫法一

圖片

寫法二

圖片

寫法三

圖片

  • 寫法一代碼量最少,正則表達(dá)式本身是比較復(fù)雜的,寫出完全沒有 bug 的正則表達(dá)本身就比較有挑戰(zhàn);另一方面,并不是每個(gè)程序員都精通正則表達(dá)式。對(duì)于不怎么懂正則表達(dá)式的同事來說,看懂并且維護(hù)這段正則表達(dá)式是比較困難的。這種實(shí)現(xiàn)方式會(huì)導(dǎo)致代碼的可讀性和可維護(hù)性變差,所以,從 KISS 原則的設(shè)計(jì)初衷上來講,這種實(shí)現(xiàn)方式并不符合 KISS 原則。
  • 寫法二使用了 StringUtils 類、Integer 類提供的一些現(xiàn)成的工具函數(shù),來處理 IP地址字符串,邏輯清晰,可讀性好。
  • 寫法三不使用任何工具函數(shù),而是通過逐一處理 IP 地址中的字符,來判斷是否合法,容易出bug,不好理解。

所以說,符合KISS原則的代碼并不是代碼越少越好,還要考慮代碼是否邏輯清晰、是否容易理解、是否夠穩(wěn)定。

總結(jié)以下如何寫出KISS原則的代碼:

  1. 不要使用同事可能不懂的技術(shù)來實(shí)現(xiàn)代碼。比如前面例子中的正則表達(dá)式,還有一些編程語言中過于高級(jí)的語法等。
  2. 不要重復(fù)造輪子,要善于使用已經(jīng)有的工具類庫(kù)。經(jīng)驗(yàn)證明,自己去實(shí)現(xiàn)這些類庫(kù),出bug 的概率會(huì)更高,維護(hù)的成本也比較高。
  3. 不要過度優(yōu)化。不要過度使用一些奇技淫巧(比如,位運(yùn)算代替算術(shù)運(yùn)算、復(fù)雜的條件語句代替if-else、使用一些過于底層的函數(shù)等)來優(yōu)化代碼,犧牲代碼的可讀性。
  4. 主觀站在別人的角度上編寫代碼。你在編寫代碼的時(shí)候就要思考我這個(gè)同事看這段代碼是不是很快就能夠明白理解。

DRY原則

Don't Repeat Yourself

你是不是有過這樣的經(jīng)歷,項(xiàng)目中很多重復(fù)邏輯的代碼,然后修改一個(gè)地方,另外一個(gè)地方忘記修改,導(dǎo)致測(cè)試給你提了很多bug?

DRY原則,英文全稱Don’t Repeat Yourself,直譯過來就是不要重復(fù)你自己。這里的重復(fù)不僅僅是代碼一模一樣,還包括實(shí)現(xiàn)邏輯重復(fù)、功能語義重復(fù)、代碼執(zhí)行重復(fù)等。我們不要偷懶,有責(zé)任把這些存在重復(fù)的地方識(shí)別出來,然后優(yōu)化它們。

如何寫出DRY原則的代碼呢?

我們直接上例子,代碼重復(fù)的我就不講了,很好理解,關(guān)于實(shí)現(xiàn)邏輯或者功能語義重復(fù)的我覺個(gè)例子。

還是上面校驗(yàn)IP的例子,團(tuán)隊(duì)中兩個(gè)同事由于不知道就有了兩種寫法。

  • 同事A寫法

圖片

  • 同事B寫法

圖片

盡管兩段代碼的實(shí)現(xiàn)邏輯不重復(fù),但語義重復(fù),也就是功能重復(fù),我們認(rèn)為它違反了 DRY 原則。我們應(yīng)該在項(xiàng)目中,統(tǒng)一一種實(shí)現(xiàn)思路,所有用到判斷 IP 地址是否合法的地方,都統(tǒng)一調(diào)用同一個(gè)函數(shù)。不然哪天校驗(yàn)規(guī)則變了,很容易只改了其中一個(gè),另外一個(gè)漏改,就會(huì)出現(xiàn)莫名其妙的bug。

其他的比如邏輯重復(fù)的意思是雖然功能是不一致的,但是里面的邏輯都是一模一樣的。舉個(gè)例子,比如校驗(yàn)用戶名和校驗(yàn)密碼,雖然功能不一致,但是校驗(yàn)邏輯都是相似,判空、字符長(zhǎng)度等等,這種情況我們就需要把相似的邏輯抽取到一個(gè)方法中,不然也是不符合DRY原則。

那么我們平時(shí)寫代碼注意些什么才是符合DRY原則呢?

  • 使用現(xiàn)成的輪子,不輕易造輪子

其實(shí)最關(guān)鍵的就是寫代碼帶腦子,用到一個(gè)方法先看看有沒有現(xiàn)成的,不要看看不看,就動(dòng)手在那里造輪子。

  • 減少代碼耦合

對(duì)于高度耦合的代碼,當(dāng)我們希望復(fù)用其中的一個(gè)功能,想把這個(gè)功能的代碼抽取出來成為一個(gè)獨(dú)立的模塊、類或者函數(shù)的時(shí)候,往往會(huì)發(fā)現(xiàn)牽一發(fā)而動(dòng)全身。移動(dòng)一點(diǎn)代碼,就要牽連到很多其他相關(guān)的代碼。所以,高度耦合的代碼會(huì)影響到代碼的復(fù)用性,我們要盡量減少代碼耦合。

  • 滿足單一職責(zé)原則

我們前面講過,如果職責(zé)不夠單一,模塊、類設(shè)計(jì)得大而全,那依賴它的代碼或者它依賴的代碼就會(huì)比較多,進(jìn)而增加了代碼的耦合。根據(jù)上一點(diǎn),也就會(huì)影響到代碼的復(fù)用性。相反,越細(xì)粒度的代碼,代碼的通用性會(huì)越好,越容易被復(fù)用。

  • 模塊化

這里的“模塊”,不單單指一組類構(gòu)成的模塊,還可以理解為單個(gè)類、函數(shù)。我們要善于將功能獨(dú)立的代碼,封裝成模塊。獨(dú)立的模塊就像一塊一塊的積木,更加容易復(fù)用,可以直接拿來搭建更加復(fù)雜的系統(tǒng)。

  • 業(yè)務(wù)與非業(yè)務(wù)邏輯分離

越是跟業(yè)務(wù)無關(guān)的代碼越是容易復(fù)用,越是針對(duì)特定業(yè)務(wù)的代碼越難復(fù)用。所以,為了復(fù)用跟業(yè)務(wù)無關(guān)的代碼,我們將業(yè)務(wù)和非業(yè)務(wù)邏輯代碼分離,抽取成一些通用的框架、類庫(kù)、組件等。

  • 通用代碼下沉

從分層的角度來看,越底層的代碼越通用、會(huì)被越多的模塊調(diào)用,越應(yīng)該設(shè)計(jì)得足夠可復(fù)用。一般情況下,在代碼分層之后,為了避免交叉調(diào)用導(dǎo)致調(diào)用關(guān)系混亂,我們只允許上層代碼調(diào)用下層代碼及同層代碼之間的調(diào)用,杜絕下層代碼調(diào)用上層代碼。所以,通用的代碼我們盡量下沉到更下層。

  • 繼承、多態(tài)、抽象、封裝

在講面向?qū)ο筇匦缘臅r(shí)候,我們講到,利用繼承,可以將公共的代碼抽取到父類,子類復(fù)用父類的屬性和方法。利用多態(tài),我們可以動(dòng)態(tài)地替換一段代碼的部分邏輯,讓這段代碼可復(fù)用。除此之外,抽象和封裝,從更加廣義的層面、而非狹義的面向?qū)ο筇匦缘膶用鎭砝斫獾脑?,越抽象、越不依賴具體的實(shí)現(xiàn),越容易復(fù)用。代碼封裝成模塊,隱藏可變的細(xì)節(jié)、暴露不變的接口,就越容易復(fù)用。

  • 應(yīng)用模板等設(shè)計(jì)模式

一些設(shè)計(jì)模式,也能提高代碼的復(fù)用性。比如,模板模式利用了多態(tài)來實(shí)現(xiàn),可以靈活地替換其中的部分代碼,整個(gè)流程模板代碼可復(fù)用。

SOLID原則

SOLID原則不是一個(gè)單一的原則,而是對(duì)軟件開發(fā)至關(guān)重要的 5 條原則,遵循這些原則有助于我們寫出高內(nèi)聚、低耦合、可擴(kuò)展、可維護(hù)性好的代碼。

S—單一職責(zé)原則

一個(gè)類應(yīng)該有一個(gè),而且只有一個(gè)改變它的理由。

單一職責(zé)原則在我看來是最容易理解也是最重要的一個(gè)原則。它的核心思想就是一個(gè)模塊、類或者方法只做一件事,只有一個(gè)職責(zé),千萬不要越俎代庖。它可以帶來下面的好處:

  • 可以讓代碼耦合度更低
  • 使代碼更容易理解和維護(hù)
  • 使代碼更易于測(cè)試和維護(hù),使軟件更易于實(shí)施,并有助于避免未來更改的意外副作用

舉個(gè)例子,我們有兩個(gè)類Person和Account。 兩者都負(fù)有存儲(chǔ)其特定信息的單一責(zé)任。 如果要更改Person的狀態(tài),則無需修改類Account,反之亦然, 不要把賬戶的行為比如修改賬戶名changeAcctName寫在Person類中。

public class Person {
     private Long personId;
     private String firstName;
     private String lastName;
     private String age;
     private List<Account> accounts;

        // 錯(cuò)誤做法
        public void changeAcctName(Account account, String acctName) {
            acccount.setAccountName(acctName);
            // 更新到數(shù)據(jù)庫(kù)
        }
    }

    public class Account {
     private Long guid;
     private String accountNumber;
     private String accountName;
     private String status;
     private String type;

    }

所以大家在編寫代碼的時(shí)候,一定要停頓思考下這個(gè)段代碼真的寫在這里嗎?另外很關(guān)鍵的一點(diǎn)是如果發(fā)現(xiàn)一個(gè)類或者一個(gè)方法十分龐大,那么很有可能已經(jīng)違背單一職責(zé)原則了,后續(xù)維護(hù)可想而知十分痛苦。

O—開閉原則

軟件實(shí)體(類、模塊、函數(shù)等)應(yīng)該對(duì)擴(kuò)展開放,對(duì)修改關(guān)閉。

對(duì)擴(kuò)展開放,對(duì)修改關(guān)閉,什么意思?很簡(jiǎn)單,其實(shí)就是我們要盡量通過新增類實(shí)現(xiàn)功能,而不是修改原有的類或者邏輯。因?yàn)樾薷囊延写a很有可能對(duì)已有功能引入bug。

讓我們通過一個(gè)例子來理解這個(gè)原則,比如一個(gè)通知服務(wù)。

public class NotificationService {
     public void sendOTP(String medium) {
            if (medium.equals("email")) {
                //email 發(fā)送
            } else if (medium.equals("mobile")) {
                // 手機(jī)發(fā)送
         } 
    }

現(xiàn)在需要新增微信的方式通知,你要怎么做呢? 是在加一個(gè)if else嗎? 這樣就不符合開閉原則了,我們看下開閉原則該怎么寫。

  • 定義一個(gè)通知服務(wù)接口
public interface NotificationService {
     public void sendOTP();
    }
  • E-mail方式通知類EmailNotification
public class EmailNotification implements NotificationService{
     public void sendOTP(){
      // write Logic using JavaEmail api
     }
    }
  • 手機(jī)方式通知類MobileNotification
public class MobileNotification implements NotificationService{
        public void sendOTP(){
      // write Logic using Twilio SMS API
     }
    }
  • 同樣可以添加微信通知服務(wù)的實(shí)現(xiàn)WechatNotification
public class WechatNotification implements NotificationService{
     public void sendOTP(String medium){
      // write Logic using wechat API
     }
    }

這樣的方式就是遵循開閉原則的,你不用修改核心的業(yè)務(wù)邏輯,這樣可能帶來意向不到的后果,而是擴(kuò)展實(shí)現(xiàn)方式,由調(diào)用方根據(jù)他們的實(shí)際情況調(diào)用。

是不是想到了設(shè)計(jì)模式中的策略模式,其實(shí)設(shè)計(jì)模式就是指導(dǎo)我們寫出高內(nèi)聚、低耦合的代碼。

L—里氏替換原則

派生類或子類必須可替代其基類或父類

這個(gè)原則稍微有點(diǎn)難以理解,它的核心思想是每個(gè)子類或派生類都應(yīng)該可以替代/等效于它們的基類或父類。這樣有一個(gè)好處,就是無論子類是什么類型,客戶端通過父類調(diào)用都不會(huì)產(chǎn)生意外的后果。

理解不了?那我我們通過一個(gè)例子來理解一下。

讓我們考慮一下我有一個(gè)名為 SocialMedia 的抽象類,它支持所有社交媒體活動(dòng)供用戶娛樂,如下所示:

package com.alvin.solid.lsp;

    public abstract class SocialMedia {
        
        public abstract  void chatWithFriend();
        
        public abstract void publishPost(Object post);
        
        public abstract  void sendPhotosAndVideos();
        
        public abstract  void groupVideoCall(String... users);
    }

社交媒體可以有多個(gè)實(shí)現(xiàn)或可以有多個(gè)子類,如 Facebook、Wechat、Weibo 和 Twitter 等。

現(xiàn)在讓我們假設(shè) Facebook 想要使用這個(gè)特性或功能。

package com.alvin.solid.lsp;

    public class Wechat extends SocialMedia {

        public void chatWithFriend() {
            //logic  
        }

        public void publishPost(Object post) {
            //logic  
        }

        public void sendPhotosAndVideos() {
            //logic  
        }

        public void groupVideoCall(String... users) {
            //logic  
        }
    }

我們都知道Facebook都提供了所有上述的功能,所以這里我們可以認(rèn)為Facebook是SocialMedia類的完全替代品,兩者都可以無中斷地替代。

現(xiàn)在讓我們討論 Weibo 類

package com.alvin.solid.lsp;

    public class Weibo extends SocialMedia {
        public void chatWithFriend() {
            //logic
        }

        public void publishPost(Object post) {
          //logic
        }

        public void sendPhotosAndVideos() {
          //logic
        }

        public void groupVideoCall(String... users) {
            //不適用
        }
    }

我們都知道Weibo微博這個(gè)產(chǎn)品是沒有群視頻功能的,所以對(duì)于 groupVideoCall方法來說 Weibo 子類不能替代父類 SocialMedia。所以我們認(rèn)為它是不符合里式替換原則。

如果強(qiáng)行這么做的話,會(huì)導(dǎo)致客戶端用父類SocialMedia調(diào)用,但是實(shí)現(xiàn)類注入的可能是個(gè)Weibo的實(shí)現(xiàn),調(diào)用groupVideoCall行為,產(chǎn)生意想不到的后果。

那有什么解決方案嗎?

那就把功能拆開唄。

public interface SocialMedia {   
       public void chatWithFriend(); 
       public void sendPhotosAndVideos() 
    }
public interface SocialPostAndMediaManager { 
        public void publishPost(Object post); 
    }
public interface VideoCallManager{ 
       public void groupVideoCall(String... users); 
    }

現(xiàn)在,如果您觀察到我們將特定功能隔離到單獨(dú)的類以遵循LSP。

現(xiàn)在由實(shí)現(xiàn)類決定支持功能,根據(jù)他們所需的功能,他們可以使用各自的接口,例如 Weibo 不支持視頻通話功能,因此 Weibo 實(shí)現(xiàn)可以設(shè)計(jì)成這樣:

public class Instagram implements SocialMedia,SocialPostAndMediaManager{
     public void chatWithFriend(){
        //logic
        }
        public void sendPhotosAndVideos(){
        //logic
        }
        public void publishPost(Object post){
        //logic
        }
    }

這樣子就是符合里式替換原則LSP。

I—接口隔離原則

接口不應(yīng)該強(qiáng)迫他們的客戶依賴它不使用的方法。

大家可以看看自己的工程,是不是一個(gè)接口類中有很多很多的接口,每次調(diào)用API方法的時(shí)候IDE工具給你彈出一大堆,十分的"臃腫肥胖"。所以該原則的核心思想要將你的接口拆小,拆細(xì),打破”胖接口“,不用強(qiáng)迫客戶端實(shí)現(xiàn)他們不需要的接口。是不是和單一職責(zé)原則有點(diǎn)像?

例如,假設(shè)有一個(gè)名為 UPIPayment 的接口,如下所示

public interface UPIPayments {
        
        public void payMoney();
        
        public void getScratchCard();
        
        public void getCashBackAsCreditBalance();
    }

現(xiàn)在讓我們談?wù)?nbsp;UPIPayments 的一些實(shí)現(xiàn),比如 Google Pay 和 AliPay。

Google Pay 支持這些功能所以他可以直接實(shí)現(xiàn)這個(gè) UPIPayments 但 AliPay 不支持 getCashBackAsCreditBalance()功能所以這里我們不應(yīng)該強(qiáng)制客戶端 AliPay 通過實(shí)現(xiàn) UPIPayments 來覆蓋這個(gè)方法。

我們需要根據(jù)客戶需要分離接口,所以為了滿足接口隔離原則,我們可以如下設(shè)計(jì):

  • 創(chuàng)建一個(gè)單獨(dú)的接口來處理現(xiàn)金返還。
public interface CashbackManager{ 
     public void getCashBackAsCreditBalance(); 
    }

現(xiàn)在我們可以從 UPIPayments 接口中刪除getCashBackAsCreditBalance ,AliPay也不需要實(shí)現(xiàn)getCashBackAsCreditBalance()這個(gè)它沒有的方法了。

D—依賴倒置原則

高層模塊不應(yīng)該依賴低層模塊,兩者都應(yīng)該依賴于抽象(接口)。抽象不應(yīng)該依賴于細(xì)節(jié)(具體實(shí)現(xiàn)),細(xì)節(jié)應(yīng)該取決于抽象。

這個(gè)原則我覺得也不是很好理解,所謂高層模塊和低層模塊的劃分,簡(jiǎn)單來說就是,在調(diào)用鏈上,調(diào)用者屬于高層,被調(diào)用者屬于低層。比如大家都知道的MVC模式,controller是調(diào)用service層接口這個(gè)抽象,而不是實(shí)現(xiàn)類。這也是我們經(jīng)常說的要面向接口編程,而非細(xì)節(jié)或者具體實(shí)現(xiàn),因?yàn)榻涌谝馕吨跫s,更加穩(wěn)定。

我們通過一個(gè)例子加深一下理解。

  • 借記卡
public class DebitCard { 
     public void doTransaction(int amount){ 
            System.out.println("tx done with DebitCard"); 
        } 
    }
  • 信用卡
public class CreditCard{ 
     public void doTransaction(int amount){ 
            System.out.println("tx done with CreditCard"); 
        } 
    }

現(xiàn)在用這兩張卡你去購(gòu)物中心購(gòu)買了一些訂單并決定使用信用卡支付

public class ShoppingMall {
     private DebitCard debitCard;
     public ShoppingMall(DebitCard debitCard) {
            this.debitCard = debitCard;
        }
     public void doPayment(Object order, int amount){              
            debitCard.doTransaction(amount); 
      }
     public static void main(String[] args) {
          DebitCard debitCard=new DebitCard();
          ShoppingMall shoppingMall=new ShoppingMall(debitCard);
          shoppingMall.doPayment("some order",5000);
        }
    }

上面的做法是一個(gè)錯(cuò)誤的方式,因?yàn)?nbsp;ShoppingMall 類與 DebitCard 緊密耦合。

現(xiàn)在你的借記卡余額不足,想使用信用卡,那么這是不可能的,因?yàn)?nbsp;ShoppingMall 與借記卡緊密結(jié)合。

當(dāng)然你也可以這樣做,從構(gòu)造函數(shù)中刪除借記卡并注入信用卡。但這不是一個(gè)好的方式,它不符合依賴倒置原則。

那該如何正確設(shè)計(jì)呢?

  • 定義依賴的抽象接口BankCard
public interface BankCard { 
      public void doTransaction(int amount); 
    }
  • 現(xiàn)在 DebitCard 和 CreditCard 都實(shí)現(xiàn)BankCard
public class CreditCard implements BankCard{
     public void doTransaction(int amount){            
            System.out.println("tx done with CreditCard");
        }
    }
public class DebitCard implements BankCard { 
     public void doTransaction(int amount){ 
      System.out.println("tx done with DebitCard"); 
        } 
    }
  • 現(xiàn)在重新設(shè)計(jì)購(gòu)物中心這個(gè)高級(jí)類,他也是去依賴這個(gè)抽象,而不是直接低級(jí)模塊的實(shí)現(xiàn)類
public class ShoppingMall {
     private BankCard bankCard;
     public ShoppingMall(BankCard bankCard) {
            this.bankCard = bankCard;
        }
     public void doPayment(Object order, int amount){
            bankCard.doTransaction(amount);
        }
     public static void main(String[] args) {
            BankCard bankCard=new CreditCard();
            ShoppingMall shoppingMall1=new ShoppingMall(bankCard);
            shoppingMall1.doPayment("do some order", 10000);
        }
    }

我們還可以拿 Tomcat這個(gè) Servlet 容器作為例子來解釋一下。

Tomcat 是運(yùn)行Java Web應(yīng)用程序的容器。我們編寫的 Web 應(yīng)用程序代碼只需要部署在Tomcat 容器下,便可以被 Tomcat 容器調(diào)用執(zhí)行。按照之前的劃分原則,Tomcat 就是高層模塊,我們編寫的 Web 應(yīng)用程序代碼就是低層模塊。Tomcat 和應(yīng)用程序代碼之間并沒有直接的依賴關(guān)系,兩者都依賴同一個(gè)“抽象”,也就是 Sevlet 規(guī)范。Servlet 規(guī)范不依賴具體的 Tomcat 容器和應(yīng)用程序的實(shí)現(xiàn)細(xì)節(jié),而 Tomcat 容器和應(yīng)用程序依賴 Servlet規(guī)范。

總結(jié)

本文總結(jié)了軟件編程中的黃金原則,KISS原則,DRY原則,SOLID原則。這些原則不僅僅適用于編程,也可以指導(dǎo)我們?cè)诩軜?gòu)設(shè)計(jì)上。雖然其中有些原則很抽象,但是大家多多實(shí)踐和思考,會(huì)體會(huì)到這些原則的精妙。

責(zé)任編輯:武曉燕 來源: JAVA旭陽
相關(guān)推薦

2022-06-15 09:54:51

PythonIDELinux

2022-06-16 16:08:00

Python初學(xué)者IDE

2015-10-12 11:00:23

編程學(xué)校工作

2019-04-08 15:48:45

程序員技能編程

2017-03-07 15:43:28

編程語言函數(shù)數(shù)據(jù)結(jié)構(gòu)

2018-08-22 10:27:35

編程人工智能機(jī)器人

2016-10-31 20:02:21

WordPress網(wǎng)站數(shù)據(jù)集大數(shù)據(jù)轉(zhuǎn)型戰(zhàn)略

2013-06-20 11:15:00

編程技能編程技巧如何選編程

2018-06-21 08:38:05

編程語言程序員代碼

2024-01-23 09:07:29

Unix哲學(xué)工具

2015-10-10 14:40:36

編程游戲

2018-07-18 08:48:11

2014-11-10 09:46:57

程序員

2020-06-01 08:35:36

編程語言JavaPython

2018-01-15 10:59:57

語言Java開發(fā)人員

2018-07-18 15:05:01

2011-11-02 09:57:28

程序員

2011-11-22 10:33:11

手機(jī)名詞

2012-09-10 09:43:21

編程編程學(xué)習(xí)編程錯(cuò)誤

2015-03-10 13:43:00

JavaSocket編程編程
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)