2019-06-03 面试问题集锦

Git 与 SVN 的区别?

  - Git 只关心文件数据的整体是否发生变化,而SVN则只关心文件内容的具体差异。
  - 在Git 中的绝大多数操作都只需要访问本地文件和资源,不必联网就可以看到所有的历史版本记录,而SVN 却需要联网。
  - SVN 断开网络或者断开VPN就无法commit代码,但是Git 可以先commit到本地仓库。
  - Git 的内容完整性要优于SVN。
  - Git 克隆一个完整项目的速度非常快,SVN 非常慢。
  - 其中最重要的区别是在于Git 上的分支远比SVN上的强大。

Git的master分支主要作用?

  git的服务器端(remote)端包含多个repository,每个repository可以理解为一个项目。而每个repository下有多个branch。"origin"就是指向某一个repository的指针。服务器端的"master"(强调服务器端是因为本地端也有master)就是指向某个repository的一个branch的指针。

Git 冲突如何解决?

  • 如果希望保存本地改动并拉下最新服务器代码,手动merge
    - 要保留服务器上的修改
    git stash
    vim 冲突文件
    git add
    git commit

  • 如果希望服务器上版本完全覆盖本地修改,使用如下命令回退并更新 
    git reset --hard
    git pull

线程池ThreadPoolExecutor的实现原理

  1. 先判断线程池中核心线程池所有的线程是否都在执行任务。如果不是,则新创建一个线程执行刚提交的任务,否则,核心线程池中所有的线程都在执行任务,则进入第2步;
  2. 判断当前阻塞队列是否已满,如果未满,则将提交的任务放置在阻塞队列中;否则,则进入第3步;
  3. 判断线程池中所有的线程是否都在执行任务,如果没有,则创建一个新的线程来执行任务,否则,则交给饱和策略进行处理;

线程池的创建

ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler)

参数说明

   1. corePoolSize:表示核心线程池的大小。当提交一个任务时,如果当前核心线程池的线程个数没有达到corePoolSize,则会创建新的线程来执行所提交的任务,**即使当前核心线程池有空闲的线程**。如果当前核心线程池的线程个数已经达到了corePoolSize,则不再重新创建线程。如果调用了`prestartCoreThread()`或者 `prestartAllCoreThreads()`,线程池创建的时候所有的核心线程都会被创建并且启动。
   2. maximumPoolSize:表示线程池能创建线程的最大个数。如果当阻塞队列已满时,并且当前线程池线程个数没有超过maximumPoolSize的话,就会创建新的线程来执行任务。
   3. keepAliveTime:空闲线程存活时间。如果当前线程池的线程个数已经超过了corePoolSize,并且线程空闲时间超过了keepAliveTime的话,就会将这些空闲线程销毁,这样可以尽可能降低系统资源消耗。
   4. unit:时间单位。为keepAliveTime指定时间单位。
   5. workQueue:阻塞队列。用于保存任务的阻塞队列,关于阻塞队列[可以看这篇文章](https://www.jianshu.com/p/c422ed5ea9ce)。可以使用**ArrayBlockingQueue, LinkedBlockingQueue, SynchronousQueue, PriorityBlockingQueue**。
   6. threadFactory:创建线程都是通过ThreadFactory来实现的,如果没指定的话,默认会使用Executors.defaultThreadFactory(),一般来说,我们会在这里对线程设置名称、异常处理器等。
   7. handler:饱和策略。当线程池的阻塞队列已满和指定的线程都已经开启,说明当前线程池已经处于饱和状态了,那么就需要采用一种策略来处理这种情况。采用的策略有这几种:
     a) AbortPolicy: 直接拒绝所提交的任务,并抛出**RejectedExecutionException**异常;
     b) CallerRunsPolicy:只用调用者所在的线程来执行任务;
     c) DiscardPolicy:不处理直接丢弃掉任务;
     d) DiscardOldestPolicy:丢弃掉阻塞队列中存放时间最久的任务,执行当前任务

Spring Boot修改端口号的3种方式?

  1. 修改配置文件 application.properties server.port属性
  2. 实现EmbeddedServletContainerCustomizer接口
  3. 命令行
    java -Dserver.port = 9090 -jar executable.jar
    java -jar executable.jar -server.port = 9090

Spring Boot启动原理

  1. 初始化监听器
    初始化Spring Boot自带的监听器,及自定义添加到SpringApplication的监听器;
  2. 发布ApplicationStartedEvent事件
    如果这个时候想执行一些代码可以通过ApplicationListener接口实现;
  3. 装配参数和环境并发布ApplicationEnvironmentPreparedEvent事件
  4. 打印Banner
  5. 创建ApplicationContext
  6. 装配Context
    这里会设置Context的环境变量、注册Initializers、beanNameGenerator等。
    并发布ApplicationPreparedEvent事件 但是并没有真正发布
  7. 注册、加载等
    注册springApplicationArguments、springBootBanner,加载资源等。
  8. 发布ApplicationPreparedEvent事件
  9. refreshContext 装配context beanfactory等非常重要的核心组件。
  10. afterRefreshContext 这里会调用自定义的Runners
  11. 发布ApplicationReadyEvent事件

nginx 如何配置服务限流?

  1. limit_req_zone 参数配置
    e.g.
http {
    limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s;
    server {
        location /search/ {
            limit_req zone=one burst=5 nodelay;
     }
}       

第一个参数:$binary_remote_addr 表示通过remote_addr这个标识来做限制,“binary_”的目的是缩写内存占用量,是限制同一客户端ip地址。
第二个参数:zone=one:10m表示生成一个大小为10M,名字为one的内存区域,用来存储访问的频次信息。
第三个参数:rate=1r/s表示允许相同标识的客户端的访问频次,这里限制的是每秒1次,还可以有 
比如30r/m的。

limit_req zone=one burst=5 nodelay;
第一个参数:zone=one 设置使用哪个配置区域来做限制,与上面limit_req_zone 里的name对应。
第二个参数:burst=5,重点说明一下这个配置,burst爆发的意思,这个配置的意思是设置一个大 
小为5的缓冲区当有大量请求(爆发)过来时,超过了访问频次限制的请求可以先放到这个缓冲区 
内。
第三个参数:nodelay,如果设置,超过访问频次而且缓冲区也满了的时候就会直接返回503,如果 
没有设置,则所有请求会等待排队。

2.
ngx_http_limit_conn_module 参数配置
这个模块用来限制单个IP的请求数。并非所有的连接都被计数。只有在服务器处理了请求并且已经 
读取了整个请求头时,连接才被计数。

nginx 高并发配置?

1. work_rlimit_nofile  最好与ulimit -n一致
2. worker_connections
3. 禁有 keeplive_timeout

Dubbo底层是通过什么进行传输?

底层通过mina,netty长连接进行数据传输。

union 和 union all 的区别?

  1. union 对两个结果集进行并集操作,不包括重复行,会按默认规则排序。
  2. union all 对两个结果集进行并集操作,包括重复行,不会进行排序。
    union 因为要进行默认排序,删除重复行数据,所以性能要比union all 差

jvm 堆栈存什么?

堆中存的是对象。栈中存的是基本数据类型和堆中对象的引用。

java泛型的的区别?

T 代表一种类型
?是通配符,泛指所有类型 一般用于定义一个引用变量,这么做的好处是,如下所示,定义一个sup的引
用变量,就可以指向多个对象。
? extends T 指T类型或T的子类型
? super T 指T类型或T的父类型
T和?运用的地方有点不同,?是定义在引用变量上,T是类上或方法上

你可能感兴趣的:(2019-06-03 面试问题集锦)