Java工程师的进阶之路

2023-05-16

目录

  • 知识点01:九大排序算法
  • 知识点02:二分查找算法
  • 知识点03:二叉树的遍历
  • 知识点04:Spring IOC
  • 知识点05:Spring AOP
  • 知识点06:Spring TX
  • 知识点07:Spring MVC
  • 知识点08:TCP三次握手
  • 知识点09:TCP四次挥手
  • 知识点10:单例设计模式


知识点01:九大排序算法

public class Sort {
    public static void main(String[] args) {
        testTime();
        testSort();
    }

    public static void testTime() {
        int[] arr = new int[10000];
        for (int i = 0; i < 10000; i++) {
            arr[i] = (int) (Math.random() * 100 + 1);
        }
        long s = System.currentTimeMillis();
//        bubbleSort(arr);
//        selectionSort(arr);
//        insertionSort(arr);
//        shellSort(arr);
//        quickSort(arr, 0, arr.length - 1);
//        mergeSort(arr, 0, arr.length - 1, new int[arr.length]);
//        radixSort(arr);
//        countingSort(arr);
//        heapSort(arr);
        long e = System.currentTimeMillis();
        System.out.println((e - s) + "ms");
    }

    public static void testSort() {
        int[] arr = new int[50];
        for (int i = 0; i < 50; i++) {
            arr[i] = (int) (Math.random() * 100 + 1);
        }
//        bubbleSort(arr);
//        selectionSort(arr);
//        insertionSort(arr);
//        shellSort(arr);
//        quickSort(arr, 0, arr.length - 1);
//        mergeSort(arr, 0, arr.length - 1, new int[arr.length]);
//        radixSort(arr);
//        countingSort(arr);
//        heapSort(arr);
        System.out.println(Arrays.toString(arr));
    }

    //堆排序(大顶堆:升序算法,小顶堆:降序算法)
    public static void heapSort(int arr[]) {
        //创建大顶堆
        for (int i = arr.length / 2 - 1; i >= 0; i--) {
            heapAdjust(arr, i, arr.length);
        }
        //调整大顶堆
        for (int i = arr.length - 1; i > 0; i--) {
            //交换元素
            int temp = arr[i];
            arr[i] = arr[0];
            arr[0] = temp;
            //调整新堆
            heapAdjust(arr, 0, i);
        }
    }

    //堆调整
    public static void heapAdjust(int arr[], int ci, int length) {
        //缓存当前结点
        int temp = arr[ci];
        //开始循环调整
        for (int li = ci * 2 + 1; li < length; li = li * 2 + 1) {
            //说明左子结点的值小于右子结点的值
            if (li + 1 < length && arr[li] < arr[li + 1]) {
                li = li + 1;
            }
            //说明当前子结点的值大于父结点的值
            if (arr[li] > temp) {
                arr[ci] = arr[li];
                ci = li;
            } else {
                break;
            }
        }
        //放到调整位置
        arr[ci] = temp;
    }

    //计数排序:升序算法
    public static void countingSort(int[] arr) {
        if (arr == null || arr.length == 0) return;
        int max = arr[0];
        int min = arr[0];
        for (int i = 1; i < arr.length; i++) {
            if (arr[i] > max) max = arr[i];
            if (arr[i] < min) min = arr[i];
        }
        //统计次数
        int[] counts = new int[max - min + 1];
        for (int i = 0; i < arr.length; i++) {
            counts[arr[i] - min]++;
        }
        //累加次数
        for (int i = 1; i < counts.length; i++) {
            counts[i] += counts[i - 1];
        }
        //倒着重排
        int[] newArr = new int[arr.length];
        for (int i = arr.length - 1; i >= 0; i--) {
            newArr[--counts[arr[i] - min]] = arr[i];
        }
        //复制数组
        for (int i = 0; i < arr.length; i++) {
            arr[i] = newArr[i];
        }
    }

    //基数排序:升序算法
    public static void radixSort(int[] arr) {
        if (arr == null || arr.length == 0) return;
        int max = arr[0];
        int min = arr[0];
        for (int i = 1; i < arr.length; i++) {
            if (arr[i] > max) max = arr[i];
            if (arr[i] < min) min = arr[i];
        }
        for (int i = 0; i < arr.length; i++) {
            arr[i] -= min;
        }
        int maxLength = String.valueOf(max - min).length();
        int[][] bucket = new int[10][arr.length];
        int[] bucketIndex = new int[10];
        for (int rounds = 0, base = 1; rounds < maxLength; rounds++, base *= 10) {
            for (int i = 0; i < arr.length; i++) {
                int digit = arr[i] / base % 10;
                bucket[digit][bucketIndex[digit]++] = arr[i];
            }
            int pos = 0;
            for (int i = 0; i < bucketIndex.length; i++) {
                for (int j = 0; j < bucketIndex[i]; j++) {
                    arr[pos++] = bucket[i][j];
                }
                bucketIndex[i] = 0;
            }
        }
        for (int i = 0; i < arr.length; i++) {
            arr[i] += min;
        }
    }

    //归并排序:升序算法
    public static void mergeSort(int[] arr, int L, int R, int[] temp) {
        if (L >= R) return;
        int left = L, middle = (L + R) / 2, right = middle + 1, tIdx = L;
        mergeSort(arr, L, middle, temp);
        mergeSort(arr, right, R, temp);
        while (left <= middle && right <= R) {
            if (arr[left] <= arr[right]) {
                temp[tIdx++] = arr[left++];
            } else {
                temp[tIdx++] = arr[right++];
            }
        }
        while (left <= middle) temp[tIdx++] = arr[left++];
        while (right <= R) temp[tIdx++] = arr[right++];
        for (int i = L; i <= R; i++) {
            arr[i] = temp[i];
        }
    }

    //快速排序:升序算法
    public static void quickSort(int[] arr, int L, int R) {
        if (L >= R) return;
        int left = L, right = R, pivot = arr[L];
        while (left < right) {
            while (left < right && arr[right] >= pivot) right--;
            arr[left] = arr[right];
            while (left < right && arr[left] <= pivot) left++;
            arr[right] = arr[left];
        }
        arr[left] = pivot;
        quickSort(arr, L, left - 1);
        quickSort(arr, left + 1, R);
    }

    //希尔排序:升序算法
    public static void shellSort(int[] arr) {
        for (int step = arr.length / 2; step > 0; step /= 2) {
            for (int i = step; i < arr.length; i++) {
                int temp = arr[i];
                int j = i - step;
                while (j >= 0 && arr[j] > temp) {
                    arr[j + step] = arr[j];
                    j -= step;
                }
                arr[j + step] = temp;
            }
        }
    }

    //插入排序:升序算法
    public static void insertionSort(int[] arr) {
        for (int i = 1; i < arr.length; i++) {
            int temp = arr[i];
            int j = i - 1;
            while (j >= 0 && arr[j] > temp) {
                arr[j + 1] = arr[j];
                j -= 1;
            }
            arr[j + 1] = temp;
        }
    }

    //选择排序:升序算法
    public static void selectionSort(int[] arr) {
        for (int i = 0; i < arr.length - 1; i++) {
            int minIndex = i;
            for (int j = i + 1; j < arr.length; j++) {
                if (arr[minIndex] > arr[j]) {
                    minIndex = j;
                }
            }
            if (minIndex != i) {
                int temp = arr[minIndex];
                arr[minIndex] = arr[i];
                arr[i] = temp;
            }
        }
    }

    //冒泡排序:升序算法
    public static void bubbleSort(int[] arr) {
        for (int i = 0; i < arr.length - 1; i++) {
            for (int j = 0; j < arr.length - 1 - i; j++) {
                if (arr[j] > arr[j + 1]) {
                    int temp = arr[j];
                    arr[j] = arr[j + 1];
                    arr[j + 1] = temp;
                }
            }
        }
    }
}

知识点02:二分查找算法

递归版:

public static int binarySearch(int[] arr, int target) {
    return binarySearch(arr, 0, arr.length - 1, target);
}

private static int binarySearch(int[] arr, int left, int right, int target) {
    if (left > right) return -1;
    int middle = (left + right) / 2;
    if (target < arr[middle]) {
        return binarySearch(arr, left, middle - 1, target);
    } else if (target > arr[middle]) {
        return binarySearch(arr, middle + 1, right, target);
    } else {
        return middle;
    }
}

迭代版:

public static int binarySearch(int[] arr, int target) {
    return binarySearch(arr, 0, arr.length - 1, target);
}

private static int binarySearch(int[] arr, int left, int right, int target) {
    while (left <= right) {
        int middle = (left + right) / 2;
        if (target < arr[middle]) {
            right = middle - 1;
        } else if (target > arr[middle]) {
            left = middle + 1;
        } else {
            return middle;
        }
    }
    return -1;
}

知识点03:二叉树的遍历

树结点:

class TreeNode {
    int data;
    TreeNode left;
    TreeNode right;

    public TreeNode() {}

    public TreeNode(int data) {
        this.data = data;
    }
}

递归版:

//中左右
public static void preOrder(TreeNode root) {
    if (root == null) return;
    System.out.print(root.data + " ");
    preOrder(root.left);
    preOrder(root.right);
}

//左中右
public static void midOrder(TreeNode root) {
    if (root == null) return;
    midOrder(root.left);
    System.out.print(root.data + " ");
    midOrder(root.right);
}

//左右中
public static void postOrder(TreeNode root) {
    if (root == null) return;
    postOrder(root.left);
    postOrder(root.right);
    System.out.print(root.data + " ");
}

迭代版:

//中左右 => 右左(中空)
public static void preOrder(TreeNode root) {
    if (root == null) return;
    Stack<TreeNode> stack = new Stack<>();
    stack.push(root);
    while (!stack.isEmpty()) {
        TreeNode node = stack.pop();
        if (node != null) {
            if (node.right != null) stack.push(node.right);
            if (node.left != null) stack.push(node.left);
            stack.push(node);
            stack.push(null);
        } else {
            node = stack.pop();
            System.out.print(node.data + " ");
        }
    }
}

//左中右 => 右(中空)左
public static void midOrder(TreeNode root) {
    if (root == null) return;
    Stack<TreeNode> stack = new Stack<>();
    stack.push(root);
    while (!stack.isEmpty()) {
        TreeNode node = stack.pop();
        if (node != null) {
            if (node.right != null) stack.push(node.right);
            stack.push(node);
            stack.push(null);
            if (node.left != null) stack.push(node.left);
        } else {
            node = stack.pop();
            System.out.print(node.data + " ");
        }
    }
}

//左右中 => (中空)右左
public static void postOrder(TreeNode root) {
    if (root == null) return;
    Stack<TreeNode> stack = new Stack<>();
    stack.push(root);
    while (!stack.isEmpty()) {
        TreeNode node = stack.pop();
        if (node != null) {
            stack.push(node);
            stack.push(null);
            if (node.right != null) stack.push(node.right);
            if (node.left != null) stack.push(node.left);
        } else {
            node = stack.pop();
            System.out.print(node.data + " ");
        }
    }
}

层序遍历:

public static void layerOrder(TreeNode root) {
    if (root == null) return;
    Queue<TreeNode> queue = new LinkedList<>();
    queue.offer(root);
    while (!queue.isEmpty()) {
        TreeNode node = queue.poll();
        System.out.print(node.data + " ");
        if (node.left != null) queue.offer(node.left);
        if (node.right != null) queue.offer(node.right);
    }
}

知识点04:Spring IOC

执行流程:

生命周期:

循环依赖:

名称完整定义存储类型
一级缓存private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);成品对象
二级缓存private final Map<String, Object> earlySingletonObjects = new ConcurrentHashMap<>(16);半成品对象
三级缓存private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);lambda表达式

1、如果只有一级缓存能否解决循环依赖问题?

如果只有一级缓存的话,那就意味着成品对象和半成品对象都要放到一级缓存中,在获取对象的时候,就有可能获取到半成品对象,而这个半成品对象是不能直接使用的,因此需要使用一级缓存存放成品对象,用二级缓存存放半成品对象。

2、只有一级二级缓存能否解决循环依赖问题?

只有一级二级缓存可以解决循环依赖问题,但是这个是有前提条件的,前提是不使用AOP,如果开启了AOP,那么Spring将会创建代理对象,如果存在代理对象循环依赖问题任然存在。

3、那么问题又来了,为什么需要三级缓存呢?

三级缓存是为了解决代理过程中的循环依赖问题。

4、使用代码演示一下循环依赖执行整个流程?

<bean id="a" class="io.github.caochenlei.domain.A">
    <property name="b" ref="b"></property>
</bean>

<bean id="b" class="io.github.caochenlei.domain.B">
    <property name="a" ref="a"></property>
</bean>
public class ABTest {
    public static void main(String[] args) {
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("ab.xml");
        A a = applicationContext.getBean(A.class);
        System.out.println(a);
        B b = applicationContext.getBean(B.class);
        System.out.println(b);
    }
}

知识点05:Spring AOP

常用术语:

  • 连接点(Join Point):代表类中有哪些方法可以被增强,这些可以被增强的方法称为连接点。
  • 切入点(Pointcut):类中虽然有很多方法可以被增强,但是只有实际被增强的方法称为切入点。
  • 通知(Advice):通知描述了增强逻辑代码在切入点处何时执行。
    • 前置通知,Before Advice
    • 后置通知,AfterReturning Advice
    • 异常通知,AfterThrowing Advice
    • 最终通知,After Advice
    • 环绕通知,Around Advice
  • 目标对象(Target Object):被增强的对象称为目标对象,由于AOP框架是使用动态代理实现的,因此该对象始终是代理对象。
  • 织入(Weaving):把通知应用到目标对象的切入点的过程就是织入。
  • 切面(Aspect):切面是一系列通知和切入点的结合。

代理过程:

执行过程:

知识点06:Spring TX

事务特性:

  • 原子性(Atomicity):强调事务的不可分割,要么全成功要么全失败。
  • 一致性(Consistency):事务的执行的前后,数据的完整性保持一致。
  • 隔离性(Isolation):一个事务的执行中,不该受到其他事务干扰。
  • 持久性(Durability):一个事务一旦结束,数据就会持久到数据库。

隔离级别:

若不考虑事务的隔离性,可能会引发读安全性问题:

  • 脏读:一个事务读到了另一个事务未提交的数据。
  • 不可重复读:一个事务读到了另一个事务已经提交的 update 的数据,导致多次查询结果不一致。
  • 幻读 / 虚读:一个事务读到了另一个事务已经提交的 insert 的数据,导致多次查询结果不一致。

要想解决读安全性问题,需要给事务设置隔离级别:

隔离级别说明描述
ISOLATION_READ_UNCOMMITTED读未提交不能解决以上所有读问题,效率最高,安全性最低,一般不用
ISOLATION_READ_COMMITTED读已提交避免脏读,不可重复读和幻读有可能发生,Oracle默认的隔离级别
ISOLATION_REPEATABLE_READ可重复读避免脏读、不可重复读,幻读有可能发生,MySQL默认的隔离级别
ISOLATION_SERIALIZABLE串行化可以解决以上所有读问题,效率最差,安全性最高,一般不用

传播行为:

传播行为当前不存在事务当前存在事务
PROPAGATION_REQUIRED新建事务使用当前事务
PROPAGATION_SUPPORTS不使用事务使用当前事务
PROPAGATION_MANDATORY抛出异常使用当前事务
PROPAGATION_REQUIRES_NEW新建事务挂起当前事务,新建事务
PROPAGATION_NOT_SUPPORTED不使用事务挂起当前事务
PROPAGATION_NEVER不使用事务抛出异常
PROPAGATION_NESTED新建事务嵌套事务

参考:org.springframework.transaction.support.AbstractPlatformTransactionManager#getTransaction

参考:org.springframework.transaction.support.AbstractPlatformTransactionManager#handleExistingTransaction

执行过程:

提交:org.springframework.transaction.support.AbstractPlatformTransactionManager#commit

回滚:org.springframework.transaction.support.AbstractPlatformTransactionManager#rollback

知识点07:Spring MVC

DispatcherServlet初始过程:

DispatcherServlet请求过程:

DispatcherServlet执行流程:

知识点08:TCP三次握手

  • 第一次握手: 起初两端都处于CLOSED关闭状态,Client将标志位SYN置为1,随机产生一个值seq=x,并将该数据包发送给Server,Client进入SYN-SENT状态,等待Server确认;
  • 第二次握手: Server收到数据包后由标志位SYN=1得知Client请求建立连接,Server将标志位SYN和ACK都置为1,ack=x+1,随机产生一个值seq=y,并将该数据包发送给Client以确认连接请求,Server进入SYN-RCVD状态,此时操作系统为该TCP连接分配TCP缓存和变量;
  • 第三次握手: Client收到确认后,检查ack是否为x+1,ACK是否为1,如果正确则将标志位ACK置为1,ack=y+1,并且此时操作系统为该TCP连接分配TCP缓存和变量,并将该数据包发送给Server,Server检查ack是否为y+1,ACK是否为1,如果正确则连接建立成功,Client和Server进入ESTABLISHED状态,完成三次握手,随后Client和Server就可以开始传输数据。

知识点09:TCP四次挥手

  • 第一次挥手: A的应用进程先向其TCP发出连接释放报文段(FIN=1,序号seq=u),并停止再发送数据,主动关闭TCP连接,进入FIN-WAIT-1(终止等待1)状态,等待B的确认。
  • 第二次挥手: B收到连接释放报文段后即发出确认报文段,(ACK=1,序号seq=v,确认号ack=u+1),B进入CLOSE-WAIT(关闭等待)状态,此时的TCP处于半关闭状态,A到B的连接释放。A收到B的确认后,进入FIN-WAIT-2(终止等待2)状态,等待B发出的连接释放报文段。
  • 第三次挥手: B没有要向A发出的数据,B发出连接释放报文段(FIN=1,ACK=1,序号seq=w,确认号ack=u+1),B进入LAST-ACK(最后确认)状态,等待A的确认。
  • 第四次挥手: A收到B的连接释放报文段后,对此发出确认报文段(ACK=1,序号seq=u+1,确认号ack=w+1),A进入TIME-WAIT(时间等待)状态。此时TCP未释放掉,需要经过时间等待计时器设置的时间2MSL后,A才进入CLOSED状态。

知识点10:单例设计模式

饿汉式:

class Singleton {
    private Singleton() {}

    private final static Singleton instance = new Singleton();

    public static Singleton getInstance() {
        return instance;
    }
}

public class SingletonTest {
    public static void main(String[] args) {
        Singleton instance1 = Singleton.getInstance();
        Singleton instance2 = Singleton.getInstance();
        System.out.println(instance1 == instance2);
    }
}

懒汉式:

class Singleton {
    private Singleton() {}

    private static Singleton instance;

    public static synchronized Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }
}

public class SingletonTest {
    public static void main(String[] args) {
        Singleton instance1 = Singleton.getInstance();
        Singleton instance2 = Singleton.getInstance();
        System.out.println(instance1 == instance2);
    }
}

双检锁:

class Singleton {
    private Singleton() {}

    private volatile static Singleton instance;

    public static Singleton getInstance() {
        if (instance == null) {
            synchronized (Singleton.class) {
                if (instance == null) {
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }
}

public class SingletonTest {
    public static void main(String[] args) {
        Singleton instance1 = Singleton.getInstance();
        Singleton instance2 = Singleton.getInstance();
        System.out.println(instance1 == instance2);
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Java工程师的进阶之路 的相关文章

  • 【OpenCV】OpenCV常用函数(C++版)

    俗话说 xff1a 好记性不如烂笔头 在使用OpenCV的过程中 xff0c 时常会用到很多函数 xff0c 而且往往可能会一时记不起这个函数的具体参数怎么设置 xff0c 故在此将常用函数做一汇总 图像缩放与放大 对图像的各项操作中 xf
  • 【Python】python曲线拟合

    python作为一款可以简单方便地进行科学计算的语言 xff0c 进行曲线拟合自然是必备的功能之一了 本文就如何进行曲线拟合进行讲解 本文需要进行拟合的数据为 xff1a x 61 np arange 1 31 1 y 61 np arra
  • 【C++】NULL和nullptr的关联与差别

    在写代码的过程中 xff0c 有时候需要将指针赋值为空指针 xff0c 以防止野指针 在C中 xff0c 都是使用NULL来实现的 xff1b 在C 43 43 中 xff0c 除了NULL之外 xff0c 还提供了nullptr来进行定义
  • 【C++】C++11可变参数模板(函数模板、类模板)

    在C 43 43 11之前 xff0c 类模板和函数模板只能含有固定数量的模板参数 C 43 43 11增强了模板功能 xff0c 允许模板定义中包含0到任意个模板参数 xff0c 这就是可变参数模板 可变参数模板的加入使得C 43 43
  • 【C++】C++11统一初始化(initializer_list<T>源码分析)

    C 43 43 11之前的初始化语法很乱 xff0c 有四种初始化方式 xff0c 而且每种之前甚至不能相互转换 让人有种剪不断 xff0c 理还乱的感觉 因此 xff0c C 43 43 11添加了统一初始化的方式 xff0c 本文将对统
  • 【C++】右值引用、移动语义、完美转发(上篇)

    在C 43 43 11 xff0c 引入了右值引用的概念 xff0c 在此基础上的移动语义在STL容器中使用非常广泛 简单来说 xff0c move语义使得你可以用廉价的move赋值替代昂贵的copy赋值 xff0c 完美转发使得可以将传来
  • 【C++】右值引用、移动语义、完美转发(下篇)

    上篇中 xff0c 主要讲解了右值引用和移动语义的具体定义和用法 在C 43 43 11中几乎所有的容器都实现了移动语义 xff0c 以方便性能优化 本文以C 43 43 11容器中的insert方法为例 xff0c 详细讲解在容器中移动语
  • AI==喜茶??

    2017年7月10日 xff0c 上海 xff0c 雨 刚从某CV方向的公司下班 xff0c 骑着小黄车朝着浦东某郊区租了一个月的床位行驶着 xff0c 雨打在脸上 xff0c 有点生疼 我不禁在思考 xff0c 这一切到底为了什么 xff
  • 【C++】unique_ptr独占型智能指针详解

    指针是C C 43 43 区别于其他语言的最强大的语法特性 xff0c 借助指针 xff0c C C 43 43 可以直接操纵内存内容 但是 xff0c 指针的引入也带来了一些使用上的困难 xff0c 这要求程序员自己必须手动地对分配申请的
  • 【C++】shared_ptr共享型智能指针详解

    指针是C C 43 43 区别于其他语言的最强大的语法特性 xff0c 借助指针 xff0c C C 43 43 可以直接操纵内存内容 但是 xff0c 指针的引入也带来了一些使用上的困难 xff0c 这要求程序员自己必须手动地对分配申请的
  • 【C++】weak_ptr弱引用智能指针详解

    weak ptr这个指针天生一副小弟的模样 xff0c 也是在C 43 43 11的时候引入的标准库 xff0c 它的出现完全是为了弥补它老大shared ptr天生有缺陷的问题 相比于上一代的智能指针auto ptr来说 xff0c 新进
  • 【C++】模板声明与定义不分离

    一般在写C 43 43 相关代码的时候 xff0c 我们总习惯于将类声明和类实现进行分离 也就是说 xff0c 类的声明一般写在 h文件中 xff0c 而它的实现一般写在 cpp文件中 但是 xff0c 在模板类中 xff0c 这个习惯却要
  • 【C++】空指针调用成员函数及访问成员变量

    最近在review代码的时候发现 xff0c 使用了空指针调用成员函数 xff0c 并且成员函数内部有使用到成员变量 xff0c 居然没有出错 很是奇怪 xff0c 就用一篇博客把关于空指针调用成员函数相关的内容总结起来 空指针调用成员函数
  • 【C++】两个类的相互引用

    有时候在设计数据结构的时候 xff0c 可能会遇到两个类需要相互引用的情形 比如类A有类型为B的成员 xff0c 而类B又有类型为A的成员 那么这种情形下 xff0c 两个类的设计上需要注意什么呢 xff1f 同一文件 尝试方案 将A和B的
  • 【滤波】离散贝叶斯滤波器

    本文参考自rlabbe Kalman and Bayesian Filters in Python的第2章节02 Discrete Bayes xff08 离散贝叶斯 xff09 span class token operator span
  • 用iPad编写C/C++代码(计算机考研党也能用iPad写算法题)

    下载iSH软件 1 在AppStore商店中下载名叫iSH Shell的软件 PS xff1a iSH是一个使用用户模式x86模拟器在iOS设备上获得本地运行的Linux Shell环境的项目 2 安装后点开iSH xff0c 初步了解iS
  • FreeRTOS数据结构——列表与列表项

    在FreeRTOS中存在着大量的基础数据结构列表和列表项的操作 xff0c 要想读懂FreeRTOS的源代码 xff0c 就必须弄懂列表和列表项的操作 一 C语言链表简介 链表就好比一个圆形的晾衣架 xff0c 晾衣架上有很多钩子 xff0
  • ROS1常见问题及解决办法——ROS依赖包安装问题

    ROS依赖包安装问题 问题描述解决方案 问题描述 在ROS编译过程中经常会遇到找不到ROS包的情况 xff0c 如下所示 CMake Error at span class token operator span opt span clas
  • Attention Model(mechanism) 的 套路

    最近刷了一些attention相关的paper 照着here的列表 43 自己搜的paper xff0c 网上相关的资料也有很多 xff0c 在此只讲一讲自己对于attention的理解 xff0c 力求做到简洁明了 一 attention
  • 程序=数据结构+算法

    数据 由 数据元素 组成 xff0c 数据元素 由 数据项 组成 数据元素 xff1a 组成数据的基本单位 xff0c 是集合的个体 数据对象 xff1a 性质相同的数据元素的集合 xff0c 是数据的一个子集 数据结构 xff1a 数据元

随机推荐

  • ROS为上位机与STM32为下位机串口通讯(一)

    STM32通过串口向ROS上位机发送信息 主要实现了STM32 通过串口向ROS上位机发送数据 xff0c 发布者将接收到的数据发布出去并打印出来 xff0c 订阅者订阅发布者发布的消息并打印出来 xff0c 最后通过roslaunch启动
  • 程序员面试真的全都答对就有offer?

    程序员面试 xff0c 技术水平重要吗 xff1f 只要面对面试官 xff0c 估计大家都认为技术水平最重要 xff0c 其他都是幌子 xff01 当然 xff0c 技术是基础 xff0c 但技术并不是全部 xff0c 而且一个面试者的技术
  • 解决vncserver打开远程桌面后没有图标,只有一个鼠标问题

    前言 介绍一个VNC客户端 IIS7服务器管理工具 作为VNC客户端 xff0c 它最优秀的功能就是支持一键导出或导入 xff0c 一键批量打开VNC xff0c 一键批量关闭VNC xff0c 多台VNC 自定义备注 xff0c 自定义分
  • openmv的串口传输

    import sensor image time from pid import PID from pyb import Servo from pyb import UART uartCP 61 UART 1 115200 用于电脑与OPe
  • 三层交换机的“三层”是什么意思?

    关注我们的朋友应该知道 xff0c 之前我们简单分析过二层工业交换机和三层工业交换机的区别 但是近期有客户向我们咨询 xff0c 工业交换机中的三层是指什么意思 xff1f 是指工业交换机中有三层 东西 吗 xff1f 就这个问题我们一起来
  • 外贸人SOHO怎么收汇?2020最新外贸B2B收款结汇方法详解!

    很多做外贸朋友都知道 xff0c 外贸收款 结汇是外贸交易中非常重要的一个环节 一个好的外贸收款渠道 xff0c 可以快速地帮助企业资金回笼 xff0c 支付货款 退税等等 xff0c 能省去很多不必要的麻烦 所以 xff0c 对于外贸从业
  • 在回收站删除的文件怎么恢复

    问题描述 xff1a 回收站清空是很常见的数据恢复故障 在回收站删除的文件怎么恢复接下来我们还需要了解下具体如何恢复回收站清空的资料 xff0c 具体请看正文了解 工具 软件 xff1a 极限数据恢复软件 步骤1 xff1a 先百度搜索并下
  • Jenkins修改显示语言为中文

    最近在Centos7 4里安装了jenkins 2 235 1版本 xff0c 使用的推荐安装插件 xff0c 安装后发现部分中文简体不翻译的情况 一 解决方法 xff1a 默认初始安装的时候已经安排了插件Localization Chin
  • 第三章 九析带你轻松完爆 MinIO - MinIO 客户端使用(mc)

    目录 1 前言 2 邀约 3 介绍 4 mc 安装 5 操作 5 1 查看 minio server 5 2 添加 minio server 5 3 删除 minio server 5 4 查看 minio server 中 bucket
  • 分享一款巨微MS1586低功耗蓝牙芯片

    MS1586包含8位单片机和低功耗 低成本的BLE收发器 xff0c 内部集成了发射机 接收机 GFSK调制解调器和BLE基带处理 遵循BLE广播通道通信 xff0c 具有成本低 体积小 控制方便等优点 特点 4KWOTPROM 256by
  • 推荐系统经典论文文献及业界应用

    Survey方面的文章及资料 Adomavicius G Tuzhilin A Toward the next generation of recommender systems A survey of the state of the a
  • 群辉web station开启http访问文件功能

  • centos7.6 快速架设kiftd私有网盘 文件管理系统

    一 基础环境 安装源ISO CentOS 7 x86 64 DVD 1810 最小化安装系统后先更新 root 64 Server yum update y root 64 Server cat etc redhat release Cen
  • 微信公众号开发

    文章目录 第一章 环境准备1 1 开发工具1 2 创建工程1 3 添加依赖1 4 添加模板1 5 测试接口1 6 内网穿透1 7 接入指南 第二章 基础支持2 1 获取 AccessToken 令牌2 2 获取微信API接口IP地址2 3
  • 果然新鲜电商系统

    项目简介 果然新鲜电商系统是一个类似小米商城的B2C电商平台 xff0c 可做毕业设计参考 访问地址 xff1a https gitee com caochenlei fresh parent 项目截图 网站首页 本地访问 xff1a ht
  • 通用代码生成工具

    项目简介 CodeBuilder可以帮助你快速生成模板文件 xff0c 目前支持mysql oracle sql server数据库 您可以自己制作代码模板并添加到模板目录 xff0c 帮助您可以应付各种开发场景 访问地址 xff1a ht
  • 后台权限管理系统

    项目简介 CommonAdmin是一个按钮级权限管理系统 xff0c 包含企业后台最常用的系统模块 xff0c 代码简洁 xff0c 开箱即用 访问地址 xff1a https gitee com caochenlei common adm
  • 个人博客管理系统

    项目简介 Blog是一款个人博客管理系统 xff0c 是我和同学上学期的期末大作业 xff0c 完成的比较仓促 xff0c 大部分功能已经完成 访问地址 xff1a https gitee com caochenlei blog 主要页面
  • Docker的学习与使用

    目录 第一章 Docker介绍第二章 Docker架构第三章 Docker安装第四章 Docker进程相关命令第五章 Docker镜像相关命令第六章 Docker容器相关命令第七章 Docker容器的数据卷第八章 Docker常见应用部署8
  • Java工程师的进阶之路

    目录 知识点01 xff1a 九大排序算法知识点02 xff1a 二分查找算法知识点03 xff1a 二叉树的遍历知识点04 xff1a Spring IOC知识点05 xff1a Spring AOP知识点06 xff1a Spring