当前位置 博文首页 > 信息技术智库:23篇大数据系列(一)java基础知识全集(2万字干

    信息技术智库:23篇大数据系列(一)java基础知识全集(2万字干

    作者:[db:作者] 时间:2021-09-13 19:07

    公众号:数据与智能、大数据club

    大数据系列爽文,从技术能力、业务基础、分析思维三大板块来呈现,你将收获:

    ??提升自信心,自如应对面试,顺利拿到实习岗位或offer;

    ??掌握大数据的基础知识,与其他同事沟通无障碍;

    ??具备一定的项目实战能力,对于大数据工作直接上手;

    ?

    有问题的小伙伴欢迎csdn主页。评论、点赞、收藏是对我最大的支持!!!

    ?

    大数据工程师知识体系:

    ?

    大数据时代已经到来

    最近几十年,高速发展的互联网,渗透进了我们生活的方方面面,整个人类社会都已经被互联网连接为一体。身处互联网之中,我们无时无刻不在产生大量数据,如浏览商品的记录、成交订单记录、观看视频的数据、浏览过的网页、搜索过的关键词、点击过的广告、朋友圈的自拍和状态等。这些数据,既是我们行为留下的痕迹,同时也是描述我们自身最佳的证据。

    2014年3月,马云曾经在北京的一次演讲中说道:“人类正从IT时代走向DT时代”。7年过去了,正如马云预想的那样,大数据时代已经到来了。

    大数据工程师的工作内容是什么?

    而大数据时代,有一个关键性的岗位不得不提,那就是大数据工程师。想必大家也会好奇,大数据工程师,日常是做什么的呢??

    1.数据采集找出描述用户或对业务发展有帮助的数据,并将定义相关的数据格式,交由业务开发部门负责收集对应的数据。
    2.ETL工程?对收集到的数据,进行各种清洗、处理、转化等操作,完成格式转换,便于后续分析,保证数据质量,以便得出可以信赖的结果。
    3.构建数仓将数据有效治理起来,构建统一的数据仓库,让数据与数据间建立连接,碰撞出更大的价值。
    4.数据建模基于已有的数据,梳理数据间的复杂关系,建立恰当的数据模型,便于分析出有价值的结论。
    5.统计分析对数据进行各种维度的统计分析,建立指标体系,系统性地描述业务发展的当前状态,寻找业务中的问题,发现新的优化点与增长点。
    6.用户画像

    基于用户的各方面数据,建立对用户的全方位理解,构建每个特定用户的画像,以便针对每个个体完成精细化运营。

    大数据工程师必备技能

    那么,问题来了,如果想成为一名大数据工程师,胜任上述工作内容,需要具备什么样的条件?拥有什么样的知识呢?

    分类

    子分类

    技能

    描述

    编程基础

    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对象与字符串的相互转化。