在阿里的這些天

第一天

  • 上午九點到下午三點左右,入職活動結束,被帶到工位。

  • 安裝環境,

    • jdk 1.8 64位
    • maven這邊工程通過maven構建,推薦使用maven3以上版本
    • IDEA 下載。idea自帶maven插件,但需要在默認的settings.XML文件中添加內部的maven遠程倉庫地址
    • git下載安裝,代碼寄存在gitlab。
    • 所有安裝環境部署完畢之后,了解工具的使用
  • 熟悉團隊的各位成員,相互認識和學習

      • 注意事項:
      • 每周三晚上八點之前提交周報:寫這一周的學習內容,遇到的問題,解決的方法,什么收獲
      • 每天的學習中遇到的問題記下來,晚上找時間向師傅請教。做到當天的問題當天解決。

第二天

  • 學習阿里的代碼編程規范
    • 根據規范中總結的經驗,結合自己之前編碼中的個人習慣進行反思,發現自己存在之前存在很多編碼不規范的地方,對這些地方進行重點總結(規范內容較多,后續還會繼續看)
  • 了解spring boot。由于內網資料看不到,自己在外網搜一下相關教程,并使用spring boot搭建一個hello world程序。

第三天

  • 熟悉信用證基本概念,了解國內跟單流程

  • java基礎復習:

    • jvm類加載機制

      • 類加載器
      類加載器類型 名稱 負責加載 加載的類
      Bootstrap ClassLoader 引導類加載器 核心java class 所有java.開頭的類
      Extension ClassLoader 擴展類加載器 擴展的java class javax.開頭的、放在ext目錄下面的
      System ClassLoader 系統類加載器 用戶程序自身的class 系統中配置的環境變量classpath路徑下面的類
      • 類加載機制
        • 全盤負責:當一個classLoader加載一個類的時候,該class所依賴的所有class 也由這個classloader負責載入。除非是顯示的使用另一個classLoader載入。
        • 雙親委托:先讓父類的加載器加載,如果父類加載器無法加載的話,再該類的加載器進行加載。
    • 垃圾回收

    • 內存模型

    • 基礎集合類

    • jdk 8 新特性

    • servlet

      • 生命周期:
        • 初始化:servlet容器會在啟動時初始化一些servlet,如果在web.xml中的servlet標簽之間加入load-startup 1
  • maven工具學習,重點關注如下問題

    • 如何解決jar沖突

      • 在項目中的pom文件中將沖突依賴排除,具體寫法:比如我們要講一個依賴中的相應jar包排除

        <dependency>
           <groupId>com.xxx.xx</groupId>
           <artifactId>xxx</artifactId>
           <version>x</version>
           <exclusions>
               <exclusion>
                   <artifactId>com.springsource.slf4j.org.apache.commons.logging</artifactId>
                   <groupId>org.slf4j</groupId>
               </exclusion>
           </exclusions>
        </dependency>
        

        ?

      ?

第四天

  • START

    • 之前有過java web開發經驗,對于servlet的生命周期以及基本開發過程有了解,但對于filter和listener了解不是很深。對這些盲點進行逐一攻破
    • 對web.xml的所有常用的配置深入掌握(規范、原理),對不常用的標簽要有所了解
    • 能夠準確描述出servlet、filter、listener各自發揮的作用、生命周期、加載順序等
    • 使用filter、servlet、listener編寫一個動態網頁小demo
    • filter servlet listener:
    • 初始化順序:listener -》filter -》servlet
    • 銷毀順序:servlet- 》filter-》listener(和初始化順序相反)
  • web.xml

    ?

  • filter

    • 定義:過濾器,對web服務器所管理的web資源:例如jsp、servlet、靜態文件等進行攔截。例如實現URL級別的權限訪問、過濾敏感詞匯
    • 主要用于對httpServletRequest進行預處理,也可以對httpServletResponse進行后處理。
    • 完整流程:FIlter對用戶請求預處理--》servlet對請求進行做出相應--》FIlter在對相應進行后處理

    filer和servlet請求響應圖

    • filter鏈:在一個web應用中,可能會有多個filter,這些filter 組合起來稱作filter鏈。filter的執行順序根據filter在web.xml中定義的順序一致

    • filer 生命周期:和servlet一樣,filter的創建和銷毀由web容器負責,當web容器啟動時,將創建filter實例對象,調用init方法。filer對象只會創建一次,故filer是單例的。在多線程情況下會存在線程安全性問題,故不要在file類中定義屬性變量,最好是無狀態的,如果非要使用,一定要使用線程安全的類。比如并發包中的類。

    • filer的四種攔截方式:REQUEST 、FORWORD、 INCLUDE、ERROE

    • REQUEST:直接訪問目標資源

    • FORWORD:轉發

    • INCLUDE:例如:<jsp:include>

    • ERROR:web.xml中配置error-page時

      可以在filter-mapping中添加多個dispatch子元素

    • filer用在哪:權限檢查、編碼過濾

    • 如何使用filer:實現javax.servlet.Filer接口,并覆蓋doFilter方法

    public class MyFilfer implements Filer{
      @Override
      public void doFilter(ServletRequest srep, ServletResponse sresp, FilterChain fc) {
         //TODO   
      }
    }
    

    在web.xml中添加filter

    <filter>
      <filter-name>myFilter</filter-name>
      <filer-class>MyFilfer</filer-class>
    </filter>
    <filter-mapping>
       <filter-name>myFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    

    ?

  • servlet

    • 生命周期:servlet實例的創建有兩個時機:
    • 客戶端第一次請求某個servlet時,系統創建servlet的實例
    • web應用啟動時立刻創建servlet 實例,需要在web.xml中配置<load-on-startup>1(或大于1)</load-on-startup>
    • 容器中只存在一個servlet實例。單例多線程的。故也是線程不安全
  • Demo :使用servlet 和 filter 實現登錄小程序

    1. filter 對用戶請求進行攔截,驗證是否登錄。如果session有用戶信息,則放過。否則redirect到登錄頁面
    2. servlet 對登錄請求進行處理,將用戶信息保存到session中

    git分支地址:http://gitlab.alibaba-inc.com/shixu.sx/user_login/tree/master

  • 問題解決

    • JVM性能調優監控常用命令

    • jps :列出jvm中正在運行的進程信息

      -q 不輸出類名、Jar名和傳入main方法的參數
      -m 輸出傳入main方法的參數
      -l 輸出main類或Jar的全限名
      -v 輸出傳入JVM的參數
      
      shixu.sx@$ jps -l
      9520 sun.tools.jps.Jps
      17924 org.apache.catalina.startup.Bootstrap
      9812 org.jetbrains.jps.cmdline.Launcher
      14184
      14440 org.jetbrains.idea.maven.server.RemoteMavenServer
      
    • jstack: 主要用來查看某個java線程堆棧信息

      場景:找出某個java 進程中最耗費cpu的java線程,并定位堆棧信息

      方案:

      1. 首先找出該java進程的進程id,比如要找bootstrap進程,

        1. 在windows環境下,命令行輸入:jps | findstr "bootstrap"
        2. linux環境下,輸入:jps | grep "bootstrap"
      2. 根據進程id,找出該進程內最耗費資源的線程信息

        命令行輸入:top -Hp 進程id, 然后根據列出的線程信息找到time最長的線程id

        1. 將線程id轉化為十六進制,然后在命令行輸入

          jstack 進程id | grep 線程id對應的十六進制數,根據打印出來的堆棧信息可以知道是哪個線程的問題

    • jmap: 用來查看堆內存使用情況

      使用jmap -heap pid查看進程堆內存使用情況。

    • jstat:jvm統計監測工具

      圖片

      S0C、S1C、S0U、S1U:Survivor 0/1區容量(Capacity)和使用量(Used)
      EC、EU:Eden區容量和使用量
      OC、OU:年老代容量和使用量
      PC、PU:永久代容量和使用量
      YGC、YGT:年輕代GC次數和GC耗時
      FGC、FGCT:Full GC次數和Full GC耗時
      GCT:GC總耗時
      堆內存 = 年輕代 + 年老代 + 永久代
      年輕代 = Eden區 + 兩個Survivor區(From和To)
      

    • 查看網絡端口命令:

    • windows:

      • 查看所有端口占用:netstat -ano
      • 查看指定端口占用:netstat -ano | findstr "端口號"
    • linux:

      • 查看所有端口占用:netstat -anp
      • 查看指定端口占用:netstat -anp | grep "端口號"
    • ?

第五天

  • 9點半到10點半,學習代碼規約

    • 問題:

      1. 規約中一條:避免在有鎖的代碼塊中調用RPC方法,為什么?

        A:一般情況下,鎖的粒度要越小越好,調用RPC本身就是一種粗粒度的處理,所以不建議放在同步代碼塊中。其次,RPC遠程調用不確定性太多,比如運行時間長、超時、事務回滾等,如果RPC方法需要運行很長時間,那么該鎖會一直被占用,導致其他線程等待時間過長。

  • jvm

    • jvm內存區域
    • pc寄存器:程序計數器,線程私有,保存當前線程執行的字節碼地址,唯一一個沒有規定任何OOM的區域
    • 虛擬機棧:線程私有,每個線程被創建時都會同時創建一個對應的虛擬機棧,棧中存放著棧幀,每一個棧幀對應一個方法調用。棧幀中保存局部變量表、操作數棧、動態鏈接等
    • 方法區:線程共享,大小可以動態調整,主要存放:類信息(名稱、方法、字段等元信息)、靜態變量。(注:jdk 8 之后方法區已經不存在,取而代之的是metaspace,一塊本地內存,由于類的元數據分配在本地內存中,元空間的最大可分配空間就是系統可用內存空間。)
    • java堆:對象和數組都在這里分配空間。線程共享。垃圾回收的主要區域
    • 垃圾回收算法回顧
    • 遇到的問題
    1. 在JVM規范中規定,如果線程執行的是非native方法,則程序計數器中保存的是當前需要執行的指令的地址;如果線程執行的是native方法,則程序計數器中的值是undefined。為什么是undefined?如果是undefined的話,那么當cpu再次切換執行到該本地方法是,怎么找到要代碼行的地址?
    2. ?
  • maven 定義和相關命令回顧

    • 項目管理和構建自動化工具

    • maven倉庫:

    • 本地倉庫:第一次運行maven構建,會自動下載所有依賴的jar文件到本地倉庫中。它避免了每次構建都引用遠程倉庫的依賴文件

    • 中央倉庫:maven社區提供,不需要配置。

    • 遠程倉庫:如果maven在中央倉庫也找不到依賴的文件,會從用戶提供的遠成倉庫中查找

    • maven依賴搜索順序:1. 本地倉庫 2. 中央倉庫 3. 遠程倉庫 4. 都找不到,報錯編譯失敗

    • 創建工程:

    命令:mvn archetype:generate -DgroupId=com.companyname.helloworld -DartifactId=helloworld Dpackage=com.company.helloworld -Dversion=1.0-SNAPSHOT

    • 構建程序:

    命令:mvn package

    • 安裝工程:

    命令:mvn install

    (安裝到本地后,在本地倉庫會有該工程,其他的項目可以依賴該工程)

    • 生成文檔

    命令:mvn site

    • spring

      • 控制翻轉和依賴注入:

      • bean作用域

      • bean生命周期

      • 依賴注入方式

      • 基于set方法

      • 基于構造方法

        (二者優劣)

      • AOP原理,代理模式(動態代理cglib和jdk代理區別)

      • 事務管理(編程式事務和聲明式事務)

      • demo小程序

  • 總結:

    • 今天主要是對spring的基礎知識和核心概念,以及常用的配置等進行了復習。回顧過程中發現,很多知識點停留在會用的水平,對底層實現不了解。比如注解這一塊,jvm在加載類的時候遇到注解該怎么處理、注解是如何引入相應的功能的,對這些問題了解以后,還要思考如何自己定義一個注解。周末要對這一點進行深入剖析。同時對于spring boot進行系統學習。

第六天

  • 上午和師傅以及徐瀟師兄一起探討了在瀏覽器輸入www.alibaba.com,之后發生的一切,結合自己對這個問題的認識,發現自己對阿里整個網絡體系以及服務架構了解很不夠。

    • 域名解析:瀏覽器dns緩存、本地dns緩存、本地host文件、請求根dns服務器解析(查詢dns根域,自頂向下進行查詢)
    • http連接:TCP三次握手,建立連接,客戶端與服務器
    • 到達阿里負載均衡層(F5或者LVS,F5是硬件實現負載均衡,LVS針對傳輸層TCP\IP)
    • VIPserver\vip
    • 統一接入(HTTPS解密成HTTP,這是一個CPU密集型任務,在這里進行處理可以降低下游服務器壓力)
    • Tengin\apach\NGINX(負載均衡,應用層負載均衡)
    • 感想:對阿里的整體網絡架構了解還很不夠,比如VIP和VIPserver在其中的具體作用,CDN等如何實現加速,怎么更快解析DNS,如果找到一條更短的路由,等等,這些點以后要一一弄明白。
  • spring boot start

    今天學習了spring boot,看了springboot的一些視頻,對spring boot有了一定的初步的認識,初步了解了spring boot的一些基本理念,如可以替換之前給予xml的配置,可以選用@configuration 和application.properties和application.yml來進行配置spring bean。了解到了spring starters ,通過這個可以減少maven依賴中的版本不匹配問題。

    spring boot的學習中,通過運行demo,加深了對spring boot的理解,demo中集成了JPA。接下來會將springboot中加入其它start比如:mybatis、tddl等,進行學習。

    感想:基于之前學習spring的基礎,spring boot的學習整體順利。但目前對spring boot的理解更多的是在spring boot的使用上,并理解相關的看到的一些注解,對spring boot的一些原理的還需要后面繼續深入。

    • 三種啟動方式:
      • main方法中啟動
      • mvn:spring-boot:run
      • mvn install 然后:java -jar 。。
    • controller的使用
      • @Controller:處理http請求
      • @RestController = @Controller + @ResponseBody:Spring4之后新加的注解,原來返回json需要@ResponseBody配合@Controller
      • @RequestMapping:配置url映射
    • 獲取參數
      • @PathVariable:獲取URL中的數據
      • @RequestParam:獲取請求參數中的值
      • @GetMapping@PostMapping:組合注解

第七天

  • 今天主要對HSF進行了學習。

在系統越來越復雜的情況下,傳統的架構會存在如下的問題:

  • 各個模塊耦合度過高,導致升級更新困難,一處變處處變
  • 擴展性差
  • 團隊開發困難
  • 分布式部署非常困難

而HSF是一個遠程RPC調用框架。面向服務,降低耦合性

  • HSF:

通過配置provider和consumer的bean就ok。

provider暴露自己提供服務的接口,consumer根據接口進行調用。

返回的對象序列化后,通過網絡傳輸。

感想:關于hsf,今天學習的內容主要是對基本原理和基本概念進行學習,然后運行了一個小demo,對服務的發布和服務的消費進行了簡單的實現。接下來還會更深入的學習。

  • OCR識別的結果亂碼問題:

針對ocr識別的結果中文亂碼的問題,我進行了單元測試,最后通過將亂碼內容用iso-8859-1編碼方式轉化為字節,然后再用utf-8解碼,解決了這個問題。iso-8859-1編碼方式是不支持中文的,所以當對含有中文的內容使用這種編碼方式進行編碼的時候,再次解碼肯定會出現亂碼。

因為java本身是跨平臺的語言, 亂碼問題在java開發中非常常見,比如java的IO操作、數據庫、內存、jav web等多種場景,而最終的問題就是出現在字節和字符的轉換上面。

第八天

  • 繼續學習HSF框架

通過看文檔,理解關于服務提供和服務的消費過程:

  • 服務提供者將提供的服務和自己的IP注冊至注冊中心ConfigServer
  • ConfigServer會將服務提供者的IP列表推送至服務消費者
  • 服務消費者發起調用時,直接從ConfigServer推送過來的服務提供者的IP列表中選擇一個IP發起遠程調用

標準的service方式RPC:

  • service 定義:基于OSGI的service定義方式
  • 底層通信方式:萬變不離tcp\ip ,io方面使用異步NIO,并使用長連接

Provider和Consumer的啟動和處理過程

  • 初識TDDL

問題:單一數據庫無法滿足性能要求

  • 數據切分
  • 讀寫分離
  • 系統容災和主備切換以及運維等問題

TDDL提供用戶訪問和數據庫之前的隔離,實現透明操作

1.直接提供分庫分表,讀寫分離、主從備份等解決數據庫擴展問題的功能.

2.基于配置模型構建的包括數據庫在線擴容、準實時數據同步服務、運維平臺等支撐系統。

核心設計:

  • SQL解釋器 :語法樹、查詢匹配規則、分庫分表
  • 查詢優化器
  • 執行器

HSF原理

HSF架構

81c9daf90bf2cdaf81edd7575ed29850.png
81c9daf90bf2cdaf81edd7575ed29850.png

HSF服務架構主要幾塊組成:

  • ConfigServer: 用于服務的注冊與發現,server通過向ConfigServer注冊自己的服務,會在ConfigServer注冊自己的服務信息,如服務地址,發布的接口,服務版本等內容。client端可以從ConfigServer訂閱自己想要的服務,之后ConfigServer就會把訂閱的服務的信息發送給client,之后client和server就可以建立連接,進行RPC調用了。
  • Diamond: 主要用于一些動態的配置內容,例如ConfigServer的地址,路由匹配,動態負載等配置。這些配置內容,可以通過在HSF服務治理網站上進行配置。
  • Redis:負責存儲HSF的元數據,consumer和provider隔一段時間會將調用信息進行上報,同時存儲了應用名和服務映射等信息。

服務注冊發現流程

HSF的基本架構和服務調用方調用服務所需要需要經過的流程。
HSF的基本架構和服務調用方調用服務所需要需要經過的流程。
  1. Provider從Diamond中獲取Configserver的地址、類型等信息。
  2. Provider在Configserver上注冊自己的IP地址、端口號、服務名、版本號、Group號信息。
  3. Provider定期將元數據(調用次數、服務狀態等等)上報給Redis,用于服務治理。
  4. Consumer從Diamond中獲取Configserver的地址、類型等信息。
  5. Consumer根據服務名、版本號、Group號信息向Configserver訂閱Provider服務。
  6. Consumer定期將元數據(調用次數、服務狀態等等)上報給Redis,用于服務治理。
  7. Configserver推送Provider的IP地址列表給Consumer。
  8. Consumer選擇一個IP地址,與該Provider建立長連接、通過RpcRequest和RpcResponse進行調用。
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • Spring Cloud為開發人員提供了快速構建分布式系統中一些常見模式的工具(例如配置管理,服務發現,斷路器,智...
    卡卡羅2017閱讀 134,948評論 18 139
  • Spring Boot 參考指南 介紹 轉載自:https://www.gitbook.com/book/qbgb...
    毛宇鵬閱讀 46,958評論 6 342
  • 從三月份找實習到現在,面了一些公司,掛了不少,但最終還是拿到小米、百度、阿里、京東、新浪、CVTE、樂視家的研發崗...
    時芥藍閱讀 42,367評論 11 349
  • 此篇翻譯的是Spring Boot官方指南 Part III. 使用 Spring Boot (Using Spr...
    K天道酬勤閱讀 6,843評論 0 21
  • 昨天下午兩點半到的巴黎戴高樂機場。坐了有史以來最熱的地鐵,巴黎地鐵沒有空調,32℃的天曬著太陽坐輕軌,還經歷了同伴...
    小easy閱讀 283評論 2 3