美文网首页java
在阿里的这些天

在阿里的这些天

作者: 时芥蓝 | 来源:发表于2017-07-12 09:25 被阅读442次

    第一天

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

    • 安装环境,

      • 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.png81c9daf90bf2cdaf81edd7575ed29850.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进行调用。

    相关文章

      网友评论

      本文标题:在阿里的这些天

      本文链接:https://www.haomeiwen.com/subject/vdfvcxtx.html