• 高精尖面试题(一)


    jdk jre jvm 三者的区别

    JVM :英文名称(Java Virtual Machine),就是我们耳熟能详的 Java 虚拟机。它只认识 xxx.class 这种类型的文件,它能够将 class 文件中的字节码指令进行识别并调用操作系统向上的 API 完成动作。所以说,jvm 是 Java 能够跨平台的核心,具体的下文会详细说明。

    JRE :英文名称(Java Runtime Environment),我们叫它:Java 运行时环境。它主要包含两个部分,jvm 的标准实现和 Java 的一些基本类库。它相对于 jvm 来说,多出来的是一部分的 Java 类库。

    JDK :英文名称(Java Development Kit),Java 开发工具包。jdk 是整个 Java 开发的核心,它集成了 jre 和一些好用的小工具。例如:javac.exe,java.exe,jar.exe 等。

    显然,这三者的关系是:一层层的嵌套关系。JDK>JRE>JVM

    HDFS的副本数为什么为3,为什么不是2或者是4?

    HDFS的副本数默认是3,并不是必须是3.

    修改hdfs的副本数,首先想到的是修改hdfs-site.xml中的dfs.replication参数

    HDFS采用一种称为机架感知的策略来改进数据的可靠性、可用性和网络带宽的利用率。

    在大多数情况下,HDFS的副本系数是3,HDFS的存放策略是一个副本存放在本地机架节点上,另一个副本存放在同一机架的另一个节点上,第三个副本存放在在不同机架的节点上。这种策略减少了机架间的数据传输,提高了写操作的效率。机架错误的概率远比节点错误的概率小,所以这种策略不会对数据的可靠性和可用性造成影响。与此同时,因为数据只存在两个机架上,这种策略减少了读数据时需要的网络传输带宽。

    在这种策略下,副本并不是均匀地分布在机架上。这种策略在不损坏可靠性和读取性能的情况下,改善了写的性能。

    怎么查看端口号 怎么查看进程

    查看端口号netstat  -anp  |grep   端口号

    ps -aux | grep ***   查询***进程的详细信息

    ps -aux   查询内存中进程信息

    查看java进程

    ps -ef | grep java

    jps

    MR 的工作原理

    略,请查看之前资料。

    说下隐语义模型的应用案例

    属于推荐系统算法的一种,应用案例需要结合自己项目来进行展开。(如果自己项目写了的话。)

    LFM(latent factor model)隐语义模型的核心思想是通过隐含特征(latent factor)联系用户兴趣和物品,采取基于用户行为统计的自动聚类。

            隐含语义分析技术的分类来自对用户行为的统计,代表了用户对物品分类的看法。隐含语义分析技术和ItemCF在物品分类方面的思想类似,如果两个物品被很多用户同时喜欢,那么这两个物品就很有可能属于同一个类。

            隐含语义分析技术允许我们指定最终有多少个分类,这个数字越大,分类的粒度就会越细,反正分类粒度就越粗。

            隐含语义分析技术会计算出物品属于每个类的权重,因此每个物品都不是硬性地被分到某一个类中。

            隐含语义分析技术给出的每个分类都不是同一个维度的,它是基于用户的共同兴趣计算出来的,如果用户的共同兴趣是某一个维度,那么LFM给出的类也是相同的维度。

            隐含语义分析技术可以通过统计用户行为决定物品在每个类中的权重,如果喜欢某个类的用户都会喜欢某个物品,那么这个物品在这个类中的权重就可能比较高。

    用java开发过吗?

    一般建议回答开发过,比如我们在开发Hive UDF函数时,写HDFS API,HBase API时,都是使用Java进行开发的。之前也使用Java写过简单的类,接口等代码。

    多线程是怎么运作的。

       多线程的优势有:

        (1)进程之间不能共享数据,线程可以;

        (2)系统创建进程需要为该进程重新分配系统资源,故创建线程代价比较小;

        (3)Java语言内置了多线程功能支持,简化了java多线程编程。

    线程的生命周期:

     

    1、新建状态

           用new关键字和Thread类或其子类建立一个线程对象后,该线程对象就处于新生状态。处于新生状态的线程有自己的内存空间,通过调用start方法进入就绪状态(runnable)。

    注意:不能对已经启动的线程再次调用start()方法,否则会出现Java.lang.IllegalThreadStateException异常。

    2、就绪状态

           处于就绪状态的线程已经具备了运行条件,但还没有分配到CPU,处于线程就绪队列(尽管是采用队列形式,事实上,把它称为可运行池而不是可运行队列。因为cpu的调度不一定是按照先进先出的顺序来调度的),等待系统为其分配CPU。等待状态并不是执行状态,当系统选定一个等待执行的Thread对象后,它就会从等待执行状态进入执行状态,系统挑选的动作称之为“cpu调度”。一旦获得CPU,线程就进入运行状态并自动调用自己的run方法。

    提示:如果希望子线程调用start()方法后立即执行,可以使用Thread.sleep()方式使主线程睡眠一伙儿,转去执行子线程。

    3、运行状态

          处于运行状态的线程最为复杂,它可以变为阻塞状态、就绪状态和死亡状态。

    处于就绪状态的线程,如果获得了cpu的调度,就会从就绪状态变为运行状态,执行run()方法中的任务。如果该线程失去了cpu资源,就会又从运行状态变为就绪状态。重新等待系统分配资源。也可以对在运行状态的线程调用yield()方法,它就会让出cpu资源,再次变为就绪状态。

    当发生如下情况是,线程会从运行状态变为阻塞状态:

         ①、线程调用sleep方法主动放弃所占用的系统资源

         ②、线程调用一个阻塞式IO方法,在该方法返回之前,该线程被阻塞

         ③、线程试图获得一个同步监视器,但更改同步监视器正被其他线程所持有

         ④、线程在等待某个通知(notify)

         ⑤、程序调用了线程的suspend方法将线程挂起。不过该方法容易导致死锁,所以程序应该尽量避免使用该方法。

    当线程的run()方法执行完,或者被强制性地终止,例如出现异常,或者调用了stop()、desyory()方法等等,就会从运行状态转变为死亡状态。

    4、阻塞状态

          处于运行状态的线程在某些情况下,如执行了sleep(睡眠)方法,或等待I/O设备等资源,将让出CPU并暂时停止自己的运行,进入阻塞状态。 

    在阻塞状态的线程不能进入就绪队列。只有当引起阻塞的原因消除时,如睡眠时间已到,或等待的I/O设备空闲下来,线程便转入就绪状态,重新到就绪队列中排队等待,被系统选中后从原来停止的位置开始继续运行。有三种方法可以暂停Threads执行:

    5、死亡状态

          当线程的run()方法执行完,或者被强制性地终止,就认为它死去。这个线程对象也许是活的,但是,它已经不是一个单独执行的线程。线程一旦死亡,就不能复生。 如果在一个死去的线程上调用start()方法,会抛出java.lang.IllegalThreadStateException异常。

    线程的创建和启动方式:

    1)继承Thread类创建线程类

    通过继承Thread类创建线程类的具体步骤和具体代码如下:

       • 定义一个继承Thread类的子类,并重写该类的run()方法;

       • 创建Thread子类的实例,即创建了线程对象;

       • 调用该线程对象的start()方法启动线程。

    2)实现Runnable接口创建线程类

    通过实现Runnable接口创建线程类的具体步骤和具体代码如下:

       • 定义Runnable接口的实现类,并重写该接口的run()方法;

       • 创建Runnable实现类的实例,并以此实例作为Thread的target对象,即该Thread对象才是真正的线程对象。

    (3)通过Callable和Future创建线程

    通过Callable和Future创建线程的具体步骤和具体代码如下:

       • 创建Callable接口的实现类,并实现call()方法,该call()方法将作为线程执行体,并且有返回值。
       • 创建Callable实现类的实例,使用FutureTask类来包装Callable对象,该FutureTask对象封装了该Callable对象的call()方法的返回值。
       • 使用FutureTask对象作为Thread对象的target创建并启动新线程。
       • 调用FutureTask对象的get()方法来获得子线程执行结束后的返回值其中

    线程管理

    线程睡眠——sleep

    线程让步——yield

    线程合并——join

    设置线程的优先级

    后台(守护)线程

     

    线程同步

     java允许多线程并发控制,当多个线程同时操作一个可共享的资源变量时(如数据的增删改查),将会导致数据不准确,相互之间产生冲突,因此加入同步锁以避免在该线程没有完成操作之前,被其他线程的调用,从而保证了该变量的唯一性和准确性。

    1、同步方法     

          即有synchronized关键字修饰的方法。由于java的每个对象都有一个内置锁,当用此关键字修饰方法时,内置锁会保护整个方法。在调用该方法前,需要获得内置锁,否则就处于阻塞状态。

    public synchronized void save(){}

     注: synchronized关键字也可以修饰静态方法,此时如果调用该静态方法,将会锁住整个类

     2、同步代码块     

         即有synchronized关键字修饰的语句块。被该关键字修饰的语句块会自动被加上内置锁,从而实现同步。

    3、使用特殊域变量(volatile)实现线程同步 

    4、使用重入锁(Lock)实现线程同步

    多线程时java最喜欢问的问题之一。详细看链接

    https://www.cnblogs.com/snow-flower/p/6114765.html

  • 相关阅读:
    phpcms V9 MVC模式 与 URL访问解析
    PHPCMS V9 框架代码分析(入口程序)
    批处理命令——for
    批处理命令——set
    批处理命令——if
    AndroidStudio简单的apk混淆
    CKEditor与CKFinder学习--CKFinder源代码改动自己定义上传文件名称
    LeetCode_Path Sum
    Java 并发:内置锁 Synchronized
    做游戏长知识------基于行为树与状态机的游戏AI(一)
  • 原文地址:https://www.cnblogs.com/lingboweifu/p/11909765.html
Copyright © 2020-2023  润新知