java 每周25问(2019-09-18)

走出舒适区,从自我提问中提高。每周25问,每月100问。

1 什么是递归? 阶乘、斐波那契数列 (Fibonacci Sequence),帕斯卡三角形和递归的联系?为什么使用递归?递归的优缺点? 如何实现递归? 如何将递归改写为非递归代码?

java 每周25问(2019-09-18)_第1张图片

阶乘、斐波那契数列 (Fibonacci Sequence),帕斯卡三角形都是递归的一种数学形式。具体可以参考《程序员的数学》第6章递归

2 链表的java代码实现?

这里是一个单链表

package 链表;
 
import javax.print.attribute.standard.NumberOfDocuments;
 
import static com.sun.tools.classfile.CharacterRangeTable_attribute.Entry.length;
class Node{
    Node next = null;
    int data;
 
    public Node(int data) {
        this.data = data;
    }
}
public class MyLinkedList {
    Node head = null;
 
    /**
     * 链表的插入
     * @param d 插入链表的数据
     */
    public void addNode(int d){
        //新建一个节点
        Node newNode = new Node(d);
        //链表为空
        if(null == head){
            head = newNode;
            return;
        }
        //循环找到链表的末尾
        Node tmp = head;
        while (tmp.next!=null){
            tmp=tmp.next;
        }
        tmp.next = newNode;
    }
 
    /**
     *
     * @param index 链表的索引
     * @return 如果索引小于1或者索引大于链表的长度返回false
     *          删除成功返回true
     */
    public boolean deleteNode(int index){
        if(index<1||index>length()){
            return false;
        }
        //特判删除头指针,因为单向链表没有前驱节点,删除比较简单
        if(index == 1){
            head = head.next;
            return true;
        }
        int i=1;
        Node preNode = head;
        Node curNode = head.next;
        while (curNode!=null){
            //找到索引的位置,将i对应的节点删除,
            //i的前驱节点指向index的后继节点(删除第index个节点)
            if(i==index){
                preNode.next = curNode.next;
                return true;
            }
            preNode = curNode;
            curNode = curNode.next;
            i++;
        }
        return true;
    }
 
    /**
     *
     * @return 返回链表的长度
     */
    public int length(){
        int length = 0;
        Node tmp = head;
        while (tmp.next!=null){
            length++;
            tmp = tmp.next;
        }
        return length;
    }
 
    /**
     *
     * @return链表为空返回true
     */
    public boolean isEmpty(){
        return null == head?true:false;
    }
 
    /**
     *
     * @return返回排好序的链表
     */
    public Node orderList(){
        int tmp=0;
        Node curNode = head;
        Node nextNode = null;
        while (curNode.next!=null){
            nextNode = curNode.next;
            //从小到大排序
            while(nextNode!=null){
                if(curNode.data > nextNode.data){
                    tmp = curNode.data;
                    curNode.data = nextNode.data;
                    nextNode.data = tmp;
                }
                nextNode = nextNode.next;
            }
            curNode = curNode.next;
        }
        return head;
    }
 
    /**
     * 输出链表
     */
    public void printList(){
        Node tmp = head;
        while(tmp!=null){
            System.out.println(tmp.data);
            tmp = tmp.next;
        }
    }
 
    public static void main(String[] args) {
        MyLinkedList list = new MyLinkedList();
        list.addNode(10);
        list.addNode(3);
        list.addNode(5);
        list.addNode(1);
        list.addNode(9);
        System.out.println("length is "+list.length());
        System.out.println("before order");
        list.printList();
        list.orderList();
        System.out.println("after order");
        list.printList();
    }
}

3 栈的java代码实现?

栈的底层是通过数组实现的


public class SqStack {
         
        private Object[] stackElem;//数组就是栈的本质
        private int top;        //top栈顶,其实就是一个数组下标
     
        public SqStack(int maxSize)
        {
            stackElem=new Object[maxSize];
            top=0;
        }
     
        //清空
        public void clear()
        {
            top=0;
        }
        //是否为空
        public boolean isEmpty()
        {
            return top==0;
        }
        //元素个数(也就是栈的大小)
        public int length()
        {
            return top;
        }
        //栈顶
        public Object peek()
        {
            if(!isEmpty())
                return stackElem[top-1];
            else
                return null;
        }
     
        //入栈
        public void push(Object x) throws Exception
        {
            if(top==stackElem.length)
            {
                throw new Exception("栈已满!");
            }
            else
            {
                stackElem[top++]=x;
            }
        }
        //出栈
        public Object pop() throws Exception
        {
            if(top==0)
            {
                throw new Exception("栈为空!");
            }
            else
                return stackElem[--top];  //删除然后返回现在的栈顶
        }
     
        //打印(从栈顶到栈底)
        public void display()
        {
            for(int i=length()-1; i>=0; i--)
            {
                System.out.print(stackElem[i]+" ");
            }
            System.out.println();
        }
        
        //jiancha
        public void showArry(){
            System.out.println("数组长度: "+stackElem.length);
            System.out.print("全部元素: ");
            for(int i=stackElem.length-1; i>=0; i--)
            {
                System.out.print(stackElem[i]+" ");
            }
            System.out.println();
        }
     
        public static void main(String[] args) throws Exception
        {
            SqStack sqStack=new SqStack(6);
            sqStack.push(3);
            sqStack.push(6);
            sqStack.push(9);
         sqStack.push(1);


            System.out.print("打印输出: ");
            sqStack.display();
     
            int top=(int)sqStack.peek();
            System.out.println("栈顶: "+top);
     
            sqStack.pop();
            System.out.print("弹出栈顶,打印输出: ");
            sqStack.display();
            
            System.out.println("数组实际情况: ");
            sqStack.showArry();
        }

}

4 队列的java代码实现?


/**
 *   顺序队列
 * @author Anthony
 *
 */

public class QueueSequence {

    private String[] arr;//队列数组
    private int end=0;//队尾标志
    
    //向队列中添加元素
    public void push(String[] arr,String value) {
        if(end

循环队列:

  • 顺序队列的不足:顺序队列在进行插入操作时,直接在队尾插入就可以,此时时间复杂度为O(1),但是在出列是在队头,即下标为0的位置,也就意味着队列中所有的元素都得向前移动,此时时间复杂度为0(n),效率较低。

  • 队列出列时不需要所有的元素都移动,引入两个指针即可,一个头指针front指向队头元素,一个尾指针rear指向队尾元素,此时队列出列只需移动指针即可。但是此种情况下会出现一种溢出情况(如下图),此时队列中任然是有空间的可以存放元素的,但是尾指针已经溢出,于是就有了循环队列。


    java 每周25问(2019-09-18)_第2张图片
/**
 *   java实现循环队列
 * @author Anthony
 *
 */
public class QueueArray {

    Object[] arr=new Object[10];;//对象数组,队列最多存储a.length-1个对象 
    int front=0;//队首下标
    int rear=0;//队尾下标
    
    /**
     *  将一个对象追加到队列尾部
     */
    public boolean enqueue(Object obj) {
        if((rear+1)%arr.length==front) {
            return false;
        }
        arr[rear]=obj;
        rear=(rear+1)%arr.length;
        return true;
    
    }
    
    //出队列
    public Object dequeue() {
        if(rear==front) {
            return null;
        }
        Object obj=arr[front];
        front=(front+1)%arr.length;
        return obj;
    }
    
    @Test
    public void test() {
        QueueArray q=new QueueArray();
        System.out.println(q.enqueue("北京"));
        System.out.println(q.enqueue("上海"));
        System.out.println(q.enqueue("广东"));
        System.out.println(q.enqueue("深圳"));
        for(int i=0;i<4;i++){   
            System.out.println(q.dequeue());   
        }   
    }
    
        
}

5 Reverse String (反转字符串)

英文版:https://leetcode.com/problems/reverse-string/

class Solution {
    public void reverseString(char[] s) {
        HashMap hashMap = new HashMap(s.length);
    
        for (int i = 0; i < s.length; i++) {
            hashMap.put(i,s[i]);
        }
        for (int i = 0; i < s.length; i++) {
            s[i]= (char) hashMap.get(s.length-i-1);
        }
    }
}

发现用了两次循环,所时间复杂度是O(n),效率并不高


java 每周25问(2019-09-18)_第3张图片

更换为双指针解法


java 每周25问(2019-09-18)_第4张图片

6 为什么插入排序比冒泡排序更受欢迎?分别写出他们以及选择排序的代码实现。

java 每周25问(2019-09-18)_第5张图片

java 每周25问(2019-09-18)_第6张图片

java 每周25问(2019-09-18)_第7张图片
/**
 * 冒泡排序
 * @param a 待排序数组
 * @param n 数组长度
 */
public static void bubbleSort(int[] a, int n) {
        if(n<=0) return ;
for (int i = 0; i < n; i++) {
//标记一次冒泡是否存在数据交换,若存在,则改为true
boolean tag = false;
for (int j = 0; j < n-1-i; j++) {
if(a[j] > a[j+1]){
int temp = a[j];
a[j] = a[j+1];
a[j+1] = temp;
tag = true;
}
}
//若本次冒泡操作未发生数据交换,则终止冒泡操作
if (tag == false) break;
}
}
/**
 * 插入排序
 * @param a 待排序数组
 * @param n 表示数组大小
 */
public static void insertSort(int[] a, int n) {
       if(n<=1) return;
       for(int i=1;i0;j–){
            if(a[j]>value){
                  a[j+1]=a[j];//移动数据
            } else {
                  break;
            }
       }
       a[j+1]=value;//插入数据
       }
}
/**
 * 选择排序
 * @param a 待排序数组
 * @param n 数组长度
 */
public static void selectSort(int[] a, int n) {
if(n<=0) return;
        for(int i=0;i

7 描述下java的新特性?

Java 8 新特性

8 什么是中台?

中台是什么,到底要解决什么问题?

9 SOA是什么?

SOA(Service-Oriented Architecture)的定义是 面向服务的架构。

就是说将软件按照功能设计成一个个服务,这些服务用标准的方式定义接口、并通过标准的协议进行调用。

SOA所定义的接口和调用方式是独立于编程语言和运行平台的,广义上将SOA可以基于不同的底层技术实现。

java 每周25问(2019-09-18)_第8张图片

SOA又叫服务治理,SOA就是帮助我们把服务之间调用的乱七八糟的关系给治理起来,然后提供一个统一的标准,把我们的服务治理成下图所示,以前我们的服务是互相交互,现在是只对数据总线进行交互,这样系统就变得统一起来。

java 每周25问(2019-09-18)_第9张图片

10 JVM概览?基本架构,生命周期,VM类加载,垃圾收集器,编译器

11 什么是快速排序?

12描述一下二分查找。用代码实现?

13 描述下散列表

14 描述一下Redis底层实现

15 图

16 二叉树

17 贪心、分治、回溯和动态规划

18 反转一个单链表。

示例:

输入: 1->2->3->4->5->NULL
输出: 5->4->3->2->1->NULL
进阶:
你可以迭代或递归地反转链表。你能否用两种方法解决这道题?

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/reverse-linked-list
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

19 Reverse Words in a String(字符串转换整数 (atoi))

英文版:https://leetcode.com/problems/string-to-integer-atoi/

20 什么是RPC框架?开源RPC框架如何选型?

21 设计链表

设计链表的实现。您可以选择使用单链表或双链表。单链表中的节点应该具有两个属性:val 和 next。val 是当前节点的值,next 是指向下一个节点的指针/引用。如果要使用双向链表,则还需要一个属性 prev 以指示链表中的上一个节点。假设链表中的所有节点都是 0-index 的。

在链表类中实现这些功能:

get(index):获取链表中第 index 个节点的值。如果索引无效,则返回-1。
addAtHead(val):在链表的第一个元素之前添加一个值为 val 的节点。插入后,新节点将成为链表的第一个节点。
addAtTail(val):将值为 val 的节点追加到链表的最后一个元素。
addAtIndex(index,val):在链表中的第 index 个节点之前添加值为 val 的节点。如果 index 等于链表的长度,则该节点将附加到链表的末尾。如果 index 大于链表长度,则不会插入节点。如果index小于0,则在头部插入节点。
deleteAtIndex(index):如果索引 index 有效,则删除链表中的第 index 个节点。

示例:

MyLinkedList linkedList = new MyLinkedList();
linkedList.addAtHead(1);
linkedList.addAtTail(3);
linkedList.addAtIndex(1,2); //链表变为1-> 2-> 3
linkedList.get(1); //返回2
linkedList.deleteAtIndex(1); //现在链表是1-> 3
linkedList.get(1); //返回3

提示:

所有val值都在 [1, 1000] 之内。
操作次数将在 [1, 1000] 之内。
请不要使用内置的 LinkedList 库。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/design-linked-list
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

22 微服务入门介绍?

23 RPC通信是什么?

24 什么是消息中间件?常见的消息中间件。

25 讲解一下分布式缓存?

26 讲解一下JVM内存模型?

27 讲解一下JVM类加载机制?

28 讲解一下JVM性能优化?

29常见的分布式解决方案和原理?

30 链表的中间节点

给定一个带有头结点 head 的非空单链表,返回链表的中间结点。

如果有两个中间结点,则返回第二个中间结点。

示例 1:

输入:[1,2,3,4,5]
输出:此列表中的结点 3 (序列化形式:[3,4,5])
返回的结点值为 3 。 (测评系统对该结点序列化表述是 [3,4,5])。
注意,我们返回了一个 ListNode 类型的对象 ans,这样:
ans.val = 3, ans.next.val = 4, ans.next.next.val = 5, 以及 ans.next.next.next = NULL.
示例 2:

输入:[1,2,3,4,5,6]
输出:此列表中的结点 4 (序列化形式:[4,5,6])
由于该列表有两个中间结点,值分别为 3 和 4,我们返回第二个结点。

提示:

给定链表的结点数介于 1 和 100 之间。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/middle-of-the-linked-list
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

31 负载均衡是什么,常见的有哪些?

32 常见的排序有哪些,试写出代码

未完待续

你可能感兴趣的:(java 每周25问(2019-09-18))