目录

1.object有哪些方法

2.hashMap结构,put过程,entry一定是链表吗?

3.concurrentHashMap了解吗?它的分段锁是怎么实现的?

4.ArrayList扩容机制?为什么ArrayList获取元素比LinkList快?

5.JVM内存模型

6.SpringMvc执行请求过程

7 四类八种基础数据类型及其包装类,装箱拆箱

8.String类可以继承吗,final说说,final修饰StringBuffer还可以append吗

9.创建线程的那几种方式?主线程可以捕获到子线程的异常吗?Callable接口?Thread和Runnable的区别,哪一种比较安全。?

10 gc方面的,怎么判断对象是否回收,怎么回收,分代回收,比例多少,大对象怎么分配,怎么判断是大对象

11.集合了解哪些?Collection 和 Collections区别

12.说说TCP?三次握手 两次不行?,四次挥手,说说TCP的流量控制、拥塞避免


1.object有哪些方法

答:一用有12个成员方法,分为6类

(1)clone()

(2)hashCode()和equale()

(3)toString和getClass()

(4)wait(),wait(long),wait(long,int),notify(),notifyAll() 线程等待和唤醒

(5)finalize() 垃圾回收时调用该方法

(6)object() 构造方法

2.hashMap结构,put过程,entry一定是链表吗?

https://www.jianshu.com/p/8324a34577a0

答:

(1)hashMap是散列表,存储内容是键值对映射的方式。jdk1.6:结构采用“拉链法”即数组+链表的形式。hashMap有多个entry,每个entry本质时一个单项链表;

(2)put()过程,首先要根据添加的键值对对应的Key的hashCode计算entry位置,如果两个hashCode值相同,则entry位置相同。再判断entry中是否存在key,如果存在,则覆盖,如果不存在,添加到entry链头;

(3)jdk1.8,hashMap采用的是数组+链表+红黑树(当链条长度大于8时,链表转成红黑树)。

HashMapjdk1.8的修改

(1)链表变成红黑树;

(2)计算hashcode的方法改变了(高位取模,hashcode=hashcode^hashcode<<16,为了能够更好的解决hash冲突);

(3)扩容机制:不再采用头插法,因为这样可能存在循环死锁,并且在重新计算hash值的时候也有改进,只计算扩容位是0还是1。

3.concurrentHashMap了解吗?它的分段锁是怎么实现的?

答:

(1)concurrentHashMap是线程安全的hashMap,与jdk1.8的hashMap结构很相似采用node+链表+红黑树,但由于它采用分段锁,所以支持多线程的访问。有一个最重要的不同点就是ConcurrentHashMap不允许key或value为null值。底层结构存放的是TreeBin对象,而不是TreeNode对象;

(2)分段锁:

在jdk1.8以前,concurrentHashMap采用分段锁+hashEntry来实现的,锁采用的是可重入锁ReentrantLock。vaule值是用volatile修饰的,因此获取到的值都是最新值。计算sazi()的时候通过多次计算(最多三次),如果前两次计算结果一样,就是争取结果,如果不同,再对每个分段进行加锁,计算第三次。

在jdk1.8 concurrentHashMap弃用了分段类,但保留了分段属性,采用Node类作为基本的存储单元(其实就是将每个entry作为一个独立的分段锁)+CAS+Synchronized来实现的。

4.ArrayList扩容机制?为什么ArrayList获取元素比LinkList快?

答:

(1)https://www.cnblogs.com/SunArmy/p/9844022.html

其实扩容实现步骤就是分两步(1)扩容---增加长度(把原来数组复制到长度更大的数组中);(2)添加元素到新数组中;

ArrayList每添加元素时,都要调用ensureCapacity()方法来确保足够容量,当需要扩容时,将新容量设置为原来的1.5倍,如果设置后的容量仍旧不够时,则直接将新容量设置为所需容量大小,然后用Array.copyof()方法将元素复杂到新数组中。发生扩容的条件:当需要的最小容量大于等于原数组容量是,需要扩容。

ps:由于每次添加元素如果容量不够的话都需要扩容,扩容非常耗时,因此,当事先知道元素数量的情况下,才使用ArrayList,否则建议使用LinkList;

(2)ArrayList的实现是基于动态数组的数据结构,get和set方法可以实现随机定位;LinkList的实现采用的是双向链表,get需要移动指针,一步一步到查询节点。因此ArrayList比LinkList获取元素更快。

5.JVM内存模型

答:JVM定义了若干个程序执行期间的数据域。有些数据在JVM启动时创建,JVM退出时销毁,有些数据依赖与线程,在线程创建时创建,随着线程退出而销毁。

https://www.cnblogs.com/fubaizhaizhuren/p/4976839.html

(1)共享数据区域:

方法区:存储每个类的信息(类名,方法信息,字段信息)、静态变量、常量以及编译器编译后的代码;

堆:存储对象和数组;

(2)线程隔离数据区域:

程序计数器:当前程序所执行的字节码行号指示器;

jvm栈:存储局部变量表、操作栈、动态链接、方法出口等信息;

本地方法栈:与jvm栈作用相似,是为本地方法服务的。

6.SpringMvc执行请求过程

答:一用11步https://blog.csdn.net/u014191220/article/details/81387596

(1)用户发送请求到前端控制器(DispatcherServlet)。

(2)前端控制器请求处理器映射器(HandlerMapping)去查找处理器(Handler)。

(3)找到以后处理器映射器(HandlerMappering)向前端控制器返回执行链(HandlerExecutionChain)。

(4)前端控制器(DispatcherServlet)调用处理器适配器(HandlerAdapter)去执行处理器(Handler)。

(5)处理器适配器去执行Handler。

(6)处理器执行完给处理器适配器返回ModelAndView。

(7)处理器适配器向前端控制器返回ModelAndView。

(8)前端控制器请求视图解析器(ViewResolver)去进行视图解析。

(9)视图解析器向前端控制器返回View。

(10)前端控制器对视图进行渲染。

(11)前端控制器向用户响应结果。

7 四类八种基础数据类型及其包装类,装箱拆箱

答:

整数类型 byte,short,int,long;  包装类型: Byte,Short,Integer,Long
浮点类型 float,double;   Float,Double
字符类型 chart;   Character
布尔类型 boolean   Boolean

装箱:基本类型转换为包装类型。其中包括自动装箱和手动装箱。自动装箱时编译器调用valueOf()方法

拆箱:包装类型转换为基本类型。其中包括自动拆箱和手动拆箱。自动拆箱时,编译器通过调用类似intValue(),doubleValue()这类的方法。

8.String类可以继承吗,final说说,final修饰StringBuffer还可以append吗

答:不可以继承,String被fianl修饰的类;

为什么要用final修饰????

原理:String本质上是一个被final修饰的char数组,如下所示

private final char value[];

value被final修饰,存放在栈中,但value数组的值存放在堆中,数组的值是可以改变的。

这样做的原因:

主要是为了”安全性“和”效率“的缘故,因为:

1、由于String类不能被继承,所以就不会没修改,这就避免了因为继承引起的安全隐患;

2、String类在程序中出现的频率比较高,如果为了避免安全隐患,在它每次出现时都用final来修饰,这无疑会降低程序的执行效率,所以干脆直接将其设为final一提高效率;

使用final关键字修饰的变量

如果该变量是一个基本类型,一旦初始化后不能再被修改;

如果该变量是一个引用类型,则初始化后,不能再指向其他对象。但该变量的内容是可以被改变的。

由于StringBuffer是引用类型,且append是修改其内容,索引被final修饰后仍可以使用。

9.创建线程的那几种方式?主线程可以捕获到子线程的异常吗?Callable接口?Thread和Runnable的区别,哪一种比较安全。?

(1)继承Thread类,步骤:

a.定义Thread类的子类,并重写该类的run()方法,该方法的方法体就是线程需要完成的任务,run()方法也称为线程执行体。

b.创建Thread子类的实例,也就是创建了线程对象。

c.启动线程,即调用线程的start()方法。t.start();

(2)实现Runnable接口,步骤:

a.定义Runnable接口的实现类,一样要重写run()方法,这个run()方法和Thread中的run()方法一样是线程的执行体。

b.创建Runnable实现类的实例,并用这个实例作为Thread的target来创建Thread对象,这个Thread对象才是真正的线程对象。(注: 启动线程是start()方法,run()并不能启动一个新的线程)

c.第三步依然是通过调用线程对象的start()方法来启动线程。new Thread(t).start();

(3)使用Callable接口和Future创建线程:和Runnable接口不一样,Callable接口提供了一个call()方法作为线程执行体,call()方法比run()方法功能要强大。

call()方法可以有返回值,call()方法可以声明抛出异常

步骤:

a.创建Callable接口的实现类,并实现call()方法,然后创建该实现类的实例(从java8开始可以直接使用Lambda表达式创建Callable对象)。

b.使用FutureTask类来包装Callable对象,该FutureTask对象封装了Callable对象的call()方法的返回值。(FutureTask是一个包装器,它通过接受Callable对象来创建,它同时实现了Future和Runnable接口。)

c.使用FutureTask对象作为Thread对象的target创建并启动线程(因为FutureTask实现了Runnable接口)

d.调用FutureTask对象的get()方法来获得子线程执行结束后的返回值

Runnable和Callable的区别是:

(1)Callable规定的方法是call(),Runnable规定的方法是run()。

(2)Callable的任务执行后可返回值,而Runnable的任务是不能返回值的。

(3)call方法可以抛出异常,run方法不可以。

(4)运行Callable任务可以拿到一个Future对象,表示异步计算(异步执行程序)的结果。它提供了检查计算是否完成的方法,以等待计算的完成,并检索计算的结果。通过Future对象可以了解任务执行情况,可取消任务的执行,还可获取执行结果。

正常情况下,如果不做特殊的处理,在主线程中是不能够捕获到子线程中的异常的。如果想要在主线程中捕获子线程的异常,我们需要使用ExecutorService,同时做一些修改。

(4)线程池

1)线程池的种类:

a.newSingleThreadExecutor 创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。如果这个线程异常结束,会有另一个取代它,保证顺序执行。单工作线程最大的特点是可保证顺序地执行各个任务,并且在任意给定的时间不会有多个线程是活动的。代码如下:

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class ThreadPoolExecutorTest {
    public static void main(String[] args) {
        ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();
        for (int i = 0; i < 10; i++) {
            final int index = i;
            singleThreadExecutor.execute(new Runnable() {
                public void run() {
                    try {
                        System.out.println(Thread.currentThread().getName() + ":" + index);
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            });
        }
    }
}

b. newScheduledThreadPool 创建一个定长线程池支持定时及周期性任务执行。延迟执行示例代码如下:表示延迟3秒执行

import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

public class ThreadPoolExecutorTest {
    public static void main(String[] args) {
        ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(5);
        scheduledThreadPool.schedule(new Runnable() {
            public void run() {
                System.out.println("delay 3 seconds");
            }
        }, 3, TimeUnit.SECONDS);
    }
}

c).newFixedThreadPool创建一个指定工作线程数量的线程池,可控制线程最大并发数,超出的线程会在队列中等待。newFixedThreadPool是一个典型且优秀的线程池,它具有线程池提高程序效率和节省创建线程时所耗的开销的优点。但是,在线程池空闲时,即线程池中没有可运行任务时,它不会释放工作线程,还会占用一定的系统资源。代码如下:

public class ThreadPoolExecutorTest {
    public static void main(String[] args) {
        ExecutorService fixedThreadPool = Executors.newFixedThreadPool(3);
        for (int i = 0; i < 10; i++) {
            final int index = i;
            fixedThreadPool.execute(new Runnable() {
                public void run() {
                    try {
                        System.out.println(Thread.currentThread().getName() + ":" + index);
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            });
        }
    }
}

d).newCachedThreadPool 创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程

这种类型的线程池特点是:

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

  • 工作线程的创建数量几乎没有限制(其实也有限制的,数目为Interger. MAX_VALUE), 这样可灵活的往线程池中添加线程。
  • 如果长时间没有往线程池中提交任务,即如果工作线程空闲了指定的时间(默认为1分钟),则该工作线程将自动终止。终止后,如果你又提交了新的任务,则线程池重新创建一个工作线程。
  • 在使用CachedThreadPool时,一定要注意控制任务的数量,否则,由于大量线程同时运行,很有会造成系统瘫痪。

public class ThreadPoolExecutorTest {
    public static void main(String[] args) {
        ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
        for (int i = 0; i < 10; i++) {
            final int index = i;
            try {
                Thread.sleep(index * 1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            cachedThreadPool.execute(new Runnable() {
                public void run() {
                    System.out.println(Thread.currentThread().getName() + ":" + index);
                }
            });
        }
    }
}

线程池为无限大,当执行第二个任务时第一个任务已经完成,会复用执行第一个任务的线程,而不用每次新建线程。

2)线程池参数问题:7个参数

java.uitl.concurrent.ThreadPoolExecutor类是线程池中核心的一个类,在ThreadPoolExecutor中提供了四个构造方法。通过源码可以发现,前面三个的构造器最后都是调用了第四个构造器进行初始化。

  • corePoolSize:核心线程大小。核心线程即为最小线程数,即使这些线程处于空闲状态也不会销毁。除非设置allowCoreThreadTimeout=true(默认false)时,核心线程会超时关闭。
  • maximumPoolSize:最大线程数。
  • keepAliveTime:空闲线程存活时间。当前线程数大于核心线程数时,在制定存活时间后,空闲线程后被销毁。
  • TimeUnit:空闲线程存活时间单位。
  • workQueue 工作队列:阻塞队列。用于存放等待执行的任务。一共有四种。
  1. ArrayBlockingQueue:基于数组的有界阻塞队列,按照FIFO顺序。可以防止资源耗尽问题。当前线程数如果>corePoolSize,再有新任务进来,向队列中存放任务,如果任务已满,如果当前线程数<maximumPoolSize,则创建新的线程。如果当前线程数>maximumPoolSize,采用拒绝策略。
  2. LinkedBlockingQueue:基于链表的无界阻塞队列(其最大容量为Interger.MAX),FIFO顺序。当前线程数如果>corePoolSize,再有新任务进来,会一直向队列中存放任务,而不创建新的线程。
  3. SynchronousQueue:一个不缓存任务的阻塞队列,生产者放入一个任务必须等到消费者取出这个任务。就是说有新的任务进来时,不会缓存,而是直接被调度执行该任务,如果没有可用的线程,则创建新的线程,如果线程数达到maximumPoolSize,则采用拒绝策略。
  4. PriorityBlockingQueue:具有优先级的无界阻塞队列,优先级通过Comparator参数实现。
  • ThreadFactory:线程工厂。创建线程使用的工程。
  • RejectedExecutionHandler:任务拒绝处理器。一共四种拒绝策略:
  1. CallerRunsPolicy
  2. AbortPolicy
  3. DiscardPolicy
  4. DiscardOldestPolicy

3)使用线程池会引发的问题:

Thread和Runnable的区别:最主要的区别就是Runnable可以避免java只能单继承的限制。

有的博客上面有讲到Runnable可以实现资源共享,只创建一个对象,多个线程同时获取对象资源。而Thread需要创建多个对象,因此资源时不共享的。(这种说法是不正确的,Thread也可以创建一个对象,同时多个线程共享资源

举例说明:假设电影院仅有10张票,一共有3个买票窗口,这个场景需要使用多线程来实现。

Thread

1) MyThread 类:线程必须用synchronized 实现线程安全。

class MyThread extends Thread {
    private int ticket = 10;
    public void run() {
        for (int i = 0; i < 10; i++) {
            synchronized (this){
            if (this.ticket > 0) {
                try {
                    Thread.sleep(100);
                    System.out.println(Thread.currentThread().getName()+"卖票了一张票,剩余:" + this.ticket--+"张票");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            }
        }
    }
}

2)错误写法:ThreadTicket 定义三个对象,三个窗口同时售票,这样总票数就不是10,而是每个窗口都有10张票,一共30张。

public class ThreadTicket {
    public static void main(String[] args) {
        MyThread mt1 = new MyThread();
        MyThread mt2 = new MyThread();
        MyThread mt3 = new MyThread();
        new Thread(mt1,"售票窗口1").start();
        new Thread(mt2,"售票窗口2").start();
        new Thread(mt3,"售票窗口3").start();
    }
}

错误写法运行结果:

正确写法:定义一个对象,使用三个线程共享资源

public class ThreadTicket {
    public static void main(String[] args) {
        MyThread mt = new MyThread();
        new Thread(mt,"售票窗口1").start();
        new Thread(mt,"售票窗口2").start();
        new Thread(mt,"售票窗口3").start();
    }
}

正确运行结果:

Runnable:

public class ThreadTicket {
    public static void main(String[] args) {
        MyThread mt = new MyThread();
        new Thread(mt,"售票窗口1").start();
        new Thread(mt,"售票窗口2").start();
        new Thread(mt,"售票窗口3").start();
    }
}

class MyThread extends Thread {
    private int ticket = 10;
    public void run() {
        for (int i = 0; i < 10; i++) {
            synchronized (this){
            if (this.ticket > 0) {
                try {
                    Thread.sleep(100);
                    System.out.println(Thread.currentThread().getName()+"卖票了一张票,剩余:" + this.ticket--+"张票");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            }
        }
    }
}

Thread通常是使用t.start();来启动线程的,因此创建几个线程,就需要创建几个对象,这样的话就存在资源不共享的情况。但是通过查看API发现:Thread是Runnable的实现类。所以启动Thread当然也可以使用new Thread(t).start();这样就实现了Thread的资源共享。

public class Thread extends Object implements Runnable

线程安全问题:多线程都存在线程安全问题。一共有三种方式来解决。

1)synchronized (this){}代码块;

2)synchronized 修饰方法;

3)Lock(ReentrantLock)显示锁(注意:需要显示上锁和释放锁)

这三种方式都能解决线程安全问题,但如果Thread采用多线程t.start();启动线程的话会产生多个对象,资源不共享,还是 存在线程安全问题,因此如果使用Thread,要尽量使用new Thread(t).start();启动线程

使用线程池要注意的问题:https://yq.aliyun.com/articles/706014

(1)避免死锁,请尽量使用CAS

(2)使用ThreadLocal要注意

ThreadLocalMap使用ThreadLocal的弱引用作为key,如果一个ThreadLocal没有外部强引用来引用它,那么系统 GC 的时候,这个ThreadLocal势必会被回收,这样一来,ThreadLocalMap中就会出现key为null的Entry,就没有办法访问这些key为null的Entry的value,如果当前线程再迟迟不结束的话,这些key为null的Entry的value就会一直存在一条强引用链:Thread Ref -> Thread -> ThreaLocalMap -> Entry -> value永远无法回收,造成内存泄漏。

10 gc方面的,怎么判断对象是否回收,怎么回收,分代回收,比例多少,大对象怎么分配,怎么判断是大对象

答:(1)引用计数法和可达性分析算法。(2)可达性分析后不可达的对象不是马上进行回收的,需要进行两次标记过程。第一次标记:判断该对象是否不要执行finalize()方法,如果该对象已经执行过finalize()方法或者没有重写该方法,则代表不需要执行,这样直接将该对象进行第二次标记,被回收;如果该对象需要执行finalize()方法,则将该对象放入到F-queue队列中,jvm自动创建一个低优先级的Finalizer线程执行对象的finalize()方法。再执行finalize()方法时,对象如果能够重新建立连接,那么该对象将摆脱这次回收,如果该对象没有重新建立连接,那么对该对象进行二次标记。二次标记的对象进行回收。(3)JVM分为三代,年轻代,老年代和持久代。年轻代和老年代是1:2。(4)大对象直接分配到老年代,大对象是指需要大量连续内存空间的对象。通过-XX:PretrnureSizeThreshold参数设置大对象。大小超过该参数的对象被认为是“大对象”,直接进入老年代。

11.集合了解哪些?Collection 和 Collections区别

答:

Collection :是接口,它的实现类有List和Set;Collections是类是针对集合的帮助类,集合搜索、排序等操作。

ps:Arrays.sortCollections.sort的实现原理:collections.sort方法底层就是调用的Array.sort方法

Arrays.sort()是针对数组的排序。主要分为对基本类型排序和对引用类型排序两种;

基本类型:当数组大小小于48时,参数leftmost==true时,采用的是原始的插入排序方法,当leftmost==false时,采用的是优化的插入排序方法(一次性插入两个数值),具体思路:

1.将要插入的数据,第一个值赋值a1,第二个值赋值a2,

2.然后判断a1与a2的大小,令a1要大于a2。

3.接下来,首先是插入大的数值a1,将a1与k之前的数字一一比较,直到数值小于a1为止,把a1插入到合适的位置,

4.接下来,插入小的数值a2,将a2与此时k之前的数字一一比较,直到数值小于a2为止,将a2插入到合适的位置

5.如果最后剩下一个,就把最后一个没有遍历到的数据插入到合适位置

当数组大小小于286时,采用的是双基准快速排序方法,具体思路:

1.选择两个枢纽元p1,p2,一般选择起始元素a[left]和末尾元素a[right](有其他选取方式)。

2.假设p1<p2,如果不是就交换。

3.基于这p1,p2将整个数组分成三部分,<p1的,p1<&<p2的,>p2的。

4.递归排序这三个部分。

当数组大小大于128时,采用的是合并排序方法,

引用数据类型:存在一个参数LegacyMergeSort.userRequested

LegacyMergeSort.userRequested==true时,当数组大小小于48时,调用的时传统的插入排序当大于48时,调用改进的合并排序(对于已经排好序的,不再进行比较,而是直接复制过去,提高效率)

LegacyMergeSort.userRequested==false时,调用TimSort.sort方法(一种起源于归并排序和插入排序的混合排序算法,O(n)~O(nlogn)是目前最优的排序算法),具体思路:

1.扫描数组,确定其中的单调上升段和严格单调下降段,将严格下降段反转;

2.定义最小基本片段长度,短于此的单调片段通过插入排序集中为长于此的段;

3.反复归并一些相邻片段,过程中避免归并长度相差很大的片段,直至整个排序完成,所用分段选择策略可以保证O(n log n)时间复杂性。

TimSort 算法为了减少对升序部分的回溯和对降序部分的性能倒退,将输入按其升序和降序特点进行了分区。排序的输入的单位不是一个个单独的数字,而是一个个的块-分区。其中每一个分区叫一个run。针对这些 run 序列,每次拿一个 run 出来按规则进行合并。每次合并会将两个 run合并成一个 run。合并的结果保存到栈中。合并直到消耗掉所有的 run,这时将栈上剩余的 run合并到只剩一个 run 为止。这时这个仅剩的 run 便是排好序的结果。
就是找到已经排好序数据的子序列,然后对剩余部分排序,然后合并起来

12.说说TCP?三次握手 两次不行?,四次挥手,说说TCP的流量控制、拥塞避免

答:TCP 是面向连接的传输层协议。每一条 TCP 连接只能有两个端点(endpoint),每一条 TCP 连接只能是点对点的(一对一)
TCP 提供可靠交付的服务,TCP 提供全双工通信,面向字节流。

三次握手,四次挥手

https://blog.csdn.net/m0_37950361/article/details/79713970

秋招面试题(360)相关推荐

  1. 2022前端秋招面试题总结 阿里 腾讯 字节 百度 网易 京东 小红书 快手面试记录

    2022前端秋招面试题总结 阿里 腾讯 字节 百度 网易 京东 小红书 快手面试记录 等了百度三个月,终于发offer了,白菜价,92大佬们拒的薪资,我知足了. 排序挂了狠多,快手,蚂蚁,- 很绝望 ...

  2. 2020大疆秋招笔试题B卷

    2020大疆秋招笔试题B卷 选择题(选项没抄下来)10道记了9道 1.关于常指针和指向常量的指针 2.多线程调用如下函数,a,b,c哪些需要加锁保护 int a = 0; void knit() {s ...

  3. 2021网易秋招笔试题(Android开发)

    网易笔试题(2021.08.08) 校招的笔试题通常是4道编程题,时间为2个小时,每题25分. 2021秋招笔试题总结如下,包含问题和代码实现. 题1:查找关键词 查找关键词(单词在文章中出现频率&g ...

  4. 秋招面试题系列- - -Java工程师(十一)

     前言:七月末八月初的时候,秋招正式打响,公司会放出大量的全职和实习岗位.为了帮助秋招的小伙伴们,学长这里整理了一系列的秋招面试题给大家,所以小伙伴们不用太过焦虑,相信你们一定能超常发挥,收到心仪公司 ...

  5. 腾讯 2015秋招笔试题 编程题2:九宫格填数

    腾讯 2015秋招笔试题 编程2:九宫格填数 题目 2: 有下图的题解,请用 C/C++ 代码来列出满足下图 0-100 内的所有答案. 配合加减乘除,使得九宫格横竖都等于4. 智力冲浪 数字推理 请 ...

  6. 2022 Java秋招面试题-必备基础

    文章目录 2022 Java秋招面试题-必备基础 一.语言基础 Java技术栈基础-语言基础 Java技术栈基础-spring Java技术栈基础-netty 二.面向对象 三.存储 redis my ...

  7. 字节跳动-2020秋招-笔试题剖析【5道算法题】

    字节跳动-2020秋招-笔试题剖析[5道算法题],限时120分钟. 让我们一起来看看这些题吧! 题一:模型文件去重 [题目描述] 抖音上不同的用户类型我们有不同的用户模型文件. 我们有一个模型配置文件 ...

  8. 酷狗java秋招笔试题

    酷狗java秋招笔试题 单选题 1.在命中率极高的缓存设计中,时间复杂度最差的数据结构是( B ). A. 数组 B. 链表 C. 树 D. 哈希表 2.某二叉树共有11个结点,其叶子结点只有2个.则 ...

  9. 秋招面试题系列- - -Java 工程师(一)

    前言:七月末八月初的时候,秋招正式打响,公司会放出大量的全职和实习岗位.为了帮助秋招的小伙伴们,学长这里整理了一系列的秋招面试题给大家,所以小伙伴们不用太过焦虑,相信你们一定能超常发挥,收到心仪公司的 ...

  10. 字节跳动2020届秋招笔试题

    字节跳动2020届秋招第一批笔试题(2019.8.11) 文章目录 字节跳动2020届秋招第一批笔试题(`2019.8.11`) 第一题[编程题25分]: 闹钟叫醒去上课 第二题[编程题25分]: 秘 ...

最新文章

  1. 静态Web服务器-多任务版
  2. 利用 pywin32 操作 excel
  3. java中包命名常见规则
  4. VS2010编译安装OpenCV2.4.3
  5. 风机桨叶故障诊断(三) 识别桨叶——初步构建BP神经网络
  6. 五行塔怎么吃第五个_中医美容——“五行美容养颜法”,善用五行,女人会越来越漂亮...
  7. OpenCV辅助对象(help objects)(3)——Ptr
  8. Elasticsearch--Docker安装ES---全文检索引擎ElasticSearch工作笔记002
  9. WebView无法放大缩小解决方案
  10. django-orm的表操作.
  11. 递归加载无限级分类,虽然我觉得效率不太好。
  12. java调用flex_转载:在JavaScript中调用Flex方法
  13. 箭头函数写法_初探ES6:箭头函数
  14. VARCHART XGantt 甘特图中的日期和夏令时
  15. SPI转can芯片CSM300详解以及Linux驱动移植调试笔记
  16. iOS之获取手机DeviceToken,以及苹果测试推送工具Easy APNs Provider
  17. 数码计算机英语单词,数码相机的规格词汇中英对照
  18. P3406 海底高铁(前缀和+差分+坑点)
  19. c++ 递归算法求全排列
  20. ckeditor富文本编辑器的使用和图片上传,复制粘贴图片上传

热门文章

  1. BST Application
  2. 基于标签的网络入侵问题
  3. linux设置无线网络
  4. 一个游戏开发者的反思—缺陷与出路
  5. android 自定义主题样式
  6. 【DEVOPS】实现Swagger2应用接口文档Word格式的在线实时更新
  7. Java中的抽象方法
  8. which 命令的用法
  9. gofunc - 简单好用的go test工具
  10. Spring Boot单元测试方法Failed to load ApplicationContext