一、什么是进程?

软件需要安装操作系统之上,软件安装之后,需要找到核心的启动文件来运行软件。

运行软件:就是让软件执行,其实是将软件中的程序从硬盘加载到内存中,在内存中开辟当前软件所需要的内存空间,而负责运行这个软件的那个内存空间就称为当前软件的一个进程。

简而言之,进程就是正在执行的一个软件(程序)。

二、什么是线程?

它是程序在执行过程中的一个独立的运行单元,它是软件在运行过程中真正干活的地方。

一个软件运行之后,有一个独立的进程,这个进程负责整个软件的生命周期。但是在一个进程中最少有一个线程,它负责具体的功能逻辑。

1、多线程

就是一个进程中运行着多个线程。使用多线程的目的,是为了提高程序的执行效率。

2、多线程执行原理

多线程最终都是需要CPU处理,而CPU(例如单核)真正在某个时间点上它本质上只能处理一个线程,而由于CPU 可以在多个线程之间进行高速切换,导致我们误认为好像是多个程序同时在执行。

由于现在的电脑的CPU都是多核,导致某个时间点上同时会有多个核心处理不同的线程。

3、是不是线程越多越好?

在合理的范围内去使用CPU的核心数,是可以提高程序的效率,但是如果无限的开启线程,会降低CPU的执行效率,可能导致死机。

三、线程和进程的区别?

进程是程序运行和资源分配的基本单位,一个程序至少有一个进程,一个进程至少有一个线程。进程在执行过程中拥有独立的内存单元,而多个线程共享内存资源,减少切换次数,从而效率更高。

线程是进程的一个实体,是CPU调度和分派的基本单位,是比程序更小的能独立运行的基本单位。同一进程中的多个线程之间可以并发执行。

四、创建线程有哪几种方式?

1、 继承Thread类创建线程类

  • 定义Thread类的子类,并重写该类的run方法,该run方法的方法体就代表了线程要完成的任务。因此把run()方法称为执行体。
  • 创建Thread子类的实例,即创建了线程对象。
  • 调用线程对象的start()方法来启动该线程。
//将类声明为Thread的子类class Demo extends Thread{ //重写run方法(执行体) public void run() { for( int i = 0 ; i < 10 ; i++) { System.out.println("demo run i = " + i); } }}public class ThreadDemo { public static void main(String[] args) { //创建线程对象 Demo d = new Demo(); //启动该线程 d.start(); for( int i = 0 ; i < 10 ; i++) { System.out.println("main i = " + i); } }}

2、通过Runnable接口创建线程类

  • 定义runnable接口的实现类,并重写该接口的run()方法,该run()方法的方法体同样是该线程的线程执行体。
  • 创建 Runnable实现类的实例,并依此实例作为Thread的target来创建Thread对象,该Thread对象才是真正的线程对象。
  • 调用线程对象的start()方法来启动该线程。
class Demo implements Runnable{ public void run() { for(int i = 0 ; i < 10 ; i++) { System.out.println("Demo run i = " + i); } }}public class ThreadDemo { public static void main(String[] args) { // 创建实现类的对象 Demo d = new Demo(); // 创建Thread的对象,将实现类对象作为参数传递 Thread t = new Thread(d); // 开启线程 t.start(); for(int i = 0 ; i < 10 ; i++) { System.out.println("main i = " + i); } }}

上面2种方式创建线程都有一个缺陷:就是在执行完任务之后无法获取执行结果。如果需要获取执行结果,就必须通过共享变量或者使用线程通信的方式来达到效果,这样使用起来就比较麻烦。而自从Java 1.5开始,就提供了Callable和Future,通过它们可以在任务执行完毕之后得到任务执行结果。

3、通过Callable和Future创建线程

  • 创建Callable接口的实现类,并实现call()方法,该call()方法将作为线程执行体,并且有返回值。
  • 创建Callable实现类的实例,使用FutureTask类来包装Callable对象,该FutureTask对象封装了该Callable对象的call()方法的返回值。
  • 使用FutureTask对象作为Thread对象的target创建并启动新线程。
  • 调用FutureTask对象的get()方法来获得子线程执行结束后的返回值。
  • 具体解释:https://www.cnblogs.com/dolphin0520/p/3949310.html

五、run方法是干什么的?

在Java中给给出Thread类来描述(封装)操作线程。最终线程是要被开启执行的,开启一个线程之后,需要告诉线程应该去干什么事情。而具体需要线程做的事情,Java给出了run方法,需要将具体的线程要执行的代码编写在其中。

简而言之,run方法,就是编写线程被启动之后需要执行的代码的方法。

六、为什么调用要start来启动线程而不直接去调用run方法?

创建Thread或Thread的子类对象,这时只是代表有线程本身这个对象而已,如果希望程序中能够出现多个线程同时执行的这种状态,就必须调用线程自身的 start 方法将线程开启。

如果直接通过线程对象本身去调用run方法,这时和普通的对象调用方法没有任何的区别。直接调用run方法,线程根本就没有开启,也就是说不会形成多个线程同时执行。

在调用start方法之后,JVM会自动的开辟一个新的线程,然后让这个新的线程去执行线程中的run方法中的代码。

七、继承Thread和实现Runnable有啥区别?

继承Thread,是让子类变成线程类。可是在某些情况下,类已经有父类,它无法再去继承Thread的。可是类中有部分代码又需要被多线程执行,那么只能让需要多线程操作的类去实现Runnable接口。

Thread类:

它是描述线程本身的,它提供操作线程的各种方法(start、stop、interrupt等等)。

Runnable接口:

它和线程没有直接的关系,它其中仅仅提供一个run方法,目的是将需要线程执行的任务书写在run方法中。最终需要将Runnable接口的实现类的对象交给Thread。

八、线程有哪些状态?

线程通常都有五种状态:创建、就绪、运行、阻塞和死亡。

  • 创建状态。在生成线程对象,并没有调用该对象的start方法,这是线程处于创建状态。
  • 就绪状态。当调用了线程对象的start方法之后,该线程就进入了就绪状态,但是此时线程调度程序还没有把该线程设置为当前线程,此时处于就绪状态。在线程运行之后,从等待或者睡眠中回来之后,也会处于就绪状态。
  • 运行状态。线程调度程序将处于就绪状态的线程设置为当前线程,此时线程就进入了运行状态,开始运行run函数当中的代码。
  • 阻塞状态。线程正在运行的时候,被暂停,通常是为了等待某个时间的发生(比如说某项资源就绪)之后再继续运行。sleep,suspend,wait等方法都可以导致线程阻塞。
  • 死亡状态。如果一个线程的run方法执行结束或者调用stop方法后,该线程就会死亡。对于已经死亡的线程,无法再使用start方法令其进入就绪

九、守护线程是什么?

守护进程(线程)(daemon thread),是个服务线程,它的作用准确地来说就是服务其他的线程。它是一类在后台运行的特殊进程,用于执行特定的系统任务。很多守护进程在系统引导的时候启动,并且一直运行直到系统关闭。另一些只在需要的时候才启动,完成任务后就自动结束。

守护线程又被称为“服务进程”、“精灵线程”、“后台线程”,是指在程序运行是在后台提供一种通用的线程。 通俗点讲,任何一个守护线程都是整个JVM中所有非守护线程的“保姆”。

JAVA里线程分2种:

1、守护线程,比如垃圾回收线程,就是最典型的守护线程。

2、用户线程,就是应用程序里的自定义线程。

十、并行和并发有什么区别?

  • 并行是指两个或者多个事件在同一时刻发生;而并发是指两个或多个事件在同一时间间隔发生。
  • 并行是在不同实体上的多个事件,并发是在同一实体上的多个事件。
  • 在一台处理器上“同时”处理多个任务,在多台处理器上同时处理多个任务。如hadoop分布式集群。

所以并发编程的目标是充分的利用处理器的每一个核,以达到最高的处理性能。

打个比方:

并发,就像一个人(cpu)喂2个孩子(程序),轮换着每人喂一口,表面上两个孩子都在吃饭。

并行,就是2个人喂2个孩子,两个孩子也同时在吃饭。

十一、runnable 和 callable 有什么区别?

  • Runnable接口中的run()方法的返回值是void,它做的事情只是纯粹地去执行run()方法中的代码而已;
  • Callable接口中的call()方法是有返回值的,是一个泛型,和Future、FutureTask配合可以用来获取异步执行的结果。

十二、sleep() 和 wait() 有什么区别?

sleep():方法是线程类(Thread)的静态方法,让调用线程进入睡眠状态,让出执行机会给其他线程,等到休眠时间结束后,线程进入就绪状态和其他线程一起竞争cpu的执行时间。因为sleep() 是static静态的方法,它不能改变对象的机锁,当一个synchronized块中调用了sleep() 方法,线程虽然进入休眠,但是对象的机锁没有被释放,其他线程依然无法访问这个对象。

wait():wait()是Object类的方法,当一个线程执行到wait方法时,它就进入到一个和该对象相关的等待池,同时释放对象的机锁,使得其他线程能够访问,可以通过notify,notifyAll方法来唤醒等待的线程。

十三、notify()和 notifyAll()有什么区别?

1、如果线程调用了对象的 wait()方法,那么线程便会处于该对象的等待池中,等待池中的线程不会去竞争该对象的锁。

2、当有线程调用了对象的 notifyAll ()方法(唤醒所有 wait 线程)或 notify()方法(只随机唤醒一个 wait 线程),被唤醒的的线程便会进入该对象的锁池中,锁池中的线程会去竞争该对象锁。也就是说,调用了notify后只有一个线程会由等待池进入锁池,而notifyAll会将该对象等待池内的所有线程移动到锁池中,等待锁竞争。

3、优先级高的线程竞争到对象锁的概率大,假若某线程没有竞争到该对象锁,它还会留在锁池中,唯有线程再次调用 wait()方法,它才会重新回到等待池中。而竞争到对象锁的线程则继续往下执行,直到执行完了 synchronized 代码块,它会释放掉该对象锁,这时锁池中的线程会继续竞争该对象锁。

十四、创建线程池有哪几种方式?

1、newFixedThreadPool(int nThreads)

创建一个固定长度的线程池,每当提交一个任务就创建一个线程,直到达到线程池的最大数量,这时线程规模将不再变化,当线程发生未预期的错误而结束时,线程池会补充一个新的线程。

2、 newCachedThreadPool()

创建一个可缓存的线程池,如果线程池的规模超过了处理需求,将自动回收空闲线程,而当需求增加时,则可以自动添加新线程,线程池的规模不存在任何限制。

3、newSingleThreadExecutor()

这是一个单线程的Executor,它创建单个工作线程来执行任务,如果这个线程异常结束,会创建一个新的来替代它;它的特点是能确保依照任务在队列中的顺序来串行执行。

4、 newScheduledThreadPool(int corePoolSize)

创建了一个固定长度的线程池,而且以延迟或定时的方式来执行任务,类似于Timer。

十五、线程池都有哪些状态?

线程池有5种状态:

1、Running

(1) 状态说明:线程池处在RUNNING状态时,能够接收新任务,以及对已添加的任务进行处理。 (2) 状态切换:线程池的初始化状态是RUNNING。换句话说,线程池被一旦被创建,就处于RUNNING状态,并且线程池中的任务数为0!

private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));

2、ShutDown

(1) 状态说明:线程池处在SHUTDOWN状态时,不接收新任务,但能处理已添加的任务。 (2) 状态切换:调用线程池的shutdown()接口时,线程池由RUNNING -> SHUTDOWN。

3、Stop

(1) 状态说明:线程池处在STOP状态时,不接收新任务,不处理已添加的任务,并且会中断正在处理的任务。 (2) 状态切换:调用线程池的shutdownNow()接口时,线程池由(RUNNING or SHUTDOWN ) -> STOP。

4、Tidying

(1) 状态说明:当所有的任务已终止,ctl 记录的”任务数量”为0,线程池会变为TIDYING状态。当线程池变为TIDYING状态时,会执行钩子函数terminated()。terminated()在ThreadPoolExecutor类中是空的,若用户想在线程池变为TIDYING时,进行相应的处理;可以通过重载terminated()函数来实现。 (2) 状态切换:当线程池在SHUTDOWN状态下,阻塞队列为空并且线程池中执行的任务也为空时,就会由 SHUTDOWN -> TIDYING。 当线程池在STOP状态下,线程池中执行的任务为空时,就会由STOP -> TIDYING。

5、Terminated

(1) 状态说明:线程池彻底终止,就变成TERMINATED状态。 (2) 状态切换:线程池处在TIDYING状态时,执行完terminated()之后,就会由 TIDYING -> TERMINATED。

说明: ctl是一个AtomicInteger类型的原子对象。ctl记录了"线程池中的任务数量"和"线程池状态"2个信息。ctl共包括32位。其中,高3位表示"线程池状态",低29位表示"线程池中的任务数量"。

各个状态切换框架图:

十六、线程池的四种拒绝策略

线程池的拒绝策略,是指当任务添加到线程池中被拒绝,而采取的处理措施。当任务添加到线程池中之所以被拒绝,可能是由于:第一,线程池异常关闭。第二,任务数量超过线程池的最大限制。

线程池共包括4种拒绝策略,它们分别是:AbortPolicy, CallerRunsPolicy, DiscardOldestPolicyDiscardPolicy

AbortPolicy -- 当任务添加到线程池中被拒绝时,它将抛出 RejectedExecutionException 异常。CallerRunsPolicy -- 当任务添加到线程池中被拒绝时,会在线程池当前正在运行的Thread线程池中处理被拒绝的任务。DiscardOldestPolicy -- 当任务添加到线程池中被拒绝时,线程池会放弃等待队列中最旧的未处理任务,然后将被拒绝的任务添加到等待队列中。DiscardPolicy -- 当任务添加到线程池中被拒绝时,线程池将丢弃被拒绝的任务。

线程池默认的处理策略是AbortPolicy!

十七、线程池中 submit()和 execute()方法有什么区别?

1、接收的参数不一样

2、submit有返回值,而execute没有

3、submit方便Exception处理

十八、在 JAVA 程序中怎么保证多线程的运行安全?

线程安全在三个方面体现:

1、原子性:提供互斥访问,同一时刻只能有一个线程对数据进行操作,(atomic,synchronized);

2、可见性:一个线程对主内存的修改可以及时地被其他线程看到,(synchronized,volatile);

3、有序性:一个线程观察其他线程中的指令执行顺序,由于指令重排序,该观察结果一般杂乱无序,(happens-before原则)。

十九、多线程锁的升级原理是什么?

在Java中,锁共有4种状态,级别从低到高依次为:无状态锁,偏向锁,轻量级锁和重量级锁状态,这几个状态会随着竞争情况逐渐升级,锁可以升级但不能降级。

锁升级的图示过程:

二十、什么是死锁?

死锁是指两个或两个以上的进程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,若无外力作用,它们都将无法推进下去。

此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁进程。是操作系统层面的一个错误,是进程死锁的简称,最早在 1965 年由 Dijkstra 在研究银行家算法时提出的,它是计算机操作系统乃至整个并发程序设计领域最难处理的问题之一。

二十一、怎么防止死锁?

死锁的四个必要条件:

1、互斥条件:进程对所分配到的资源不允许其他进程进行访问,若其他进程访问该资源,只能等待,直至占有该资源的进程使用完成后释放该资源;

2、请求和保持条件:进程获得一定的资源之后,又对其他资源发出请求,但是该资源可能被其他进程占有,此事请求阻塞,但又对自己获得的资源保持不放;

3、不可剥夺条件:是指进程已获得的资源,在未完成使用之前,不可被剥夺,只能在使用完后自己释放;

4、环路等待条件:是指进程发生死锁后,若干进程之间形成一种头尾相接的循环等待资源关系。

这四个条件是死锁的必要条件,只要系统发生死锁,这些条件必然成立,而只要上述条件之 一不满足,就不会发生死锁。理解了死锁的原因,尤其是产生死锁的四个必要条件,就可以最大可能地避免、预防和解除死锁。所以,在系统设计、进程调度等方面注意如何不让这四个必要条件成立,如何确定资源的合理分配算法,避免进程永久占据系统资源。

此外,也要防止进程在处于等待状态的情况下占用资源。因此,对资源的分配要给予合理的规划。

二十二、ThreadLocal 是什么?有哪些使用场景?

线程局部变量是局限于线程内部的变量,属于线程自身所有,不在多个线程间共享。Java提供ThreadLocal类来支持线程局部变量,是一种实现线程安全的方式。但是在管理环境下(如 web 服务器)使用线程局部变量的时候要特别小心,在这种情况下,工作线程的生命周期比任何应用变量的生命周期都要长。任何线程局部变量一旦在工作完成后没有释放,Java 应用就存在内存泄露的风险。

二十三、简述 synchronized 底层实现原理?

synchronized 可以保证方法或者代码块在运行时,同一时刻只有一个方法可以进入到临界区,同时它还可以保证共享变量的内存可见性。

Java中每一个对象都可以作为锁,这是synchronized实现同步的基础:

  • 普通同步方法,锁是当前实例对象
  • 静态同步方法,锁是当前类的class对象
  • 同步方法块,锁是括号里面的对象

二十四、能不能将synchronized 添加在run方法上,为什么?

从语法上讲,是可以在run方法上添加同步关键字,让整个run方法同步。但实际是不允许的。 ​ 因为run方法是线程要执行的任务方法,也就是线程只有进入到run方法中才能执行任务,而将同步添加在run方法上,意味着线程都无法进入到run方法,更无法执行任务。而线程出run方法,就意味着当前这个线程已经将任务执行完成了。其他线程进入run方法也没有意义。

二十五、synchronized 和 volatile 的区别是什么?

  • volatile本质是在告诉jvm当前变量在寄存器(工作内存)中的值是不确定的,需要从主存中读取; synchronized则是锁定当前变量,只有当前线程可以访问该变量,其他线程被阻塞住。
  • volatile仅能使用在变量级别;synchronized则可以使用在变量、方法、和类级别的。
  • volatile仅能实现变量的修改可见性,不能保证原子性;而synchronized则可以保证变量的修改可见性和原子性。
  • volatile不会造成线程的阻塞;synchronized可能会造成线程的阻塞。
  • volatile标记的变量不会被编译器优化;synchronized标记的变量可以被编译器优化。

二十五、synchronized 和 Lock 有什么区别?

  • 首先synchronized是java内置关键字,在jvm层面,Lock是个java类;
  • synchronized无法判断是否获取锁的状态,Lock可以判断是否获取到锁;
  • synchronized会自动释放锁(a 线程执行完同步代码会释放锁 ;b 线程执行过程中发生异常会释放锁),Lock需在finally中手工释放锁(unlock()方法释放锁),否则容易造成线程死锁;
  • 用synchronized关键字的两个线程1和线程2,如果当前线程1获得锁,线程2线程等待。如果线程1阻塞,线程2则会一直等待下去,而Lock锁就不一定会等待下去,如果尝试获取不到锁,线程可以不用一直等待就结束了;
  • synchronized的锁可重入、不可中断、非公平,而Lock锁可重入、可判断、可公平(两者皆可);
  • Lock锁适合大量同步的代码的同步问题,synchronized锁适合代码少量的同步问题。

二十六、synchronized 和 ReentrantLock 区别是什么?

synchronized是和if、else、for、while一样的关键字,ReentrantLock是类,这是二者的本质区别。既然ReentrantLock是类,那么它就提供了比synchronized更多更灵活的特性,可以被继承、可以有方法、可以有各种各样的类变量,ReentrantLock比synchronized的扩展性体现在几点上:

  • ReentrantLock可以对获取锁的等待时间进行设置,这样就避免了死锁
  • ReentrantLock可以获取各种锁的信息
  • ReentrantLock可以灵活地实现多路通知
  • 另外,二者的锁机制其实也是不一样的:ReentrantLock底层调用的是Unsafe的park方法加锁,synchronized操作的应该是对象头中mark word。

二十七、 简述 atomic 的原理?

Atomic包中的类基本的特性就是在多线程环境下,当有多个线程同时对单个(包括基本类型及引用类型)变量进行操作时,具有排他性,即当多个线程同时对该变量的值进行更新时,仅有一个线程能成功,而未成功的线程可以向自旋锁一样,继续尝试,一直等到执行成功。

Atomic系列的类中的核心方法都会调用unsafe类中的几个本地方法。我们需要先知道一个东西就是Unsafe类,全名为:sun.misc.Unsafe,这个类包含了大量的对C代码的操作,包括很多直接内存分配以及原子操作的调用,而它之所以标记为非安全的,是告诉你这个里面大量的方法调用都会存在安全隐患,需要小心使用,否则会导致严重的后果,例如在通过unsafe分配内存的时候,如果自己指定某些区域可能会导致一些类似C++一样的指针越界到其他进程的问题

原文:https://www.cnblogs.com/zyouyi/p/11331216.html

鸣谢作者:游戈之泪

同软件多个线程设置不同ip_多线程--面试知识相关推荐

  1. 同软件多个线程设置不同ip_中学校园广播-中学IP网络广播系统解决方案

    学校广播站 概况及需求 中学一般都是三至六个年级(包含初中部和高中部).对广播系统的基本要求如下: 要求具有上下课音乐铃和常规校园广播的功能,如广播体操.眼保健操自动播放,广播通知.广播找人.公共区及 ...

  2. 同软件多个线程设置不同ip_软件测试如何自学?收下这份《2020千锋性能测试入门视频教程》...

    萧亚轩在吐槽大会上说:"我只是天赋异禀,一个平平无奇的恋爱小天才."讲真,小千是百分百赞同,毕竟谁不是在平平无奇的生活里悄咪咪的给自己加持各种装备,偶尔一个大招适时放出,真的能够亮 ...

  3. 同软件多个线程设置不同ip_5-13网络编程(附带多线程死锁,线程通信)

    0513多线程 死锁 当线程任务中出现了多个同步(多个锁)时,如果同步中嵌套了其他的同步.这时容易引发一种现象:程序出现无限等待,这种现象我们称为死锁 线程通信 生产者消费者模式 模拟街道案例 wai ...

  4. 同软件多个线程设置不同ip_IP数量不够该如何解决,快试试掘金网ip代理

    当你利用爬虫爬取网络信息的时候经常会莫名其妙的被目标网站禁止访问,你可以查找以下几个原因: 第一如果你察觉你获取到的信息内容和目标网站所屏幕显示的正常信息不同,换句话说所抓取的信息是一片空白的,那么很 ...

  5. burp爆破线程设置多少_多线程到底需要设置多少个线程?

    我们在使用线程池的时候,会有两个疑问点: 线程池的线程数量设置过多会导致线程竞争激烈 如果线程数量设置过少的话,还会导致系统无法充分利用计算机资源 那么如何设置才不会影响系统性能呢?其实线程池的设置是 ...

  6. 为线程设置一个名字 [mythread setName:@第一个子线程];

    为线程设置一个名字      [mythread setName:@"第一个子线程"];

  7. Thread\Threading.Timer\Task中ShowDialog()方法报错:“在可以调用 OLE 之前,必须将当前线程设置为单线程单元(STA)模式”

    在可以调用 OLE 之前,必须将当前线程设置为单线程单元(STA)模式.请确保您的 Main 函数带有 STAThreadAttribute 标记. 出错环境: 1.在Thread线程中,调用Show ...

  8. 【技术贴】五分钟解决打开软件提示windows正在设置Microsoft Office Profes

    [技术贴]解决打开软件提示windows正在设置Microsoft Office Professional Edition 2003,请插入光盘|office安装提示错误139 解决办法很简单, 1. ...

  9. 异常错误:在可以调用 OLE 之前,必须将当前线程设置为单线程单元(STA)模式

    最近做一个蛋疼的东西就是C#调用windows API 来操作一个摄像头,自动处理一些东西.要用到剪切板复制 粘贴功能,即 Clipboard.SetDataObject(filedic, true) ...

最新文章

  1. 如何在自己的信息管理系统里集成第三方权限控制组件 - 设计一个漂亮的WEB界面...
  2. mybaits错误解决:There is no getter for property named 'parentId ' in class 'java.lang.String'
  3. (0001) iOS 开发之收集第三方资源篇
  4. 启明云端分享|SSD201_自动升级固件与烧录MAC地址
  5. 数据库-数据类型介绍
  6. 西北大学计算机转专业,西北大学可以转专业吗,西北大学新生转专业政策
  7. 【转】ABP源码分析二十一:Feature
  8. python各进制的表述与转换
  9. 14寸笔记本电脑_纯小白预算5000到6000有什么好的笔记本电脑推荐吗?
  10. [ActionScript 3.0] 记录几个ByteArray 十六进制 String等相互转换的方法
  11. Mac 麦克风不工作?6 种修复方法
  12. 星巴克推出含萃取后咖啡粉制作的渣渣管;麦咖啡四款新品登陆全国1600家门店;可口可乐业绩恢复至疫情前水平 | 美通企业日报...
  13. java mvc接收json_详解springmvc 接收json对象的两种方式
  14. Python 数据处理库 pandas
  15. python计算增长率_计算Pandas集团年增长率
  16. Windows11常用快捷键总结(包含触控板使用技巧)
  17. Linux上如何测试服务器之间的通信
  18. html自学网页制作,HTML入门学习教程:简单网页制作
  19. 汽车降价结束会迎来报复性涨价吗
  20. 使用OpenCV采集摄像头的视频并保存为文件

热门文章

  1. 业界首创,腾讯网络平台部实现大规模光网络实时管控系统TOOP
  2. 3 年 3 款产品百万级增长方法论
  3. 写 Python 到底用什么编辑器好?鹅厂程序猿吵翻了
  4. 腾讯容器云平台GaiaStack亮相kubeCon
  5. 《视频直播技术详解》系列之二:采集
  6. Linux共享库路径配置
  7. JAVA程序设计----多线程(上)
  8. C#多线程 我的第一个多线程程序
  9. 在Spring Boot中使用内存数据库
  10. 理解分布式一致性:拜占庭容错与PBFT