1. 程式人生 > >android 專案練習:自己的詞典app——生詞本(一)

android 專案練習:自己的詞典app——生詞本(一)

前言:

自學android差不多兩個月了,由於本身對英語不感冒,而且記英語單詞總是很快忘記,因此學習的過程也是蠻累的,好多類和方法都不知道啥意思,還要去查詞典才知道。
還是延續我讀書時的記憶方法——每次遇到生詞就寫在筆記本上,下次在遇到就算不記得中文意思,也能記得寫過這個單詞,然後就是找筆記本就可以了。不過那,這種方法也有個問題——自己的字太醜,每次都是找了好久都沒找那個詞,其實明明在哪裡,只是快速掃看不到o(╯□╰)o。
後來,就想找一個背單詞的app,可以把我不認識的生詞新增到一個生詞本,可以快速瀏覽生詞本里的單詞,也可以僅僅針對生詞本里的詞出一些幫助記憶的練習題?又想,既然我在學android,為什麼不自己做一個那?於是就有了這個專案練習!

專案實現:

我在網上找到了一個前輩分享的類似的app編寫過程,發現其中很多內容都是我會的,於是我就參考著自己動手寫起來。
由於這個專案不是完成後才開始寫這篇部落格,是我邊實踐邊寫的,因此整體思路是根據我的寫程式碼進度來的,在寫這裡的時候剛實現了查單詞的介面和完整功能。

查詞介面:

先來看下這個介面的功能和實現思路:
(一)肯定是要能查單詞
簡單的實現思路就是使用現有詞典的API介面,我採用的是金山詞霸的API介面,地址:http://open.iciba.com/。優點是這個介面會返回發音MP3的http地址。
查詞介面:http://dict-co.iciba.com/api/dictionary.php?w=go&key=

** 這裡的key是你自己申請的金山詞霸開放平臺的API key。
開啟後是這樣的:

<dict num="219" id="219" name="219">
<key>go</key>
<ps>gəʊ</ps>
<pron>http://res.iciba.com/resource/amp3/0/0/34/d1/34d1f91fb2e514b8576fab1a75a89a6b.mp3</pron>
<ps>goʊ</ps>
<pron>http://res.iciba.com/resource/amp3/1/0/34/d1/34d1f91fb2e514b8576fab1a75a89a6b.mp3</pron
>
<pos>vi.</pos><acceptation>走;離開;去做;進行; </acceptation> <pos>vt.</pos> <acceptation>變得;發出…聲音;成為;處於…狀態;</acceptation> <pos>n.</pos> <acceptation>輪到的順序;精力;幹勁;嘗試;</acceptation> <sent><orig> Go is an irregular verb. </orig><trans> go是個不規則動詞. </trans></sent><sent><orig> Kyong - go means a warning or half - point deduction and gam - jeom means a one - point deduction. </orig><trans> Kyoug -go是指一次警告或被扣減半分, gam -jeom是指被扣減1分. </trans></sent><sent><orig> From the get - go means from the beginning. </orig><trans> 原來fromtheget-go 就是一開始的時候. </trans></sent><sent><orig> With the reduction of SRWC, GO activity decreased mild water stress and increased water stress. </orig><trans> 隨著土壤相對含水量的下降,GO酶括性在土壤水分含量下降時首先降低,以後又逐漸上升. </trans></sent><sent><orig> We proved orthocompactness and weakly suborthocompactness are equivalent for all subspaces of product of two GO - space. </orig><trans> 證明了GO - 空間子空間的正交緊性和弱子正交緊性是等價的. </trans></sent></dict>

因此這裡就要用到Http網路訪問和XML解析。為避免重複訪問網路,我們可以將解析出來單詞的資料儲存在本地,這樣下次在查到該詞是可以直接從本地讀取了,同樣的我們可以直接把MP3檔案也儲存本地。
分析完成後開始動手,首先按功能分模組,這方面由於我是新手,就是按照自己看的清晰的方式來,新建一個util包,這裡都是放一些工具類。然後新建一個類HttpUtil,通過HttpURLConnection實現網路訪問功能:

public class HttpUtil {
    /**
     * 在新執行緒中傳送網路請求
     *
     * @param address  網路地址
     * @param listener HttpCallBackListener介面的實現類;
     *                 onFinish方法為訪問成功後的回撥方法;
     *                 onError為訪問不成功時的回撥方法
     */
    public static void sentHttpRequest(final String address, final HttpCallBackListener listener) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                HttpURLConnection connection = null;
                try {
                    URL url = new URL(address);
                    connection = (HttpURLConnection) url.openConnection();
                    connection.setRequestMethod("GET");
                    connection.setConnectTimeout(8000);
                    connection.setReadTimeout(8000);
                    InputStream inputStream = connection.getInputStream();
                    if (listener != null) {
                        listener.onFinish(inputStream);
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                    if (listener != null) {
                        listener.onError();
                    }
                } finally {
                    if (connection != null) {
                        connection.disconnect();
                    }
                }
            }
        }).start();
    }
}

android網路訪問不能在UI執行緒中進行,避免阻塞,因此,這裡我直接在新執行緒實現,根據目的需要,完成網路請求後要對返回的XML檔案進行解析,因此方法第二引數傳入HttpCallBackListener介面的實現類,分別對應onFinish方法為訪問成功後的回撥方法,onError為訪問不成功時的回撥方法。

接下來是XML解析了,我採用的是SAX解析方法。
我們先分析下XML檔案,看看有哪些節點:
key:單詞本身; ps:第一個是英音音標,第二個是美音音標; pron第一個是英音的MP3地址,第二個是美音的;pos 詞性; acception 詞義;sent 例句; orig例句英語;trans例句中文翻譯。
這個api介面也可以查中文,只需要在待查的詞前面加上一個下劃線 _ 即可,如 :_你好。

<dict num="219" id="219" name="219">
<key>你好</key>
<fy>Hello</fy>
<sent>
<orig>Hello! Hello! Hello! Hello! Hel - lo!</orig>
<trans>你好! 你好! 你好! 你好! 你好!</trans>
</sent>
<sent>
<orig>Hello! Hello! Hello! Hello ! I'm glad to meet you.</orig>
<trans>你好! 你好! 你好! 你好! 見到你很高興.</trans>
</sent>
<sent>
<orig>Hello Marie. Hello Berlioz. Hello Toulouse.</orig>
<trans>你好瑪麗, 你好柏里歐, 你好圖魯茲.</trans>
</sent>
<sent>
<orig>
B Hi Gao. How are you doing? It's good to meet you.
</orig>
<trans>B你好,高. 你好 嗎 ?很高興認識你.</trans>
</sent>
<sent>
<orig>
Grant: Hi , Tess. Hi , Jenna. Are you doing your homework?
</orig>
<trans>格蘭特: 你好! 苔絲. 你好! 詹娜. 你們在做家庭作業 嗎 ?</trans>
</sent>
</dict>

可以看到查中文的話會多一個屬性:fy 即中文的英文翻譯,要一起考慮進去。

因為要把查到單詞的內容儲存本地,我們就要建一個Words類用來管理xml解析出來的內容,新建一個model包,在其下新建一個Words類:

public class Words {
    //中英文標記
    private boolean isChinese;
    //要翻譯的單詞,可以是中文;
    private String key;
    //key為中文時的翻譯
    private String fy;
    //英音發音
    private String psE;
    //英音發音的mp3地址
    private String pronE;
    //美音發音
    private String psA;
    //美音發音的mp3地址
    private String pronA;
    //單詞的詞性與詞義
    private String posAcceptation;
    //例句
    private String sent;

    public Words() {
        this.key = "";
        this.fy = "";
        this.psE = "";
        this.pronE = "";
        this.psA = "";
        this.pronA = "";
        this.posAcceptation = "";
        this.sent = "";
        this.isChinese = false;
    }

    public Words(boolean isChinese, String key, String fy, String psE,
                 String pronE, String psA, String pronA, String posAcceptation, String sent) {
        this.isChinese = isChinese;
        this.key = key;
        this.fy = fy;
        this.psE = psE;
        this.pronE = pronE;
        this.psA = psA;
        this.pronA = pronA;
        this.posAcceptation = posAcceptation;
        this.sent = sent;
    }

    public boolean getIsChinese() {
        return isChinese;
    }

    public void setIsChinese(boolean isChinese) {
        this.isChinese = isChinese;
    }

    public String getKey() {
        return key;
    }

    public void setKey(String key) {
        this.key = key;
    }

    public String getFy() {
        return fy;
    }

    public void setFy(String fy) {
        this.fy = fy;
    }

    public String getPsE() {
        return psE;
    }

    public void setPsE(String psE) {
        this.psE = psE;
    }

    public String getPronE() {
        return pronE;
    }

    public void setPronE(String pronE) {
        this.pronE = pronE;
    }

    public String getPsA() {
        return psA;
    }

    public void setPsA(String psA) {
        this.psA = psA;
    }

    public String getPronA() {
        return pronA;
    }

    public void setPronA(String pronA) {
        this.pronA = pronA;
    }

    public String getPosAcceptation() {
        return posAcceptation;
    }

    public void setPosAcceptation(String posAcceptation) {
        this.posAcceptation = posAcceptation;
    }

    public String getSent() {
        return sent;
    }

    public void setSent(String sent) {
        this.sent = sent;
    }
}

其中只包含一些成員變數,對應我們需要的內容,還有各自的get()和set()方法。

接著在util包下新建一個WordsHandler類繼承自DefaultHandler,這個類中解析XML內容成一個words物件:

public class WordsHandler extends DefaultHandler {
    //記錄當前節點
    private String nodeName;
    private Words words;
    //單詞的詞性與詞義
    private StringBuilder posAcceptation;
    //例句
    private StringBuilder sent;

    /**
     * 獲取解析後的words物件
     */
    public Words getWords() {
        return words;
    }

    //開始解析XML時呼叫
    @Override
    public void startDocument() throws SAXException {
        //初始化
        words = new Words();
        posAcceptation = new StringBuilder();
        sent = new StringBuilder();
    }

    //結束解析XML時呼叫
    @Override
    public void endDocument() throws SAXException {
        //將所有解析出來的內容賦予words
        words.setPosAcceptation(posAcceptation.toString().trim());
        words.setSent(sent.toString().trim());
    }

    //開始解析節點時呼叫
    @Override
    public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
        nodeName = localName;
    }

    //結束解析節點時呼叫
    @Override
    public void endElement(String uri, String localName, String qName) throws SAXException {
        //在讀完整個節點後換行
        if ("acceptation".equals(localName)) {
            posAcceptation.append("\n");
        } else if ("orig".equals(localName)) {
            sent.append("\n");
        } else if ("trans".equals(localName)) {
            sent.append("\n");
            sent.append("\n");
        }
    }

    //獲取節點中內容時呼叫
    @Override
    public void characters(char[] ch, int start, int length) throws SAXException {
        String a = new String(ch, start, length);
        //去掉文字中原有的換行
        for (int i = start; i < start + length; i++) {
            if (ch[i] == '\n')
                return;
        }
        //將節點的內容存入Words物件對應的屬性中
        if ("key".equals(nodeName)) {
            words.setKey(a.trim());
        } else if ("ps".equals(nodeName)) {
            if (words.getPsE().length() <= 0) {
                words.setPsE(a.trim());
            } else {
                words.setPsA(a.trim());
            }
        } else if ("pron".equals(nodeName)) {
            if (words.getPronE().length() <= 0) {
                words.setPronE(a.trim());
            } else {
                words.setPronA(a.trim());
            }
        } else if ("pos".equals(nodeName)) {
            posAcceptation.append(a);
        } else if ("acceptation".equals(nodeName)) {
            posAcceptation.append(a);
        } else if ("orig".equals(nodeName)) {
            sent.append(a);
        } else if ("trans".equals(nodeName)) {
            sent.append(a);
        } else if ("fy".equals(nodeName)) {
            words.setFy(a);
            words.setIsChinese(true);
        }
    }
}

在這裡,如何對解析出來的文字重新排版換行這個問題卡了我好幾個小時,最後終於找到解決方法,我在昨天的一篇部落格中有分享:SAX解析中換行問題解決

接著,同樣是util包下新建一個ParseXML類,作為解析XML的工具類:

public class ParseXML {
    /**
     * 使用SAX解析XML的方法
     */
    public static void parse(DefaultHandler handler, InputStream inputStream) {
        try {
            InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");
            BufferedReader reader = new BufferedReader(inputStreamReader);
            SAXParserFactory factory = SAXParserFactory.newInstance();
            XMLReader xmlReader = factory.newSAXParser().getXMLReader();
            xmlReader.setContentHandler(handler);
            xmlReader.parse(new InputSource(reader));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

這裡應該沒什麼問題,呼叫SAXParserFactory.newInstance()獲得SAXParserFactory的例項,再呼叫newSAXParser().getXMLReader()獲得XMLPreader例項,setContentHandler()傳入自定義的解析類WordsHandler,最後呼叫parse()方法,傳入inputStream包裝成的BufferReader開始解析。

解析後我們可以呼叫WordsHandler的getWords獲得所查單詞對應的words物件,接下來可以用SQLite儲存在本地。新建一個db包,在db包中新建一個WordsSQLiteOpenHelper類繼承自SQLiteOpenHelper,在這個類中新建words庫:

public class WordsSQLiteOpenHelper extends SQLiteOpenHelper {
    /**建表語句*/
    private String CREATE_WORDS = "create table Words(id Integer primary key autoincrement," +
            "isChinese text,key text,fy text,psE text,pronE text,psA text,pronA text,posAcceptation text,sent text)";

    public WordsSQLiteOpenHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {
        super(context, name, factory, version);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL(CREATE_WORDS);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

    }
}

目前沒有升級資料的需要,因此僅寫了建立資料庫的程式碼。

接下來是一個大類WordsAction,我把它放在util包下,這個類裡包含了大部分查詞介面所用到的方法,包括:儲存words到資料庫、獲取address地址、向資料庫中查詢words、儲存發音mp3檔案、播放發音MP3。
發音MP3我們後面再看,先來看資料庫這塊:

public class WordsAction {
    /**
     * 本類的例項
     */
    private static WordsAction wordsAction;
    /**
     * Words的表名
     */
    private final String TABLE_WORDS = "Words";
    /**
     * 資料庫工具,用於增、刪、該、查
     */
    private SQLiteDatabase db;
    private MediaPlayer player = null;

    /**
     * 私有化的構造器
     */
    private WordsAction(Context context) {
        WordsSQLiteOpenHelper helper = new WordsSQLiteOpenHelper(context, TABLE_WORDS, null, 1);
        db = helper.getWritableDatabase();
    }

    /**
     * 單例類WordsAction獲取例項方法
     *
     * @param context 上下文
     */
    public static WordsAction getInstance(Context context) {
        //雙重效驗鎖,提高效能
        if (wordsAction == null) {
            synchronized (WordsAction.class) {
                if (wordsAction == null) {
                    wordsAction = new WordsAction(context);
                }
            }
        }
        return wordsAction;
    }

    /**
     * 向資料庫中儲存新的Words物件
     * 會先對word進行判斷,為有效值時才會儲存
     *
     * @param words 單詞類的例項
     */
    public boolean saveWords(Words words) {
        //判斷是否是有效物件,即有資料
        if (words.getSent().length() > 0) {
            ContentValues values = new ContentValues();
            values.put("isChinese", "" + words.getIsChinese());
            values.put("key", words.getKey());
            values.put("fy", words.getFy());
            values.put("psE", words.getPsE());
            values.put("pronE", words.getPronE());
            values.put("psA", words.getPsA());
            values.put("pronA", words.getPronA());
            values.put("posAcceptation", words.getPosAcceptation());
            values.put("sent", words.getSent());
            db.insert(TABLE_WORDS, null, values);
            values.clear();
            return true;
        }
        return false;
    }

    /**
     * 從資料庫中查詢查詢的words
     *
     * @param key 查詢的值
     * @return words 若返回words的key為空,則說明資料庫中沒有該詞
     */
    public Words getWordsFromSQLite(String key) {
        Words words = new Words();
        Cursor cursor = db.query(TABLE_WORDS, null, "key=?", new String[]{key}, null, null, null);
        //資料庫中有
        if (cursor.getCount() > 0) {
            Log.d("測試", "資料庫中有");
            if (cursor.moveToFirst()) {
                do {
                    String isChinese = cursor.getString(cursor.getColumnIndex("isChinese"));
                    if ("true".equals(isChinese)) {
                        words.setIsChinese(true);
                    } else if ("false".equals(isChinese)) {
                        words.setIsChinese(false);
                    }
                    words.setKey(cursor.getString(cursor.getColumnIndex("key")));
                    words.setFy(cursor.getString(cursor.getColumnIndex("fy")));
                    words.setPsE(cursor.getString(cursor.getColumnIndex("psE")));
                    words.setPronE(cursor.getString(cursor.getColumnIndex("pronE")));
                    words.setPsA(cursor.getString(cursor.getColumnIndex("psA")));
                    words.setPronA(cursor.getString(cursor.getColumnIndex("pronA")));
                    words.setPosAcceptation(cursor.getString(cursor.getColumnIndex("posAcceptation")));
                    words.setSent(cursor.getString(cursor.getColumnIndex("sent")));
                } while (cursor.moveToNext());
            }
            cursor.close();
        } else {
            Log.d("測試", "資料庫中沒有");
            cursor.close();
        }

        return words;
    }

這是一個單例類,我採用了雙重鎖的方式,提高效能。
方法說明都在程式碼中有。
這個類中還有一個方法,用於獲取Http訪問的地址:

/**
     * 獲取網路查詢單詞的對應地址
     *
     * @param key 要查詢的單詞
     * @return address 所查單詞對應的http地址
     */
    public String getAddressForWords(final String key) {
        String address_p1 = "http://dict-co.iciba.com/api/dictionary.php?w=";
        String address_p2 = "";
        String address_p3 = "&key=E568F04171398072F7EC5D8B4A6CBDB4";
        if (isChinese(key)) {
            try {
                //此處非常重要!對中文的key進行重新編碼,生成正確的網址
                address_p2 = "_" + URLEncoder.encode(key, "UTF-8");
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
        } else {
            address_p2 = key;
        }
        return address_p1 + address_p2 + address_p3;

    }

看到程式碼中“此處非常重要!”的提示那段沒,這也是一個卡了我幾個小時的問題。
原本我是這樣寫的:

address_p2 = "_"+key;

問題是在查詢中文的時候得不到任何資料,我還列印了訪問的網址,Log出來的地址,我複製到ie瀏覽器返回有資料的,沒有問題,又檢查了WordsHandler,也沒有問題。想了好久才意識到我在瀏覽器位址列輸入的中文會自動轉碼,而用HttpURLConnection訪問時卻不會自動轉碼。
所以在這裡要手動的對中文進行重新編碼。if裡的isChinese()方法可以通過Unicode編碼完美的判斷中文漢字和符號

/**
     * 判斷是否是中文
     *
     * @param strName String型別的字串
     */
    public static boolean isChinese(String strName) {
        char[] ch = strName.toCharArray();
        for (int i = 0; i < ch.length; i++) {
            char c = ch[i];
            if (isChinese(c)) {
                return true;
            }
        }
        return false;
    }

    /**
     * 根據Unicode編碼完美的判斷中文漢字和符號
     *
     * @param c char型別的字串
     */
    private static boolean isChinese(char c) {
        Character.UnicodeBlock ub = Character.UnicodeBlock.of(c);
        if (ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS
                || ub == Character.UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS
                || ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A
                || ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_B
                || ub == Character.UnicodeBlock.CJK_SYMBOLS_AND_PUNCTUATION
                || ub == Character.UnicodeBlock.HALFWIDTH_AND_FULLWIDTH_FORMS
                || ub == Character.UnicodeBlock.GENERAL_PUNCTUATION) {
            return true;
        }
        return false;
    }

到這裡,基本的查詞功能就能實現了!
其實我寫這些程式碼的時候,會簡單寫一個Activity,裡面有TextView,然後呼叫上述方法,測試我寫的程式碼是否正確。

HttpUtil.sentHttpRequest(address, new HttpCallBackListener() {
                @Override
                public void onFinish(InputStream inputStream) {
                    WordsHandler wordsHandler = new WordsHandler();
                    ParseXML.parse(wordsHandler, inputStream);
                    words = wordsHandler.getWords();
                    wordsAction.saveWords(words);
                    wordsAction.saveWordsMP3(words);
                    }
                @Override
                public void onError() {

                }
            });
 }

這就是測試的時候簡單呼叫方法,看看能不能實現功能。
今天就到這裡,明天繼續後續內容!

相關推薦

android 專案練習自己詞典app——生詞

前言: 自學android差不多兩個月了,由於本身對英語不感冒,而且記英語單詞總是很快忘記,因此學習的過程也是蠻累的,好多類和方法都不知道啥意思,還要去查詞典才知道。 還是延續我讀書時的記憶方法——每次遇到生詞就寫在筆記本上,下次在遇到就算不記得中文意思,也

Android之測量APP效能概覽

如果應用程式響應緩慢、顯示不穩定的動畫、凍結、崩潰或消耗大量電力,則認為其效能很差。為了避免這些效能問題,使用本頁中列出的分析工具來識別應用程式在哪裡低效使用資源,例如CPU、記憶體、圖形、網路和裝置電池。 Note: While profiling an app, you shoul

分享知識-快樂自己SpringBoot整合熱部署配置

<build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> &l

Vue專案實戰優化已有元件優化系列

一_原有元件效果 其中,核取方塊為一個元件,根據資料庫中的值,進行是否勾選,並且核取方塊只能是禁用的 二_原有元件程式碼 <template> <input v-if="gearboxtype === 'A'" checked type="

步一個腳印】Tomcat+MySQL為自己APP打造伺服器1伺服器環境搭建

做 Android 開發一年多了,雖然不敢說有多精通,但也相對熟悉。做久了就會發現 Android 在行外人眼中是多麼高深(包括 IOS 也一樣),但是我們自己知道其實 Android 和 Web 前

Android 端天氣預報APP的實現天氣顯示介面之上下滑動

最近參加了一個小比賽,選了天氣預報APP這個題目,最初選擇它,是想練練網路資料獲取和資料解析方面的知識,後來發現倒是學到了不少介面的東西。下面我來一步步講解一下我是怎麼完成的吧~ 首先,天氣預報最直觀的部分應該就是天氣顯示介面了,這裡,我想做成可以有上下滑動的

Android Studio開發APP常用方法

選擇選單,彈出子選單,點選選項跳轉到新Activity SubMenu prog = menu.addSubMenu("啟動程式"); prog.setHeaderTitle("選擇要啟動的程式"); MenuItem

create-react-app原始碼解析,npm run start如何讓專案跑起來

    小編花了點時間,大致弄懂npm run start如何執行專案的原理了,現在給大家分享下心得!npm run start是通過node跑js檔案,從而專案得以執行,小編通過npm run eject拿到了所有配置,然後通過解析原始碼,明白瞭如果通過webpack等讓專

步一個腳印】Tomcat+MySQL為自己APP打造伺服器4完結篇

        在這個系列的前幾篇文章中,從最初簡單的伺服器環境搭建、MySQL資料庫的安裝、Servlet 的原理及使用、資料庫的連線及CURD操作、Android和伺服器GET/POST資料互動,到最後JSon格式報文的使用,我們已經將這個過程完整的走完一遍,但是其中

Android之路回撥的入門理解CallBack

這裡我會用最簡單的例子來介紹Android中的回撥。 例子:我會定義一個輸入框,如果輸入的數字大於10,我會輸出“大於10”,否則輸出“小於或者等於10”。看具體的程式碼怎麼用回撥來實現這個功能。

讓我們把KBEngine玩壞吧!如何定制我們自己的C++函數

data ase erro glob alt ins sin 程序 all 為什麽不更新kbe warring的代碼解讀了,因為在我看來那個demo講完了實體就沒東西可講了,如果專心的看官方文檔和PPT的話demo的代碼後面沒任何難點了已經,單純的復制黏貼代碼實在太過無聊。

【問底】夏俊深入站點服務端技術——站點並發的問題

而是 思路 臨時 系統負載 表現 json article 不能 情況 摘要:本文來自擁有十年IT從業經驗、擅長站點架構設計、Web前端技術以及Java企業級開發的夏俊,此文也是《關於大型站點技術演進的思考》系列文章的最新出爐內容。首發於CSDN,各位技術人員不

java枚舉即對java枚舉中的例子進行拓展

枚舉/* 知識點:枚舉 枚舉是從java5開始提供的一種新的數據類型,是一個特殊的類,就是多個常量對象的集合 定義格式: [修飾符] enum 枚舉類名 { 常量A, 常量B, 常量C; } */ //定義枚舉 enum Weekday { Mond

信息收集篇玩轉信息收集

sgk 理解 自己 htm 分類 style col china 推薦 都知道,信息收集這個東西在各行各業都能用到,在偵探業,現場的勘察以及細節信息需要了解;IT/網絡安全/黑客這方面也更是如此,要談信息收集這個東西說起來覆蓋的業界可謂是非常的廣泛,今天我就主要是在計算

Python學習14.Python面向對象

針對 序列 內部 根據 輸出結果 lane p s person ane 一、面向對象簡介   Python設計之初,就是一門面向對象的語言,在Python中一切皆對象,而且在Python中創建一個對象也很簡單,今天我們就來學習一下Python的面向對象的知識。 二、兩

演算法基礎資料型別,基礎結構

基礎概念 一、資料型別 基本資料型別一般長度 (注意以下的 long long 實際上指的是 unsigned long long 型別) (long long 型別數值範圍是-9223372036854775808 ~ 9223372036854775807)差不多範圍是

Linux進階自動化運維之ANSIBLE

運維自動化發展歷程 1、本地部署(On-Premiss) 部署硬體+軟體+作業系統+環境+服務 2、基礎設施即服務(Iaas) 相當於只准備硬體 3、平臺即服務(Paas) 相當於只准備服務 4、軟體即服務(SaaS) 直接使用 企業實際應用場景分析 1、Dev開發環境 使用者:程式

開發工具全棧開發工具彙總——彙總

本文中將各類開發過程中需要使用的工具進行彙總,後面會有詳細介紹 一、前端 AxureRP:原型圖設計工具 JetBrains WebStorm:網頁編輯工具 EditPlus:網頁編輯工具 HBuilder:輕量級網頁編輯工具 ace_admin:ac

python學習之【第十七篇】Python中的面向物件

1.什麼是類和類的物件? 類是一種資料結構,我們可以用它來定義物件,後者把資料值和行為特性融合在一起,類是現實世界的抽象的實體以程式設計形式出現。例項是這些物件的具體化。類是用來描述一類事物,類的物件指的是這一類事物的一個個體。例如:“人”就是一個類,而男人,女人,小孩等就是“人”這個類的例項物件;再比如“

個人的武林滲透測試常規思路分析

寫在前面 滲透測試是門技術,也是一門藝術。 這門技術(藝術)一開始也不是每個人都會的,正所謂沒有人一出生就會走路,從不懂到入門到深諳,一步步慢慢來,每個人都是這樣;但是在這個過程中,思路無疑是最重要的,沒有做不到只有想不到,就跟咱們高中解題時有了思路就迎刃而解一樣,手裡拿著鏟子(技巧知識)但不是道從何挖起