23篇大數據系列(一)java基礎知識全集(2萬字干貨,建議收藏)
大數據系列爽文,從技術能力、業務基礎、分析思維三大板塊來呈現,你將收獲:
??提升自信心,自如應對面試,順利拿到實習崗位或offer;
??掌握大數據的基礎知識,與其他同事溝通無障礙;
??具備一定的項目實戰能力,對于大數據工作直接上手;
有問題的小伙伴歡迎csdn主頁。評論、、是對我最大的支持!!!
大數據工程師知識體系:
大數據時代已經到來
最近幾十年,高速發展的互聯網,滲透進了我們生活的方方面面,整個人類社會都已經被互聯網連接為一體。身處互聯網之中,我們無時無刻不在產生大量數據,如瀏覽商品的記錄、成交訂單記錄、觀看視頻的數據、瀏覽過的網頁、搜索過的關鍵詞、點擊過的廣告、朋友圈的自拍和狀態等。這些數據,既是我們行為留下的痕跡,同時也是描述我們自身最佳的證據。
2014年3月,馬云曾經在北京的一次演講中說道:“人類正從IT時代走向DT時代”。7年過去了,正如馬云預想的那樣,大數據時代已經到來了。
大數據工程師的工作內容是什么?
而大數據時代,有一個關鍵性的崗位不得不提,那就是大數據工程師。想必大家也會好奇,大數據工程師,日常是做什么的呢?
基于用戶的各方面數據,建立對用戶的全方位理解,構建每個特定用戶的畫像,以便針對每個個體完成精細化運營。
大數據工程師必備技能
那么,問題來了,如果想成為一名大數據工程師,勝任上述工作內容,需要具備什么樣的條件?擁有什么樣的知識呢?
分類
子分類
技能
描述
技
術
能
力
編程基礎
Java基礎
大數據生態必備的java基礎
Scala基礎
Spark相關生態的必備技能
SQL基礎
數據分析師的通用語言
SQL進階
完成復雜分析的必備技能
大數據框架
HDFS&YARN
大數據生態的底層基石
Hive基礎
大數據分析的常用工具
Hive進階
大數據分析師的高級裝備
Spark基礎
排查問題必備的底層運行原理
Spark SQL
應對復雜任務的利刃
工具
Hue&Zeppelin
通用的探索分析工具
Azkaban
作業管理調度平臺
Tableau
數據可視化平臺
業務基礎
數據收集
數據是如何收集到的?
ETL工程
怎么清洗、處理和轉化數據?
數據倉庫基礎
如何完成面向分析的數據建模?
元數據中心
如何做好數據治理?
分析思維
數據分析思維方法論
怎么去分析一個具體問題?
排查問題思維
如何高效排查數據問題?
指標體系
怎么讓數據成體系化?
四、為啥以Java開場
作為穩居編程語言排行榜前三的java語言,具有非常多的優秀特性,同時擁有龐大的類庫生態和大量的開發者。Java語言在大數據生態體系中地位也是無可撼動,目前流行的大數據生態組件,很多都是用Java語言或基于JVM的語言(如Scala)開發的。
因此,要想玩轉大數據,或多或少需要對Java有所了解。
五、本文的講解思路
第1部分:基本概念及特性
這部分會花較大篇幅給大家介紹java中的幾個很重要的基礎概念,面向對象、類、對象、封裝、繼承、多態和泛型,一來給后續講解中有示例代碼的地方打個基礎,二來讓之前沒怎么了解過Java的小伙伴對Java有個初步認識。
第2部分:初始化過程
主要講述類(子類和父類)中各成員變量的初始化順序。
第3部分:常見的集合及方法
主要簡述Collection和Map兩個接口以及各集合的常用方法。
第4部分:常用的字符串處理方法
這部分會對每種方法進行詳細說明并通過示例幫助小伙伴們加深理解。
第5部分:日期處理方法
主要通過示例代碼對最常用到的日期處理類java.util.Date、java.util.Calendar、java.text.SimpleDateFormat進行介紹。
第6部分:json的解析與操作
重點介紹了兩點,一是java變量和json格式之間的相互轉化,二是json對象與字符串的相互轉化。
第7部分:正則表達式
講述了正則表達式的概念、作用、基本規則,并給出了示例代碼。
第8部分:異常處理
此處根據實際經驗給大家總結下異常處理常遇到的幾種問題。
第9部分:JDBC
主要是通過示例代碼給出java連接數據庫的操作步驟。
1、基本概念及特性
Java 是面向對象的高級編程語言,所謂對象就是真實世界中的實體,對象與實體是一一對應的,也就是說現實世界中每一個實體都是一個對象,它是一種具體的概念,正所謂萬物皆對象。
對象有以下特點:
咚咚咚,敲黑板!!!
以上圖例中,第四個特點說到:對象都是某個類別的實例。借此,我們要引出Java中另外兩個非常重要的概念,那就是類和對象。
類:
對某類事物的普遍一致性特征、功能的抽象、描述和封裝。
對象:
使用 new 關鍵字或反射技術創建的某個類的實例。同一個類的所有對象,都具有相同的基礎屬性(比如人的年齡、性別)和行為(比如人的吃飯、睡覺),但是每個對象的具體屬性值和行為表現會具有自己獨特的個性。
舉例:
老師是java中的一個類,一位24歲的、性別女、名字叫馬冬梅的老師就是老師這個類別里對應的一個具體對象。
我們來看一下創建一個具體的java類和對象的代碼框架是什么樣子的:
public class Teacher { //屬性:姓名、所教課程名、性別、年齡 Stringname; StringteachClass; Stringsex; int age; publicvoid setName(String name) { this.name= name; } publicvoid setTeachClass(String teachClass) { this.teachClass = teachClass; } publicvoid setSex(String sex) { this.sex = sex; } publicvoid setAge(int age) { this.age = age; } publicTeacher() { } //方法:獲得老師所教授的課程名 publicvoid getClass(String name, String teachClass) { System.out.println(name + "老師所教授的課程是"+ teachClass); } }
//創建老師類的一個具體對象public class Main { public static void main(String[] args) { //new一個具體對象teacherA TeacherteacherA = new Teacher(); //具體對象的屬性值 teacherA.setName("馬冬梅"); teacherA.setSex("女"); teacherA.setAge(22); //具體對象的行為:馬冬梅老師教授的課程是生物 teacherA.getClass(teacherA.getName(), "生物"); }}
ok,通過以上示例,希望大家對于java的類和對象有了一個初步的概念和了解。
那么,為什么這種所謂的面向對象的編程理念會得到大家的接納和推崇呢?
因為面向對象程序設計有以下優點:
1. 可重用:它是面向對象軟件開發的核心思路,提高了開發效率。面向對象程序設計的抽象、繼承、封裝和多態四大特點都圍繞這個核心。
2. 可擴展:它使面向對象設計脫離了基于模塊的設計,便于軟件的修改。
接下來就針對Java的繼承、封裝、多態和泛型?4 個特性進行講解,來了解一下它們是如何實現代碼重用和擴展的。
1.繼承
如同現實生活中的子女繼承父母的遺產一樣,在java中繼承指的是子類繼承父類的屬性和方法。見以下實例:
大家有沒有發現語文老師類和數學老師類里的屬性和方法大部分是相同的,以上說到java面向對象編程的優點是可重用性和可擴展性,如何通過繼承來實現重用和擴展呢?
那就是通過再提煉一個上層父類--老師類來實現,語文老師類和數學老師類再作為子類對其繼承使用。
如下:
采用這種向上抽象方式,是為了將多個類的通用屬性和方法提取出來,放在它們的父類中,避免同樣的代碼寫多份(即為了實現復用),在子類中只需要定義自己獨有的屬性和方法,以繼承的方式在父類中獲取通用屬性和方法即可。
//繼承代碼結構public class Chinese extends Teacher{ //定義自己獨有的屬性:工作內容 Stringcontent; //定義自己獨有的方法 publicvoid writeModels(String name, string content) { System.out.println(name + "老師主要工作內容是"+ content); }}
特別說明:繼承只能是單繼承,即一個子類只能繼承一個父類。
2.封裝
封裝的目的在于保護信息。
Java 提供了私有和公有的訪問模式,類的公有接口代表外部的用戶應該知道或可以知道的所有信息,私有的方法數據只能通過該類的成員代碼來訪問,這就可以確保不會發生不希望發生的事情。
封裝主要優點如下:
那么,怎么理解封裝實現了復用和擴展呢?
讀者可以理解為所謂封裝其實只是將屬性和功能封裝成類,并對類里的成員定義了不同的訪問權限,最終還是通過與繼承機制的結合實現的代碼復用和擴展。
3.多態
所謂多態,就是指程序中定義的引用變量所指向的具體類型和通過該引用變量發出的方法調用在編程時并不確定,而是在程序運行期間才確定,即一個引用變量到底會指向哪個類的實例對象,該引用變量發出的方法調用的到底是哪個類中實現的方法,必須在由程序運行期間才能決定。即不修改程序代碼就可以讓程序有多個運行狀態可以選擇,這就是多態性。
上文是根據為啥這個特性叫做多態性的角度給大家解釋了一下,如果從實際運用中最終看到的實際效果這個方面來總結,可以理解為,多態是同一個行為具有多個不同表現形式或形態的能力。
舉個形象的例子:
現實中,比如我們按下 F1 鍵這個動作: 如果當前在 Flash 界面下彈出的就是 AS 3 的幫助文檔;如果當前在 Word 下彈出的就是 Word 幫助;在 Windows 下彈出的就是 Windows 幫助和支持。
同一個事件發生在不同的對象上會產生不同的結果,可見,多態實現了很好的擴展性。
4.泛型
泛型的本質是參數化類型,也就是說所操作的數據類型被指定為一個參數。
public class GenericTest{ // 泛型方法 printArray publicstatic < E > void printArray( E[] inputArray ) { // 輸出數組元素 for( E element : inputArray ){ System.out.printf( "%s ", element ); } System.out.println(); } publicstatic void main( String args[] ) { // 創建不同類型數組: Integer, Double 和 Character Integer[] intArray = { 1, 2, 3, 4, 5 }; Double[]doubleArray = { 1.1, 2.2, 3.3, 4.4 }; Character[] charArray = { 'H', 'E', 'L', 'L', 'O' }; System.out.println( "整型數組元素為:" ); printArray( intArray ); // 傳遞一個整型數組 System.out.println( "\n雙精度型數組元素為:" ); printArray(doubleArray ); // 傳遞一個雙精度型數組 System.out.println( "\n字符型數組元素為:" ); printArray( charArray ); // 傳遞一個字符型數組 } }
結果如下:
整型數組元素為:1 2 3 4 5 雙精度型數組元素為:1.1 2.2 3.3 4.4 字符型數組元素為:H E L L O
同一個方法,允許傳入不同的參數類型,得到不同的運行結果,以此實現了代碼的復用和擴展。
2、初始化過程
雖然本文講解的絕大部分內容偏向應用,但對于初始化過程這種看上去有點涉及到底層原理的內容,考慮再三,還是要稍微提及一下,那是因為在實際工作中,經常發生因為對整個初始化過程的機制不了解而寫出不合理代碼,從而產生bug的現象。
本段會針對類的各成員的初始化順序重點強調一下,這也是犯錯最多且唯一我們能控制的地方,希望大家務必對此要有所了解。
話不多說,上實例:
class Father{ static{ System.out.println("父類靜態代碼塊初始化" ); } { System.out.println("父類代碼塊初始化" ); } private static void s=print(); public static void print() { System.out.println("父類靜態方法" ); } public Father() { System.out.println("父類無參構造函數初始化完成" ); show(); } public void show() { System.out.println("父類show()方法" ); }}class Son extends Father{ static{ System.out.println("子類靜態代碼塊初始化" ); } { System.out.println("子類代碼塊初始化" ); } private static int i=1; private String s="子類私有成員變量" ; public void show() { System.out.println("子類show()方法:i=" +i); } public Son() { System.out.println("子類構造函數初始化完成" ); System.out.println("子類成員變量初始化完成:s="+s); show(); }}public class TestClassLoadSeq { public static void main(String[]args) { new Son(); }}
執行順序:
父類靜態代碼塊初始化
父類靜態方法
子類靜態代碼塊初始化
父類代碼塊初始化
父類無參構造函數初始化完成
子類show()方法:i=1??//因為創建的是son實例,所以父類里的show方法被初始化時,實際調用的是子類show方法
子類代碼塊初始化
子類構造函數初始化完成
子類成員變量初始化完成:s=子類私有成員變量
子類show()方法:i=1
在遇到初始化失敗的相關bug時,通常錯誤提示不會直接指向有問題的那行。
因此,需要你對類初始化過程有所了解,這樣才能快速定位到哪個環節最有可能出問題。
3、常見的集合及方法
在日常的數據分析工作中,常常需要使用到集合來存儲和處理數據,因此需要大家對集合的分類和功能有所了解。Java的集合框架分為兩部分,分別對應兩大接口:Collection接口和Map接口。以下就通過這兩大接口開始講解。
1.Collection接口
Collection接口涉及三種類型的集合:1.Set(規則集) 2.List(線性表) 3.Queue(隊列),其層級關系如圖:
ps:圖片源自網絡
這三種類型集合的常用方法及特性總結如下:
集合類型
特性
常用方法
Set
集合中沒有相同的元素
hashCode() //返回對象存儲的物理地址
equals() //判斷值是否相等
List
線性表是一個有序允許重復的集合
add(int index) //指定下標添加元素
addAll(int index, Collection extends ?E> c) //指定下標處添加c中所有元素
get(int index) //返回指定下標元素
lastIndexOf(Object ?o) //返回相同元素的下標
listIterator() ?//返回遍歷列表的迭代器
listIterator(int startIndex) //返回從startIndex開始的所有元素的迭代器
remove(int index) //刪除指定下標的元素
set(int index, E element) //設置指定下標的元素
subList(int fromIndex, int ?toIndex) //返回從fromIndex到toIndex元素子列表
Queue
是一種先進先出的數據結構
offer(E ?e) //添加元素
poll() ?// 返回并刪除隊頭元素,否則返回null? remove() //返回并刪除隊頭元素,否則拋出異常
peek() ?// 返回隊頭元素,否則返回null
element() ?//返回隊頭元素,否則拋出異常
2.Map接口
Map接口涉及三種類型的集合:1.HashMap? 2.LinkedHashMap 3.TreeMap。其層級關系如下:
Map----
|
|----SortMap----TreeMap
|
|----HashMap----LinkedHashMap
Map的特性為鍵值不能重復。每個鍵值對應著一個值,鍵與值一起存儲在集合中。
Map接口中有如下方法:
clear() //刪除所有條目 containsKey(Object key) //如果包含指定鍵值返回true containsValue(Object value) //如果包含指定值返回true get(Object key) //獲得指定鍵值對應的值 entrySet() //返回包含條目的規則集 isEmpty() //判斷是否空 keySet() //返回包含鍵值的一個規則集 put(Object key, Object value) //添加鍵值對 putAll( ) //將指定實例中的鍵值對添加到當前實例中 remove(Object key) //刪除指定鍵值對應的值 size() //鍵值對個數 values() //返回包含的集合
4、常用的字符串處理方法
數據分析工作中,最基本的一項工作就是通過hive寫類sql語言處理數據,而類sql語法中處理字符串的方法都是通過對java的字符串處理方法進行一層封裝得到的,接下來,我們就一起來看下常用Java字符串處理方法有哪些。
字符串查找
String提供了兩種查找字符串的方法,即indexOf與lastIndexOf方法。
1、indexOf(String s)
該方法用于返回參數字符串s在指定字符串中首次出現的索引位置,如果沒有檢索到字符串s,該方法返回-1
String str ="We are students";int size = str.indexOf("a"); // 變量size的值是3
2、lastIndexOf(String str)
該方法用于返回字符串最后一次出現的索引位置。如果沒有檢索到字符串str,該方法返回-1。如果lastIndexOf方法中的參數是空字符串"" ,則返回的結果與length方法的返回結果相同。
獲取指定索引位置的字符
使用charAt()方法可將指定索引處的字符返回。
String str = "hello word";char mychar = str.charAt(5); // mychar的結果是w
獲取子字符串
通過String類的substring()方法可對字符串進行截取。
1、substring(int beginIndex)
該方法返回的是從指定的索引位置開始截取直到該字符串結尾的子串。
String str = "Hello,word";String substr = str.substring(3); //獲取字符串,此時substr值為lo,word
2、substring(int beginIndex,? int endIndex)
String str = "Hello word";String substr = str.substring(0,3); //substr的值為hel
去除空格
trim()方法返回字符串的副本,忽略前導空格和尾部空格。
字符串替換
replace()方法可實現將指定的字符或字符串替換成新的字符或字符串
String str= "address";String newstr = str.replace("a","A");// newstr的值為Address
判斷字符串的開始與結尾
startsWith()方法與endsWith()方法分別用于判斷字符串是否以指定的內容開始或結束。這兩個方法的返回值都為boolean類型。
1、startsWith(Stringprefix)
該方法用于判斷當前字符串對象的前綴是否是參數指定的字符串。
2、endsWith(Stringsuffix)
該方法用于判斷當前字符串是否以給定的子字符串結束
判斷字符串是否相等
1、equals(Stringotherstr)
如果兩個字符串具有相同的字符和長度,則使用equals()方法比較時,返回true。同時equals()方法比較時區分大小寫。
2、equalsIgnoreCase(Stringotherstr)
equalsIgnoreCase()方法與equals()類似,不過在比較時忽略了大小寫。
字母大小寫轉換
字符串的toLowerCase()方法可將字符串中的所有字符從大寫字母改寫為小寫字母,而toUpperCase()方法可將字符串中的小寫字母改寫為大寫字母。
str.toLowerCase();
str.toUpperCase();
字符串分割
使用split()方法可以使字符串按指定的分隔字符或字符串對內容進行分割,并將分割后的結果存放在字符串數組中。
str.split('&');
str.split(String sign, in limit);
該方法可根據給定的分割符對字符串進行拆分,并限定拆分的次數。
5、常用的日期處理方法
另一個在數據分析工作中,跟字符串處理一樣使用較為頻繁的就是關于日期的相關處理。
其中最常用到的日期處理類有:java.util.Date、java.util.Calendar、java.text.SimpleDateFormat。
1.java.util.Date的使用
構造函數
Date() :分配 Date 對象并用當前時間初始化此對象,以表示分配它的時間(精確到毫秒)。
Date(long date) :分配 Date 對象并初始化此對象,以表示自從標準基準時間(即 1970 年 1 月 1 日 00:00:00 GMT)以來的指定毫秒數。
常用方法
2.java.text.SimpleDateFormat的使用
java.text.SimpleDateFormat主要用于格式化日期,需要說明的一點是該類的實例是線程不安全的。
構造函數
public SimpleDateFormat(String pattern):pattern是描述日期和時間格式的模式 如:yyyyMMDD
使用方式
public class TestDateFormat { public voiddateFormat(){ Date date= new Date(); //創建不同的日期格式 SimpleDateFormat dt1 = new SimpleDateFormat('YYYY-MM-DD HH:MM:SS'); dt1.format(date);//返回的日期格式如:2019-05-13 04:03:45 SimpleDateFormat dt2 = new SimpleDateFormat('YYYY-MM-DD'); dt2.format(date);//返回的日期格式如:2019-05-13 SimpleDateFormat df3 = new SimpleDateFormat("yyyy年MM月dd日 hh時mm分ss秒 EE",Locale.CHINA) ; dt3.format(date);//返回的日期格式如:2019年05月13日 04時03分45秒 星期一 }}
3.java.util.Calendar的使用
java.util.Calendar是個抽象類,它可以通過特定的方式設置和讀取日期的特定部分,比如年、月、日、時等,并為操作日歷字段(例如獲得下星期的日期)提供了一些方法。
創建實例
Calendar dt = Calendar.getInstance();
常見操作
//設置時間dt.setTime(new Date()); //獲取年月日時分秒dt.get(Calendar.YEAR);dt.get(Calendar.MONTH);dt.get(Calendar.DAY_OF_MONTH);dt.get(Calendar.HOUR);dt.get(Calendar.MINUTE);dt.get(Calendar.SECOND); //獲取上午下午dt.get(Calendar.AM_PM); //獲取一周中的星期幾dt.get(Calendar.DAY_OF_WEEK); //當前日期基礎上加減指定天數dt.add(Calendar.YEAR, -1);dt.sub(Calendar.YEAR, -1);
6、json的解析與操作
json的表達能力非常強,一方面擁有常用的數據類型,另一方面可以表達復雜的數據結構。因此,在大數據領域,經常使用json作為信息的載體,將數據封裝起來。所以,理解json的結構,對json進行解析與操作,在數據分析工作中非常重要。
下面是幾個常用的 JSON 解析類庫:
Json官方:Douglas Crockford在2001年開始推廣使用的數據格式,解析最具有通用性,但是有點小麻煩
Gson:谷歌開發的 JSON 庫,功能十分全面
FastJson:阿里巴巴開發的 JSON 庫,性能十分優秀
Jackson:社區十分活躍且更新速度很快
下面我們主要通過代碼示例來了解下java變量和json格式之間的相互轉化以及json對象與字符串的相互轉化。
1.編碼
從 Java 變量到 JSON 格式的編碼過程如下:
public void testJson() { JSONObject object = new JSONObject(); //string object.put("string","string"); //int object.put("int",2); //boolean object.put("boolean",true); //array List
輸出結果如下:
{"boolean":true,"string":"string","list":[1,2,3],"int":2}
2.解碼
從 JSON 對象到 Java 變量的解碼過程如下:
public void testJson2() { JSONObjectobject = JSONObject .parseObject("{\"boolean\":true,\"string\":\"string\",\"list\":[1,2,3],\"int\":2}"); //string String s = object.getString("string"); System.out.println(s); //int int i = object.getIntValue("int"); System.out.println(i); //boolean boolean b = object.getBooleanValue("boolean"); System.out.println(b); //list List
3.JSON 對象與字符串的相互轉化
//前提說明:JSON是一個抽象類,以下實例中的parseObject(String text)、parseArray(String text)、toJSONString(JSONObject obj)、toJSONString(JSONArray arr)是該抽象類的靜態方法 //從字符串解析JSON對象JSONObject obj =JSON.parseObject("{\"runoob\":\"測試實例\"}");//從字符串解析JSON數組JSONArray arr =JSON.parseArray("[\"測試實例\",\"RUNOOB\"]\n");//將JSON對象轉化為字符串String objStr =JSON.toJSONString(obj);//將JSON數組轉化為字符串String arrStr =JSON.toJSONString(arr);
7、正則表達式
數據分析過程中,經常需要對字符串進行匹配、替換、提取等操作,而有時簡單的字符串處理方法已經無法滿足復雜的處理邏輯時,就需要使用到正則表達式來完成。
這部分的內容,在ETL中的數據提取和處理環節應用非常頻繁,所以大家要重點掌握。
概念
正則表達式是對字符串操作的一種邏輯公式,就是用事先定義好的一些特定字符、及這些特定字符的組合,組成一個“規則字符串”,這個“規則字符串”用來表達對字符串的一種過濾邏輯。
--摘自百度百科
作用
1.匹配:給定的字符串是否符合正則表達式的過濾邏輯
2.提取:可以將匹配成功的特定部分提取出來
3.替換:針對匹配成功的特定部分,替換為新的字符串
規則
圖片摘自云游道士的博客
PS:由于篇幅有限,上述規則只是列出了常用的一些規則,如果在實際工作中發現上述規則不滿足業務需求,可以百度一下,尋找其他規則。以下為一些常用的匹配示例。
示例
匹配目標
常用正則表達式
郵箱
^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$
手機號碼
^1[3-9]\d{9}$
網頁URL
^(https?://)?[\S]+$
IP地址
^(((?:[1-9]\d?)|(?:1\d{2})|(?:2[0-4]\d)|(?:25[0-5]))[.]){3}((?:[1-9]\d?)|(?:1\d{2})|(?:2[0-4]\d)|(?:25[0-5]))$
密碼(8-16位,只允許字母、數字、指定符號(_+-.?))
^[\w\-\.+?]{8,16}$
注意事項
1. 使用"|"時,應盡量使用括號來標識邊界,否則容易引起歧義
2. 當使用正則匹配是否包含某一字符串時,不需要在前后加模糊匹配,否則會引起性能下降。例如匹配文本(“This is a pretty dog”)中是否包含“pre”開頭的單詞時,正則表達式應寫作“pre[a-z]+”,而不要寫作“.*pre[a-z]+.*”
3. 所有的特殊字符在[ ]內都將失去其原有的特殊含義,使用時要特別注意。上面的示例中密碼的匹配就是一個字符(+?)含義變化例子
4. 正則表達式中的符號都是英文半角符號
5. 寫好正則后,尤其是復雜的表達式,最好可以測試一下。
可以使用在線工具完成測試,如:
https://c.runoob.com/front-end/854
http://tool.oschina.net/regex/
在java中的使用示例
import java.util.regex.*;// 下面只是使用示例代碼,不能直接運行// 目標字符串String url ="https://aa.bb.com/cn/index.html";// URL匹配規則String regex = "^(https?://)?[\S]+$";// 編譯正則表達式Pattern pattern =Pattern.compile(regex);// 匹配正則表達式與目標字符串,返回匹配結果對象Matcher matcher =pattern.matcher(url);// 判斷字符串是否與正則表達式匹配成功boolean result =matcher.matches();System.out.println(result);
PS:在java中還有一種忽略正則表達式內英文字母大小寫的寫法,意思是在匹配時,忽略目標字符串中英文字母的大小寫,都能匹配成功,寫法如下所示:
// 忽略大小寫的寫法Pattern pattern =Pattern.compile(regex, Pattern.CASE_INSENSITIVE);
8、異常處理
相信大家對異常都不陌生,當程序運行中發生錯誤時,通常都會拋出異常(Exception)來警醒開發人員,如果不處理就會導致程序直接退出。
數據分析工作中,經常會遇到各種問題,這時異常便提供了找到相應問題誘發原因的重要線索,因此我們要保持良好的編碼習慣,避免錯過重要提示線索。
講解這部分知識的主要目的,是用于數據分析日常工作中排查程序問題。怎么捕獲異常,怎么根據異常尋找錯誤發生的位置,相信大家都比較熟悉了,這里我們不再贅述,而是說一下異常處理常遇到的幾種問題。
1.你可能沒捕獲到你的“異常”
我們常見的異常都是Exception的子類,但是異常的頂級父類是Throwable,它下面有兩個子類一個是Exception,另一個是Error。由于Error非常少見,所以大家通常會忽略它。如果你發現你的try catch語句沒能捕獲住“異常”,那就要考慮下,拋出的可能是Error。
還有一種可能性,就是分布式程序的異常。例如,編寫Spark的處理代碼時,要能分清你的代碼是運行在Driver還是Executor上,如果異常發生在Executor,而你在Driver上捕獲,那么也會出現無法捕獲的問題。
2.捕獲異常后,不要讓異常被吃掉
工作中經常被問到一個問題,我的代碼沒有任何報錯,但是運行后卻沒有輸出結果,或者結果數據量很少。
為什么會這樣呢?
這是因為,有些同學在捕獲異常時,可能不太關心異常的發生,如由于臟數據引起的異常(非法json解析失敗),捕獲到這種解析異常,只需要過濾掉對應臟數據即可,便在catch語句塊中什么都沒寫。
這雖不影響程序運行,但是卻吞掉了非常重要的信息。尤其是使用異常的父類Exception來進行捕獲時,可能有超出你預想的異常,就這樣被吃掉了。
根據實際工作的經驗,建議大家至少要把錯誤打印出來,方便后續排查。不然很容易出現,程序內部一直在出錯,但是表面上卻風平浪靜。
打印異常有兩種方式,一是只打印異常摘要信息,即打印異常的message,通過getMessage()方法獲得后打印;
另一種是打印詳細的堆棧信息,通過調用printStackTrace()方法完成詳細信息打印。一般建議,在Executor中執行的代碼(如逐條數據處理的代碼)打印摘要信息,在Driver上執行的代碼,打印堆棧信息。
3. 不要在finally里使用return
finally代碼塊通常是用來做一些必須要做的收尾工作,如釋放資源、修改特定標記位等。
盡量不要在finally代碼塊中使用return,這會使代碼的執行結果變得不好預期。如果需要確保一定有返回值,請catch住所有異常,然后在finally代碼塊的下面寫return。
4. 巧妙利用異常返回信息
當調用一個方法時,通常我們會使用return給調用者返回數據。但還有一種不太常用的做法,就是使用異常返回信息,讓調用者通過捕獲異常的方式,獲取到異常內攜帶的信息。關于這種方式的應用,在后續講解spark時會提到。
5. 合理使用自定義異常
通過自定義異常,我們可以建立自己的異常處理體系,針對不同的業務錯誤,進行相應等級的處理。舉個例子,在數據處理過程中,需要讀取多個數據源,但是可能存在要讀取的路徑不存在,或者讀入的數據量為0等情況,這時通常需要阻斷流程,最好的方式就是拋異常,但有時我們又希望阻斷部分流程,這時只有拋一個自定義的異常,然后外層流程控制中捕獲這個異常,有針對性地處理才能達成目的。
9、JDBC
最后,關于java連接數據庫的橋梁jdbc自然要提及一下,主要還是講講如何使用。
1.加載數據庫驅動
//1.加載驅動Class.forName("com.mysql.jdbc.Driver");
2.建立連接
//URL用于標識數據庫的位置,username和password是訪問數據的用戶名和密碼String url ="jdbc:mysql://localhost:3306/test";String username ="test";String password ="yqz56258";Connection conn = null//2.獲取與數據庫的鏈接conn =DriverManager.getConnection(url, username, password);
3.執行sql獲得結果集
Statement st = null;//3.獲取用于向數據庫發送sql語句的statementst =conn.createStatement();//4.向數據庫發sqlString sql = "select id,name,sex,age from teachers";ResultSet rs =st.executeQuery(sql);
4.結果集遍歷
//next():類似指針的效果,會向下移動while(rs.next()){ //getString(int index):根據索引獲取指定位置的值 String id = rs.getString(1); String name = rs.getString(2); String sex = rs.getString(3); //getString(String columnname):根據列名獲取本列的值 String age =rs.getString("age");}
10、小結
到此為止,所有在大數據工作中最常用到的java基礎知識算是帶著大家溫習一遍啦,讓我們一起來回顧下總共講了哪些知識點:
基礎概念和特性(面向對象、類、對象、封裝、繼承、多態、泛型)、常見的集合及方法、常用的字符串處理方法、常用的日期處理方法、json的解析與操作、正則表達式、異常處理、JDBC。
推薦閱讀:https://blog.csdn.net/weixin_39032019/article/details/117997723
推薦閱讀:https://blog.csdn.net/weixin_39032019/article/details/117737757
【抽獎環節】
抽獎規則:只要評論數過30,隨機抽取一名幸運讀者,現金紅包獎勵 66.66??元!!
開獎方式:采用python random隨機函數,隨機從評論區,搖出頁數、序號。
開獎時間:從文章發布時間起,第三天下午評開獎,評論區公布中獎結果~
上期中獎嘉賓:m0_58649824(情不知所起)
評論、、是對我最大的支持!!
Hadoop Java 大數據
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。