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=
開啟後是這樣的:
<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.什麼是類和類的物件? 類是一種資料結構,我們可以用它來定義物件,後者把資料值和行為特性融合在一起,類是現實世界的抽象的實體以程式設計形式出現。例項是這些物件的具體化。類是用來描述一類事物,類的物件指的是這一類事物的一個個體。例如:“人”就是一個類,而男人,女人,小孩等就是“人”這個類的例項物件;再比如“
一個人的武林:滲透測試常規思路分析(一)
寫在前面 滲透測試是門技術,也是一門藝術。 這門技術(藝術)一開始也不是每個人都會的,正所謂沒有人一出生就會走路,從不懂到入門到深諳,一步步慢慢來,每個人都是這樣;但是在這個過程中,思路無疑是最重要的,沒有做不到只有想不到,就跟咱們高中解題時有了思路就迎刃而解一樣,手裡拿著鏟子(技巧知識)但不是道從何挖起