• Java面试题整理二


    一.io有几种流?

    有两种流:字节流和字符流.

    字节流继承自inputstream和outstream。

    字符流继承自write和read。

    二.Jdbc的开发流程?

    JDBC编程的六个步骤:

    1)加载驱动程序。

    2)建立连接

    3)创建语句。

    4)执行语句。

    5)处理ResultSet。

    (6)关闭连接

    public class UseJdbc {  
      
        public void Jdbc() {  
            try {  
                Class.forName("com.mysql.cj.jdbc.Driver");//加载驱动程序  
                System.out.println("Ok");  
                //建立连接  
                Connection connection = DriverManager.getConnection("jdbc:mysql://localhost/Contacts?serverTimezone=UTC", "root", "Cc229654512");  
                System.out.println("Database connected");  
                //创建语句  
                Statement statement = connection.createStatement();  
                //用executeQuery执行SQL查询语句  
                ResultSet resultSet = statement.executeQuery("select Name, PhoneNumber, Email, QQ, Note from Contacts");  
                //获取并输出返回结果  
                while (resultSet.next()) {  
                    System.out.println(resultSet.getString(1) + "	" + resultSet.getString(2) + "	" + resultSet.getString(3) + "	" + resultSet.getString(4) + "	"  
                            + resultSet.getString(5));  
                }  
                //关闭连接  
                connection.close();  
            } catch (Exception ex) {  
                ex.printStackTrace();  
            }  
        }  
    }  

    三.Nginx负载权重的分配?

    我们这里讨论nginx的两种负载均衡方式 轮询加权(也可以不加权,就是1:1负载)和ip_hash(同一ip会被分配给固定的后端服务器,解决session问题)
    这个配置文件,我们可以写到nginx.conf里面(如果只有一个web集群),如果有多个web集群,最好写到vhosts里面,以虚拟主机的方式,这里我写到nginx.conf里面
    第一种配置:加权轮询,按服务器的性能给予权重,本例是1:2分配
     upstream lb {
    
                    server 192.168.196.130 weight=1 fail_timeout=20s;
                    server 192.168.196.132 weight=2 fail_timeout=20s;
     }
    
     server {
                    listen 80;
                    server_name safexjt.com www.safexjt.com;
      index index.html index.htm index.php;
      location / {
                            proxy_pass http://lb;
       proxy_next_upstream http_500 http_502 http_503 error timeout invalid_header;
       include proxy.conf;
                    }
     }
    
    第二种配置:ip_hash轮询方法,不可给服务器加权重
    
     upstream lb {
    
                    server 192.168.196.130 fail_timeout=20s;
                    server 192.168.196.132 fail_timeout=20s;
      ip_hash;
     }
    
     server {
                    listen 80;
                    server_name safexjt.com www.safexjt.com;
      index index.html index.htm index.php;
      location / {
                            proxy_pass http://lb;
       proxy_next_upstream http_500 http_502 http_503 error timeout invalid_header;
       include proxy.conf;
                    }
     }
    
    方法二 nginx负载均衡基于ip_hash实现session粘帖
    
    
    1、轮询(默认)
    每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器down掉,能自动剔除。 
    
    upstream backserver {
    server 192.168.0.14;
    server 192.168.0.15;
    }
    2、指定权重
    指定轮询几率,weight和访问比率成正比,用于后端服务器性能不均的情况。 
    
    upstream backserver {
    server 192.168.0.14 weight=10;
    server 192.168.0.15 weight=10;
    }
    3、IP绑定 ip_hash
    每个请求按访问ip的hash结果分配,这样每个访客固定访问一个后端服务器,可以解决session的问题。 
    
    upstream backserver {
    ip_hash;
    server 192.168.0.14:88;
    server 192.168.0.15:80;
    }
    4、fair(第三方)
    按后端服务器的响应时间来分配请求,响应时间短的优先分配。 
    
    upstream backserver {
    server server1;
    server server2;
    fair;
    }
    5、url_hash(第三方)
    按访问url的hash结果来分配请求,使每个url定向到同一个后端服务器,后端服务器为缓存时比较有效。 
    
    upstream backserver {
    server squid1:3128;
    server squid2:3128;
    hash $request_uri;
    hash_method crc32;
    }
    在需要使用负载均衡的server中增加 
    
    proxy_pass http://backserver/;
    upstream backserver{
    ip_hash;
    server 127.0.0.1:9090 down; (down 表示单前的server暂时不参与负载)
    server 127.0.0.1:8080 weight=2; (weight 默认为1.weight越大,负载的权重就越大)
    server 127.0.0.1:6060;
    server 127.0.0.1:7070 backup; (其它所有的非backup机器down或者忙的时候,请求backup机器)
    }
    max_fails :允许请求失败的次数默认为1.当超过最大次数时,返回proxy_next_upstream 模块定义的错误
    fail_timeout:max_fails次失败后,暂停的时间

    四、视频的推流与拉流?

    推流,指的是把采集阶段封包好的内容传输到服务器的过程。

    拉流是指服务器已有直播内容,用指定地址进行拉取的过程。

     五。Springboot的启动方式以及springboot项目会存放在Tomcat中吗?

    启动方式有两种:第一种在springbootapplication中运行run as java application

    第二种 运行run as spring boot app

    总结下SpringBoot应用部署到Tomcat下的配置方法用于备忘也方便遇到同样问题的朋友
    
    将打包方式改成war 
    这个没啥好说的, 肯定要改成war
    
    配置嵌入Tomcat中的方式 
    这里有两种方式可选择:
    
    方式一:用spring-boot内置的tomcat库, 并指定你要部署到Tomcat的版本
    
    <properties>
        <tomcat.version>7.0.69</tomcat.version>
    </properties>
    <dependency>
        <groupId>org.apache.tomcat</groupId>
        <artifactId>tomcat-juli</artifactId>
        <version>${tomcat.version}</version>
    </dependency>
    
    方式二:不用spring-boot内置的tomcat库(强烈推荐这种方式!!)
    
    <!-- 打war包时加入此项, 告诉spring-boot tomcat相关jar包用外部的,不要打进去 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-tomcat</artifactId>
        <scope>provided</scope>
    </dependency>
    
    maven-war-plugin (可选) 
    与maven-resources-plugin类似,当你有一些自定义的打包操作, 比如有非标准目录文件要打到war包中或者有配置文件引用了pom中的变量。 具体用法参见官方文档:http://maven.apache.org/components/plugins/maven-war-plugin/

    六。线程中的sleepwait的区别?

     sleep与wait最主要的区别在于,sleep与wait都可以使线程等待,但sleep不会释放资源而wait会释放资源。
    
    还有就是,wait方法只能在同步块或者同步方法中执行。
    
      怎么理解这句话?
    
      这里有个例子:我登录图书管理系统订了一本 《疯狂JAVA讲义》,当我去到图书管排队借书,到了借书窗口的时候,我告诉管理员我们的名字和预定的书,然后管理员查询到我预订的信息,然后安排助理去预定的图书中找这本书,这个时候,如果我用的是sleep模式,我就一直站在窗口前,直到管理员给我这本书。如果我用的是wait模式,那么我就让出位置给在排队的后面的同学,到旁边的椅子上等待,直到通知我,我要的书找到了,我再回到队伍中排队取票。
    
      这样是不是明白对了?
    
    下面来验证一下,sleep是否不会释放资源而wait会释放资源。
    
    复制代码
    public class ThreadTest {
        public static void main(String[] args) throws InterruptedException {
            
            new Thread(new Thread1()).start();
            
            synchronized (ThreadTest.class) {
                System.out.println("Main Thread go to sleep  : currenttime-->"+System.currentTimeMillis());
                //sleep过程不会释放资源
                Thread.sleep(10000);
            }
            System.out.println("Main Thread get up : currenttime-->"+System.currentTimeMillis());
                new Thread(new Thread2()).start();
                System.out.println("Main Thread over");
        }
        static class Thread1 implements Runnable{
            @Override
            public void run() {
                System.out.println("Thread1 is ready :currenttime-->"+System.currentTimeMillis());
                //因为sleep不会释放资源,所以在主线程sleep结束前,是不能取得资源的锁,而是在等待
                synchronized (ThreadTest.class) {
                System.out.println("Thread1 is running :currenttime-->"+System.currentTimeMillis());
                    System.out.println("Thread1 wait :currenttime-->"+System.currentTimeMillis());
                    try {
                        ThreadTest.class.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }              
                System.out.println("Thread1 is over ");
            }
            }
            
        }
        static class Thread2 implements Runnable{
            @Override
            public void run() {
            System.out.println("Thread2 is ready :currenttime-->"+System.currentTimeMillis());
                synchronized (ThreadTest.class){
                    System.out.println("Thread2 is running :currenttime-->"+System.currentTimeMillis());
                    System.out.println("Thread2 notify :currenttime-->"+System.currentTimeMillis());
                    ThreadTest.class.notify();
                    System.out.println("Thread2 is over");
                    
                }
            }
            
        }
    
    }
    复制代码
     
    
    输出结果:
    
    复制代码
    Main Thread go to sleep  : currenttime-->1400232812969
    Thread1 is ready :currenttime-->1400232812969
    Main Thread get up : currenttime-->1400232822970
    Thread1 is running :currenttime-->1400232822970
    Thread1 wait :currenttime-->1400232822970
    Main Thread over
    Thread2 is ready :currenttime-->1400232822972
    Thread2 is running :currenttime-->1400232822972
    Thread2 notify :currenttime-->1400232822972
    Thread2 is over
    Thread1 is over 
    复制代码
     
    
      由结果可以看出,当主线程sleep10s中的过程,Thread1仅仅处于ready状态,而一直没有获取到ThreadTest.class的锁,原因在于,主线程在sleep的之前已经获取了该资源的锁,这也验证了在用sleep()的时候不会释放资源。
       当主线程sleep完之后,Thread1获取到了ThreadTest.class的锁,然后调用了wait方法(wait方法是Object的静态方法)。在调用该方法后,Thread2启动,且顺利获取到ThreadTest.class的锁,这也验证了在用wait()方法的时候会释放资源。
    
      最后,在Thread2中调用notify方法(notify方法也是Object的静态方法,作用是唤醒在同步监视器上等待的一个线程),然后我们看到 "Thread1 is over"。wait 方法与 notify 方法或notifyAll方法 搭配使用,来协调线程运行。如果我们把Thread2中的notify方法去掉,会发现最后Thread1并没有再次运行,也就不会打印"Thread1 is over"。

    七.简述collection中的集合以及区别,map的种类和区别?

    1.ArrayList: 元素单个,效率高,多用于查询 
    2.Vector: 元素单个,线程安全,多用于查询 
    3.LinkedList:元素单个,多用于插入和删除 
    4.HashMap: 元素成对,元素可为空 
    5.HashTable: 元素成对,线程安全,元素不可为空 

      arraylist和linklist的区别:

    因为数组有索引(角标)所以ArrayList的查询速度快,而添加删除元素速度稍慢。因为,你每删除或者添加一个元素,你都要移动所添加或删除元素后面的所有数据,该集合是线程不同步的(线程不安全)。

         Linklist底层是通过链表实现的,他的特点是查询速度慢,因为他没有角标都是上一个原素指向下一个元素。查询一个元素要遍历整个集合。但是他的添加和删除比arraylist快。

         hashset和treeset的区别:

       hashset:不能保证元素的排列顺序,顺序有可能发生变化 。不是同步的(线程不安全)。集合元素可以是null,但只能放入一个null。

      treeset:TreeSet 是二差树实现的,Treeset中的数据是自动排好序的,不允许放入null值.

        hashmap和hashtable的区别:hashmap线程不安全,可以接受null(hashmap可以接受null的键值(key)和值(value)而hashtable则不行),hashtable线程安全。

    八。Redismongodb的区别?

    Redis和MongoDB都是NoSQL(非关系性数据库)。redis是通过key和value的形式存放在内存中,Redis有五种数据类型:string(字符串)、 list(双向链表)、dict(hash表)、set(集合)、zset(排序set)。MongoDB是面像文档流形式。

    九。项目的分布式dubbokafka ?

    Dubbo是Alibaba开源的分布式服务框架,它最大的特点是按照分层的方式来架构,使用这种方式可以使各个层之间解耦合(或者最大限度地松耦合)。从服务模型的角度来看,Dubbo采用的是一种非常简单的模型,要么是提供方提供服务,要么是消费方消费服务,所以基于这一点可以抽象出服务提供方(Provider)和服务消费方(Consumer)两个角色

    Dubbo的总体架构,如图所示:

    Dubbo框架设计一共划分了10个层,而最上面的Service层是留给实际想要使用Dubbo开发分布式服务的开发者实现业务逻辑的接口层。图中左边淡蓝背景的为服务消费方使用的接口,右边淡绿色背景的为服务提供方使用的接口, 位于中轴线上的为双方都用到的接口。 下面,结合Dubbo官方文档,我们分别理解一下框架分层架构中,各个层次的设计要点:

    1. 服务接口层(Service):该层是与实际业务逻辑相关的,根据服务提供方和服务消费方的业务设计对应的接口和实现。
    2. 配置层(Config):对外配置接口,以ServiceConfig和ReferenceConfig为中心,可以直接new配置类,也可以通过spring解析配置生成配置类。
    3. 服务代理层(Proxy):服务接口透明代理,生成服务的客户端Stub和服务器端Skeleton,以ServiceProxy为中心,扩展接口为ProxyFactory。
    4. 服务注册层(Registry):封装服务地址的注册与发现,以服务URL为中心,扩展接口为RegistryFactory、Registry和RegistryService。可能没有服务注册中心,此时服务提供方直接暴露服务。
    5. 集群层(Cluster):封装多个提供者的路由及负载均衡,并桥接注册中心,以Invoker为中心,扩展接口为Cluster、Directory、Router和LoadBalance。将多个服务提供方组合为一个服务提供方,实现对服务消费方来透明,只需要与一个服务提供方进行交互。
    6. 监控层(Monitor):RPC调用次数和调用时间监控,以Statistics为中心,扩展接口为MonitorFactory、Monitor和MonitorService。
    7. 远程调用层(Protocol):封将RPC调用,以Invocation和Result为中心,扩展接口为Protocol、Invoker和Exporter。Protocol是服务域,它是Invoker暴露和引用的主功能入口,它负责Invoker的生命周期管理。Invoker是实体域,它是Dubbo的核心模型,其它模型都向它靠扰,或转换成它,它代表一个可执行体,可向它发起invoke调用,它有可能是一个本地的实现,也可能是一个远程的实现,也可能一个集群实现。
    8. 信息交换层(Exchange):封装请求响应模式,同步转异步,以Request和Response为中心,扩展接口为Exchanger、ExchangeChannel、ExchangeClient和ExchangeServer。
    9. 网络传输层(Transport):抽象mina和netty为统一接口,以Message为中心,扩展接口为Channel、Transporter、Client、Server和Codec。
    10. 数据序列化层(Serialize):可复用的一些工具,扩展接口为Serialization、 ObjectInput、ObjectOutput和ThreadPool。
    11. Dubbo支持多种协议,如下所示:

      • Dubbo协议
      • Hessian协议
      • HTTP协议
      • RMI协议
      • WebService协议
      • Thrift协议
      • Memcached协议
      • Redis协议

    dubbo理论参考资料:http://shiyanjun.cn/archives/325.html

    dubbo配置参考资料一:http://blog.csdn.net/noaman_wgs/article/details/70214612

    dubbo配置参考资料二:https://www.cnblogs.com/Javame/p/3632473.html

    Kafka是由LinkedIn开发的一个分布式的消息系统,使用Scala编写,它以可水平扩展和高吞吐率而被广泛使用。目前越来越多的开源分布式处理系统如Cloudera、Apache Storm、Spark都支持与Kafka集成。

    kafka 相关名词解释如下:

    复制代码
    1.producer:
      消息生产者,发布消息到 kafka 集群的终端或服务。
    2.broker:
      kafka 集群中包含的服务器。
    3.topic:
      每条发布到 kafka 集群的消息属于的类别,即 kafka 是面向 topic 的。
    4.partition:
      partition 是物理上的概念,每个 topic 包含一个或多个 partition。kafka 分配的单位是 partition。
    5.consumer:
      从 kafka 集群中消费消息的终端或服务。
    6.Consumer group:
      high-level consumer API 中,每个 consumer 都属于一个 consumer group,每条消息只能被 consumer group 中的一个 Consumer 消费,但可以被多个 consumer group 消费。
    7.replica:
      partition 的副本,保障 partition 的高可用。
    8.leader:
      replica 中的一个角色, producer 和 consumer 只跟 leader 交互。
    9.follower:
      replica 中的一个角色,从 leader 中复制数据。
    10.controller:
      kafka 集群中的其中一个服务器,用来进行 leader election 以及 各种 failover。
    12.zookeeper:
      kafka 通过 zookeeper 来存储集群的 meta 信息。

    kafka的参考资料:https://www.cnblogs.com/cyfonly/p/5954614.html

    十。Springbean的生命周期?

    1.生命周期流程图:

      Spring Bean的完整生命周期从创建Spring容器开始,直到最终Spring容器销毁Bean,这其中包含了一系列关键点。

     

    若容器注册了以上各种接口,程序那么将会按照以上的流程进行。下面将仔细讲解各接口作用。

    2.各种接口方法分类

    Bean的完整生命周期经历了各种方法调用,这些方法可以划分为以下几类:

    1、Bean自身的方法  :  这个包括了Bean本身调用的方法和通过配置文件中<bean>的init-method和destroy-method指定的方法

    2、Bean级生命周期接口方法  :  这个包括了BeanNameAware、BeanFactoryAware、InitializingBean和DiposableBean这些接口的方法

    3、容器级生命周期接口方法  :  这个包括了InstantiationAwareBeanPostProcessor 和 BeanPostProcessor 这两个接口实现,一般称它们的实现类为“后处理器”。

    4、工厂后处理器接口方法  :  这个包括了AspectJWeavingEnabler, ConfigurationClassPostProcessor, CustomAutowireConfigurer等等非常有用的工厂后处理器  接口的方法。工厂后处理器也是容器级的。在应用上下文装配配置文件之后立即调用。

  • 相关阅读:
    PHP学习(一)----变量及字符串
    swith
    重写和重载的区别
    静态对象与非静态对象
    继承
    面向对象
    五个对面向对象的实例
    双色球 36选7
    菱形java代码
    双色球代码
  • 原文地址:https://www.cnblogs.com/sbj-dawn/p/7846449.html
Copyright © 2020-2023  润新知