在阿里的这些天

第一天

  • 上午九点到下午三点左右,入职活动结束,被带到工位。

  • 安装环境,

    • 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再次切换执行到该本地方法是,怎么找到要代码行的地址?
  • 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阅读 67,239评论 12 114
  • Spring Boot 参考指南 介绍 转载自:https://www.gitbook.com/book/qbgb...
    毛宇鹏阅读 33,798评论 5 336
  • 从三月份找实习到现在,面了一些公司,挂了不少,但最终还是拿到小米、百度、阿里、京东、新浪、CVTE、乐视家的研发岗...
    时芥蓝阅读 26,308评论 9 312
  • 此篇翻译的是Spring Boot官方指南 Part III. 使用 Spring Boot (Using Spr...
    K天道酬勤阅读 4,303评论 0 21
  • 昨天下午两点半到的巴黎戴高乐机场。坐了有史以来最热的地铁,巴黎地铁没有空调,32℃的天晒着太阳坐轻轨,还经历了同伴...
    小easy阅读 27评论 2 3