最近准备面试,所以会收集一些不懂得题目然后进行答案的搜索,以下答案基本都是来自网络,然后进行了一点删减和自己的总结,如果有侵权,请评论或者私信联系我,我马上删除


ReentrantLock实现原理

答:内部有一个NonfairSync/FairSync静态内部类,继承于同样是静态内部类的Sync类,Sync继承了AbstractQueuedSynchronizer,在lock()调用的时候实际上是调用这个Sync类的lock方法,这个Sync类的lock方法是实现了AQS的lock方法,使用了CAS比较并交换的方法去试图获取一个锁

如果成功就设置当前线程为获得者,并且把数值变为1,如果获取失败就执行acquire->tryAcquire->nonfairTryAcquire方法,就是再获取一次锁,如果还是失败就加入到阻塞队列中,nonFairSync即使是也会添加;通过 addWaiter 方法将当前线程封装成 Node 添加到 AQS 队列尾部,然后acquireQueued,将 Node 作为参数,如果此时node前面就是head并且锁已被释放,就可以拿锁;如果前面不是,则进入阻塞状态(使用LockSupport中的函数)等待下一次判断(自旋),并设置状态为signal;如果获取失败并且当前线程不是该锁的拥有者,并且队列加入也失败,那就执行中断

NonfairSync和FairSync的区别就是在获取锁时是否先进行CAS去抢占锁,然后再考虑队列

tryLock()方法是非阻塞式的,普通的lock()是阻塞式的

unlock()方法会使同步量减一,如果为零了,那就把锁拥有者清空,并唤醒下一个线程.如果下一个线程不存在或者状态不正常,就从尾部向前唤醒,保证别的线程添加节点时的正常操作

park()和unpark()操作代表线程挂起和唤醒

final boolean acquireQueued(final Node node, int arg) {boolean failed = true;try {//表示是否被打断boolean interrupted = false;for (;;) {//获取node.pre节点final Node p = node.predecessor();if (p == head //当前节点是否是同步队列中的第二个节点&& tryAcquire(arg)) {//获取锁,head指向当前节点setHead(node);//head=head.nextp.next = null;//置空 failed = false;return interrupted;//返回是否被中断过}if (shouldParkAfterFailedAcquire(p, node) && //是否阻塞(因为阻塞唤醒是个耗时操作,进入阻塞前判断pre节点状态.如果pre节点即将释放锁,则不进入空转)parkAndCheckInterrupt())//利用unsafe.park()进行阻塞interrupted = true;//如果Thread.interrupt()被调用,(不会真的被打断,会继续循环空转直到获取到锁)}} finally {if (failed)//tryAcquire()过程出现异常导致获取锁失败,则移除当前节点cancelAcquire(node);}
}

用过CountDownLatch么?什么场景下用的?

答:就像是AtomicInteger的另一个版本,创建对象时设置一个数,然后使用countDown()方法进行CAS减一操作,直至减到0时返回true

只不过内部依然是使用的Sync继承AQS来实现的。CountDownLatch是一次性的

可以用于多个线程不按顺序同时工作,并需要在主线程中判断所有工作是否完成的情况,设置为对应线程数,每个线程完成对应的任务之后就减一,在主线程完成自己的活之后,循环判断countDownLatch是否为0,就可以知道任务是否都完成了。


AQS底层原理

答:AQS内部有一个静态内部类Node,是由线程和状态变量组成的;AQS内部有一个双向队列,以Node为节点,当有新的线程获取锁失败时,添加到tail之后,并把新的这个节点设置为tail(此过程需要CAS来保证成功)。如果获取锁成功,就是添加到头部,此方法不需要CAS因为添加的动作肯定是锁获得者,一定安全。

AQS 是一个同步双向链表,它能够实现线程的阻塞以及唤醒,但它并不具备业务功能,所以在不同的同步场景中,会继承 AQS 来实现对应场景的功能


加锁会带来哪些性能问题。如何解决?偏向锁、轻量级锁、重量级锁?

答:三种锁用于synchronized的底层jvm优化中,并且只能沿着偏向->轻量级->重量级的方向演进

如果一个锁只被一个线程获取过,那就直接设置为偏向锁,在锁的对象头中设置对应线程的id,不需要设置互斥量

假如出现了锁竞争,那就直接膨胀为轻量级锁,跟偏向锁类似,但仍然不需要设置互斥量。如果轻量级锁通过自旋失败,再膨胀为重量级锁;适用于持有锁的线程能在很短时间内释放锁资源。

重量级锁由于需要设置互斥量,并且挂起、恢复线程,因此会有性能损失.

尽可能地减少锁的出现与持有时间! JIT编译器的逃逸分析也会对没必要的锁进行锁消除,但不能依赖编译器优化


出现 OOM 后怎么排查问题?

答:1、万事先找到java的pid:ps -aux | grep java

2、可以用top查看内存情况

3、jmap -参数 pid 把java虚拟机内存弄进一个快照,查看堆、元空间的对象情况,查看哪种对象最多

4、使用一些分析工具(jstat)查看gc情况

5、不只是OOM要进行排查,太过频繁的full gc也应该进行排查与优化

6、如果是设置的内存太小,应该调大内存

7、最容易出现内存不足的情况:从mysql中取出大量的数据进行处理


手写LRU 缓存

class LRUCache extends LinkedHashMap<Integer, Integer>{private int capacity;public LRUCache(int capacity) {super(capacity, 0.75F, true);this.capacity = capacity;}public int get(int key) {return super.getOrDefault(key, -1);}public void put(int key, int value) {super.put(key, value);}@Overrideprotected boolean removeEldestEntry(Map.Entry<Integer, Integer> eldest) {return size() > capacity; }
}

什么时候需要自定义类加载器?

答:1、加密源码。因此java代码容易被反编译 2、从非标准的来源加载代码 3、动态创建


ConcurrentHashMap原理?

答:HashTable是线程安全的原因是因为在方法上使用synchronized,效率很低

ConcurrentHashMap采用了"分段锁"的思想,多线程访问不同的数据段时不会竞争同一个锁,可以提高效率。

**JDK1.7版本:**拥有多个Segment<K,V>,每一个segment都是一个HashEntry<K,V>[] table即一个Entry数组,就相当于一个小HashMap

并且Segment继承了ReentrantLock,可以作为互斥锁使用。put时根据key的hash查找对应的Segment,跟HashMap查找table上的位置是一样的,然后用头插法进行插入

**JDK1.8版本:**取消了Segment,采用volatile HashEntry<K,V>[] table,跟HashMap相比多了一个volatile关键字,并采用synchronized和CAS来进行操作。并且与HashMap的更新同步,采用链表加红黑树的结构。而TreeNode又有一层TreeBin的包装类作为根节点并带有读写锁。

put操作:首先进行底层数组是否为空的判断,如果是就进行数组初始化。然后计算得到key对应的位置,如果是空则通过CAS试图去插入节点,如果对应的位置上的状态是正在进行拓展,则帮助它进行拓展。如果这个位置已经有数据了,那就使用synchronized锁住然后插入(根据链表/红黑树进行插入,尾插法),然后再判断是否需要转换或退化红黑树(如果已经存在key,则修改值)。

初始化的过程也会对当前的状态进行判断,如果在当前线程将要进行初始化的时候发现状态量是正在初始化,则yield()让步。(MOVED:-1表示正在扩容)

get操作:当key为null时抛出异常;计算key的hash值对应的数组,遍历。如果找到就返回值,否则返回null;如果遇到扩容的时候,会调用标志正在扩容节点ForwardingNode的find方法,查找该节点,匹配就返

**同步机制:**1、读操作:在get操作中,没有使用同步机制,也没有使用unsafe方法,所以读操作是支持并发操作的。并且由于node节点的setValue是不支持的,只能进行原子性的等号赋值,所以可以保证拿到的就是同一个值

2、扩容是通过transfer方法来进行的。而调用transfer方法的只有trePresize(树化操作时)、helpTransfer(正在扩容时加入帮忙)和addCount(操作数组导致数组元素增加)三个方法

3、当在进行数组扩容的时候,如果当前节点还没有被处理(也就是说还没有设置为fwd节点),那就可以进行设置操作。如果该节点已经被处理了,则当前线程也会加入到扩容的操作中去

4、sizeCtl负数代表正在进行初始化或扩容操作、-N 表示有N-1个线程正在进行扩容操作,正数或0代表hash表还没有被初始化,这个数值表示初始化或下一次进行扩容的大小

5、计算元素数量时,使用baseCount+countCell数组,countCell数组是多个线程对元素的增减数量


Synchronized与ReentrantLock区别?CAS和synchronize有什么区别?

答:1、Lock是一个接口,synchronized是Java中的关键字,synchronized是内置的语言实现

2、synchronized发生异常时,会自动释放线程占用的锁,故不会发生死锁现象。Lock发生异常,若没有主动释放,极有可能造成死锁,故需要在finally中调用unLock方法释放锁;

3、Lock可以让等待锁的线程响应中断,使用synchronized只会让等待的线程一直等待下去,不能响应中断

4、通过Lock可以知道有没有成功获取到锁,synchronized就不灵

5、ReentrantLock可以是公平锁,而synchronized只能是非公平锁

6、ReentrantLock主要使用CAS,synchronized可以由偏向、轻量、重量级锁演进,如果能用synchronized的话尽量使用它


HashMap存储了50w的数据,给出最快速的遍历方法

答:用entrySet进行遍历


Semaphore用过吗?

答:Semaphore就相似于ReentrantLock的多值版本,如果设值为1,就约等于ReentrantLock。与CountDownLatch不同的是CountDownLatch只能减,而Semaphore的acquire减完之后要release去加回去


CompletableFuture用过吗?

答:CompletableFuture类实现了CompletionStage和Future接口,是一个用来实现异步功能的类,它可以通过传入一些函数式接口实现来进行异步的流程处理,并自行处理最终的结果;原先的Future的话采用的是轮询的方法去获得结果,而CompletableFuture使用传入的函数式进行结果的处理。

//采用异步的方法,得到hello后,调用join回到主线程,此时s = hello
String s = CompletableFuture.supplyAsync(() -> ("hello")).join();
//还可以调用thenAccept thenRun等方法

JVM有了解吗?JVM中参数 –Xms 和 -Xmx 是什么意思?

答:JVM是操作系统和java程序之间的一个桥梁,模拟了一个运行环境;

–Xms:设定堆内存的起始大小 –Xmx :设定堆内存的最大大小 -Xmn:memory newgeneration新生代内存 –Xss:设定stack size每个线程的堆栈大小


fast-fail和fast-safe?

答:Iterator的安全失败fast-safe是基于对底层集合做拷贝,因此它不受原集合上修改的影响。java.util包下面的所有的集合类都是快速失败的,而java.util.concurrent包下面所有的类都是fast-safe的。快速失败fast-fail的迭代器会抛出ConcurrentModificationException异常。

在调用 next()remove()时,都会执行 checkForComodification()去检查ExpectModCount与ModCount是否一致;无论是add()、remove(),还是clear(),只要涉及到修改集合中的元素个数时,都会改变modCount的值。所以在多线程访问和修改的情况下就会出现fast-fail情况。

CopyOnWriteArrayList在进行添加操作的时候,将原数组进行一次复制,在复制的数组上进行操作并替代原数组,并且在这个过程中是加锁的,可以保证安全,但是速度有所下降。CopyOnWriteArrayList的迭代器是内部设计的,迭代器所访问的数组是不变的,即其他线程的修改引起了原list的数组中对象的改变,此时迭代器中所访问的数组依然不变。因此,这个迭代器是只读的,其他操作会抛出异常。


解决哈希冲突的四种方法

答:1、开放定址法:一旦发生了冲突,就去寻找下一个空的散列地址。为减少冲突,要求装填因子α较小,故当结点规模较大时会浪费很多空间

2、再哈希法:一次哈希不行就再哈希一次,但是会浪费计算。

3、链地址法:使用链表代替节点,但是指针需要额外的空间

4、公共溢出区:冲突溢出的部分放在专门的区域


HashMap为什么不是线程安全的?(JDK1.7和1.8的不同)

答:主要存在两个不安全的情况:putresize

put时,如果有链表a->b,此时线程1持有c,线程2持有d,都要插入到b之后。若线程1拿到b准备插入c时,线程2进入并在b后插入了d,那么回到线程1插入c之后,d就丢失了,即造成了数据丢失的情况

JDK7中,resize时使用头插法。若有链表a->b->c,扩容时插入到另一链表中,若此时插入a完成,准备插入b,另一线程进入完成了resize,则另一链表此时为c->b->a,回到原先的线程,a插入完毕准备插入下一个节点,发现下一个节点时b,就会造成死循环

JDK8中改为尾插法之后,就不会出现这种问题,但是put问题依然存在


线程池的线程数怎么确定?如果是IO操作、计算型为主怎么确定?

答:根据任务的不同类型进行区分。由于IO操作在IO过程中不需要使用到cpu因此可以使用多个线程,而计算型不应该频繁切换cpu

  • 如果是CPU密集型应用,则线程池大小设置为N+1 (N为CPU总核数)

  • 如果是IO密集型应用,则线程池大小设置为2N+1 (N为CPU总核数)

  • 可以在这两者的基础上进行优先级的顺序安排


写个BlockingQueue?阻塞队列有没有看过底层是怎么实现的?

答:以BlockQueue为例,其内部有两个锁:take锁和put锁(ReentrantLock),和一个原子计数器(AtomicInteger)

当offer时,锁住put锁,进行入队操作,并把计数器加一

当poll时,锁住take锁,进行出队操作,并把计数器减一

如果是要移除、查询中间的某个节点,或是进行其他非首尾节点的操作,那就要把两个锁都锁住

当队列的size == capacity时,用Condition notfull的notFull.await()再套个while去阻塞,当size + 1 < capacity时,用notfull的signal()去唤醒被阻塞的现场。与上述情况相反的是notEmpty的使用,即队列为空时阻塞想要poll的线程

//利用阻塞队列可以实现消费者-生产者模型
private static BlockingQueue<String> blockingDeque = new ArrayBlockingQueue<String>(5);//生产者进行生产...
blockingDeque.put("food");//消费者进行消费...
String food = blockingDeque.take();

AtomicInteger的底层?使用?

答:底层使用是sun.misc下的unsafe类和CAS操作,是一个类似c++可以直接操作内存的类,在AtomicInteger初始化是会去获取类的地址,后续unsafe就在这个地址上进行操作。直接进行底层的操作,好处是保证了原子性,坏处是有安全问题,因此unsafe类在jdk9中被删除了。并且AtomicInteger不能解决ABA问题。

常用方法有**getAndIncrement()**加返旧、**getAndDecrement()**减返旧、getAndAdd(int delta)加n返旧、addAndGet(int delta)加n返新、incrementAndGet()加返新、decrementAndGet减返新


Java中线程的状态?
  1. 新建状态(New): 线程对象被创建后,就进入了新建状态。例如,Thread thread = new Thread()。

  2. 就绪状态(Runnable): 也被称为“可执行状态”。线程对象被创建后,其它线程调用了该对象的start()方法,从而来启动该线程。例如,thread.start()。处于就绪状态的线程,随时可能被CPU调度执行。

  3. 运行状态(Running): 线程获取CPU权限进行执行。需要注意的是,线程只能从就绪状态进入到运行状态。

  4. 阻塞状态(Blocked): 阻塞状态是线程因为某种原因放弃CPU使用权,暂时停止运行。直到线程进入就绪状态,才有机会转到运行状态。阻塞的情况分三种:

    (01) 等待阻塞 – 通过调用线程的wait()方法,让线程等待某工作的完成。
    (02) 同步阻塞 – 线程在获取synchronized同步锁失败(因为锁被其它线程所占用),它会进入同步阻塞状态。
    (03) 其他阻塞 – 通过调用线程的sleep()或join()或发出了I/O请求时,线程会进入到阻塞状态。当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入就绪状态。

  5. 死亡状态(Dead): 线程执行完了或者因异常退出了run()方法,该线程结束生命周期。


join()、yield()方法是干什么?

yield() 方法和 sleep() 方法类似,也不会释放“锁标志”,区别在于,它没有参数,即 yield() 方法只是使当前线程重新回到可执行状态,所以执行 yield() 的线程有可能在进入到可执行状态后马上又被执行,另外 yield() 方法只能使同优先级或者高优先级的线程得到执行机会,这也和 sleep() 方法不同。
join() 方法会使当前线程等待调用 join() 方法的线程结束后才能继续执行。比如在main中调用线程A.join() 会等线程A执行完再继续执行main

join就像是完全让开,而yield是只让上级,并且不交出锁,而且有可能继续执行


wait(),notify() 及 notifyAll() ?

答:都是 Object 类的方法,wait(),notify() 及 notifyAll() 只能在 synchronized 语句中使用,但是如果使用的是 ReenTrantLock 实现同步,该如何达到这三个方法的效果呢?解决方法是使用 ReenTrantLock.newCondition() 获取一个 Condition 类对象,然后 Condition 的 await(),signal() 以及 signalAll() 分别对应上面的三个方法。


ThreadLocal了解吗?原理?为什么会发送内存泄漏?使用的是开放地址法?

答:Thread类中有两个变量threadLocals和inheritableThreadLocals,二者都是ThreadLocal内部类ThreadLocalMap类型的变量

ThreadLocal内的方法调用的是当前线程中的threadLocals变量把当前这个ThreadLocal变量作为key,传入的value作为value设置进对应线程的map,即currentThread.threadLocals中。

注意,ThreadLocalMap不是HashMap,结构类似但是内部的Entry是WeakReference<ThreadLocal<?>> 弱引用

发生内存泄漏的原因:ThreadLocalMap的这个ThreadLocal被gc了,则当前线程的这个map里key变为null,但value依然存在,则这个线程不停止,这个value就无法被回收,造成内存泄漏

若ThreadLocalMap的Entry使用的是强引用,则不主动删除的话,ThreadLocal变量会伴随到全部使用它的线程的死亡才被回收

即强引用的话会造成key(ThreadLocal)和value两者内存泄漏,弱引用的话最多造成value的内存泄漏

将ThreadLocal变量定义成private static,这样就一直存在ThreadLocal的强引用,也就能保证任何时候都能通过ThreadLocal的弱引用访问到Entry的value值,进而清除掉

InheritableThreadLocal则是提供了一种子线程访问父线程的方法:把父线程的InheritableThreadLocal赋给子线程

使用开放地址法的原因:线程数一般较少,使用开放地址法比较节省空间,并且不用遍历链表,效率较高


TreeMap查询、写入的时间复杂度多少?底层数据结构?

答:O(logN)。底层数据结构是红黑树,红黑树需要满足以下几点:

1、每个节点都只能是红色或者黑色

2、根节点是黑色

3、每个叶节点(NIL节点,空节点)是黑色的。

4、如果一个结点是红的,则它两个子节点都是黑的。也就是说在一条路径上不能出现相邻的两个红色结点。

5、从任一节点到其每个叶子的所有路径都包含相同数目的黑色节点

put节点时,找到合适的位置插入再进行旋转;删除节点时,用特定的叶子节点(右分支最左边 或者 左分支最右边)替代要删除的节点再进行旋转


Arrays.sort()用的是什么算法?

答:元素小于47个时用插入排序,47到286用快排,大于296用归并排序。但也不是绝对,比如大于286但是不具备归并排的区间升区间降,就会用快排


如何用cglib来实现动态代理

答:使用一个Enhance增强器和一个MethodInterceptor方法拦截器

//MethodInterceptor内的方法
public Object getProxy(Class clazz) {enhancer.setSuperclass(clazz);enhancer.setCallback(this);return enhancer.create();//实现此方法进行增强
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable

GC Roots?

答:1、各个线程的局部变量 2、类的静态变量 3、方法区中常量引用的对象 4、被synchronized锁住的对象 5、虚拟机内部的引用如基本数据类型的Class对象等

小技巧:由于Root采用栈方式存放变量和指针,所以如果一个指针,它保存了堆内存里面的对象,但是自己又不存放在堆内存里面,那它就是一个Root

btw:System.gc()和Runtime.gc()没有区别,System.gc()调用了Runtime.gc()


逃逸分析?

答:一、同步省略。如果一个对象被发现只能从一个线程被访问到,那么对于这个对象的操作可以不考虑同步。

二、将堆分配转化为栈分配。如果一个对象在子程序中被分配,要使指向该对象的指针永远不会逃逸,对象可能是栈分配的候选,而不是堆分配。

三、分离对象或标量替换。有的对象可能不需要作为一个连续的内存结构存在也可以被访问到,那么对象的部分(或全部)可以不存储在内存,而是存储在CPU寄存器中。


垃圾回收器?G1?CMS?

答:

在jvm的client模式下用的是Serial + SerialOld组合,对于这种垃圾量小且单核的情况比较适用

ParNew回收器相当于Serial的多线程版,ParNew + SerialOld模式在JDK8已经标记为过时,ParNew一般与CMS一起使用

Parallel Scavenge + Parallel Old组合是JDK8的默认组合,以高吞吐量为目标,并具有自适应调节功能

CMS回收器以低延迟为目标,先进行初步标记(stw)然后与用户线程一起运行时进行并发标记,然后再次STW进行重新标记,接下来就可以进行一次并发清除了,最后用重置线程进行收尾。如果内存碎片太多的话,则依然需要一次SerialOld来兜底。常与ParNew进行搭配使用。如果改为标记整理的话,会对用户线程造成影响

**G1(Garbage First)**回收器:是新生代和老年代同时的算法,将内存看作一个个的小块,每个小块可以是Eden或是Survivor或是old区,在回收时维护一个队列,按照回收后的效益进行排序,回收时将要回收的小块用标记复制算法到另一个空闲小块中,如果是比较大的对象,G1中还有一种针对于大对象的块,是连续的。虽然用标记复制算法但是从效果上看更像是标记整理。由于可以知道回收的小块的数量,因此可以预测大概的回收时长是多少。与CMS相比,最好不一定有它好,但最坏一定比它好。在大内存的情况下,G1会有优势。G1采用了Remembered Set来记录本小块指向了哪些小块,因此会有性能消耗,但不需要进行全部小块的扫描

混合回收:回收新生代和部分老年代(1/8);根区域扫描->并发标记->再次标记->独占清理(只是排序,找要回收的小块)->并发清理

full gc:如果以上效果不好,则进行一次full gc(串行)

命令:-XX:+UseXX垃圾回收器


JDBC是如何实现和数据库连接的,基于什么协议?

答:使用的应该是封装的TCP/IP协议,具体实现应该是类似于SSH连接这种吧


JDBC中的PreparedStatement有哪些优点

答:是一个预编译的语句执行器,所以主要是预编译的好处:1、可以批量处理数据,因为要填入的数据已经提前可知了

2、预编译防止sql注入 3、当然,单条语句的执行没有普通的Statemen快


new一个对象的过程?

答:1、查看常量池中是否有这个类的符号引用 2、如果还没加载过类,就进行父类、类的加载(双亲委派) 3、为对象分配一个内存空间:指针碰撞、空闲列表 4、对数据类型都赋0值 5、对对象头进行设置:GC年龄等等 6、调用init方法 7、创建栈中引用


啥时候破坏双亲委派?

答:系统类加载器需要加载用户类时,比如JDBC中驱动的加载,使用的就是系统类加载器.实现方法就是重写类加载器的loadclass方法


如何判断一个JVM进程是否发生了内存泄漏?

答:1、首先查看关键容易出现泄漏的代码段

2、查看整个JVM进程的内存使用情况是否符合预期

3、查看新生代老年代的对象数量


hazy的面试小笔记之Java(持续更新)相关推荐

  1. Vue -- 指令【学习笔记】(持续更新)

    Vue – 指令[学习笔记](持续更新) 记录了Vue第三天的学习笔记 v-show 注意,v-show 不支持 <template> 元素,也不支持 v-else. 带有 v-show ...

  2. 尚硅谷(李立超)——HTML5CSS3笔记总结【持续更新】

    尚硅谷(李立超)--HTML5&CSS3笔记总结[持续更新] 本文适合前端菜鸟食用,小编自己整理的李立超老师视频的笔记,手打不易,那就望您每年快乐吧.逃) 一.进制 1.十进制(日常使用): ...

  3. 前端(js/css/html)那些小的知识点,持续更新......

    前端(js/css/html)那些小的知识点,持续更新...... 1.行内元素与块级元素有哪些及区别? 块级元素和行内元素的区别是,块级元素会占一行显示,而行内元素可以在一行并排显示.通过样式控制, ...

  4. 全部文章分类与整理(找工作+面试+资源分享),持续更新

    阅读本文大概需要 6 分钟 由于本公众号发表的文章有点多,并且发的文章也不是一个专题一个专题这样发的,所以难免有读者过来找我吐槽说,想搜索历史的文章,不太方便. 鉴于此,为了大家阅读文章方便,我整理了 ...

  5. 2019最新Web前端经典面试试题及答案,持续更新

    Ps: 文章所述内容,来源渠道平时积累以及网上摘录.按日期持续更新...目录: 转载请注明来源. -2018/6/8   1.position的定位方式 2.描述下从输入URL到整个网页加载完毕及显示 ...

  6. 最实用的微信小程序大全,持续更新中...

    最全的小程序开发教程,点击下载掘金App. 小程序上线 1月9日,张小龙没有食言,微信小程序如约而至.凌晨刚过,我们便在微信发现页看到了小程序的入口. 微信发现页 之后的一个小时里,每个微信群都在疯狂 ...

  7. 个人学习笔记汇总(持续更新)

    白墨的个人学习笔记 HTML JAVA Python MySQL 等待添加 说明 大家好,这里白墨,话不多说,先放笔记: HTML HTML笔记 JAVA JAVA笔记Myeclipse快捷键占位符的 ...

  8. AutoCAD2019+vs2019+C# 二次开发学习笔记day01(持续更新)

    目录 一.新建项目 1.应用程序 目标框架 选择 4.7.2版 2.生成 目标平台选择x64 3.调试 启动外部程序 选择 acad.exe 二.添加autocad类库 三.如何运用命名空间 1.[C ...

  9. 数据结构(Java)-持续更新补充

    复习一下数据结构,巩固一下基础. 之后打算再学一下算法,之前刷题总感觉摸不清门道,应该是概念没彻底搞明白. 栈 import java.util.Arrays;public class Stack { ...

  10. 2020年Java面试题及答案_Java面试宝典_Java笔试题(持续更新中)

    推荐面试视频教程 2019年最新Java互联网大厂面试精粹 前言 前言: 少年易老学难成,一寸光阴不可轻.未觉池塘春草梦,阶前梧叶已秋声 .-朱熹<劝学诗> 勤奋才是改变你命运的唯一捷径. ...

最新文章

  1. 飞机的“黑色十分钟”能被人工智能消灭吗?
  2. 超实用总结:AI实践者需要用到的10个深度学习方法
  3. exit的用法python_python 中exit,sys.exit,os._exit用法
  4. java jxl创建多个sheet,使用jxl导出excel时怎么创建多个sheet | 学步园
  5. java学习(89):Charactor包装类统计
  6. python图像分类代码_Kaggle—So Easy!百行代码实现排名Top 5%的图像分类比赛
  7. 0626 Django模型(ORM)
  8. 洛谷 P2010 回文日期
  9. java的jdk和jre有什么区别
  10. 红胖子创业一年整总结:前二十年题记,萌芽初期,外包初期,创业初期,未来规划
  11. 魔兽争霸lostTemple地图
  12. mysql every derived table must_Mysql错误Every derived table must have its own alias解决方法
  13. 什么是「设计模式」?
  14. java 代码箭头代表什么_箭头运算符' - '在Java中做什么?
  15. 跟涛哥一起学嵌入式 26:深入浅出计算机编码、乱码问题
  16. Zabbix 配置钉钉告警
  17. SAP 财务校验(基本内容及常用财务校验配置涉及退出提供源代码)
  18. Java十六进制操作
  19. UGUI Text组件上动态显示Emoji
  20. 什么是分库分表?为什么需要分表?什么时候分库分表

热门文章

  1. windows s2019安装crucible-4.8.2
  2. 无线路由器DNS服务器异常,fast无线路由器dns异常的解决方法
  3. 查询淘宝京东商品历史价格的方法
  4. 什么是数据结构?是举一个例子,叙述逻辑结构、存储结构和运算三个方面的内容。
  5. 同花顺没签三方要赔钱才能拿回三方!!!!
  6. win10子系统基本备份
  7. 纯电动汽车架构设计(一) :电动车架构设计核心与前悬架选择
  8. openwrt默认mac地址配置(MT7620a)
  9. Permission denied: user=10273, access=WRITE, inode=“/cou/jd_phone_list“:root:supergroup:-rw-r--r--
  10. 网站被劫持,打开一个网站会跳到另一个怎么办,直接输入网址也是这样。怎么办呢?