我最近参加了一次采访,我被问到"编写一个程序,从10亿个数字中找出100个最大的数字."
我只能给出一个强力解决方案,即以O(nlogn)时间复杂度对数组进行排序并获取最后100个数字.
Arrays.sort(array);
Run Code Online (Sandbox Code Playgroud)
面试官正在寻找更好的时间复杂性,我尝试了其他一些解决方案但未能回答他.有更好的时间复杂度解决方案吗?
与传统的等待通知机制相比,使用Condition接口/实现的优势是什么?在这里,我引用Doug Lea撰写的评论:
条件因素将Object监视器方法(wait,notify和notifyAll)分解为不同的对象,以通过将它们与使用任意Lock实现相结合来实现每个对象具有多个等待集的效果.如果Lock替换了synchronized方法和语句的使用,则Condition将替换Object监视方法的使用.
我认为这是一种更加面向对象的实现等待/通知机制的方式.但是,前者是否有合理的优势?
在针对多线程系统的Queue实现时,我遇到了一些惊喜.这是:-
场景: - 1个生产者,1个消费者: - 生产者将整数放入队列中.消费者只是将其从队列中删除.
队列的基础数据结构: - TreeSet(我从未想过会使用),LinkedList,LinkedBlockingQueue(具有不确定的大小)
代码: - TreeSet作为队列: -
while (i < 2000000) {
synchronized (objQueue) {
if (!(objQueue.size() > 0)) {
try {
objQueue.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Integer x = objQueue.first();
if (x != null) {
objQueue.remove(x);
++i;
}
}
}
Run Code Online (Sandbox Code Playgroud)
编辑:-
while (i < 2000000) {
synchronized (objQueue) {
objQueue.add(i);
++i;
objQueue.notify();
}
}
Run Code Online (Sandbox Code Playgroud)
对于LinkedBlockingQueue: -
while (i < 2000000){
try {
objQueue.put(i);
++i; …
Run Code Online (Sandbox Code Playgroud) 我只是想了解乐观和悲观的锁定机制,并在https://en.wikipedia.org/wiki/Lock_(database)中找到了它们的定义
如果我尝试将概念与java而不是数据库联系起来,我是否正确地说同步使用始终是悲观的并且CAS(AtomicInteger
和其他类)的使用始终是乐观的?
1)昨天才问这个问题条件与等待通知机制
2)我想对其进行编辑,并在问题中添加一些“如果”,但是由于它可能变得很麻烦并且包含足够的文字以引起读者的兴趣和困惑,所以我想在这里提出一个新问题。
3)在我的文章上下文中,其URL在点1)中给出,请考虑作用于单个数据结构'S'的4个线程P1,T1和P2,T2的情况。
4)我试图再次画出使用Condition接口而不是等待通知的优势。
5)考虑代码
final Lock lock = new ReentrantLock();
Condition c1 = lock.newCondition();
Condition c2 = lock.newCondition();
Condition c3 = lock.newCondition();
Condition c4 = lock.newCondition();
Run Code Online (Sandbox Code Playgroud)
6)考虑使用c1,c2的P1,T1(以标准await()/ signalAll()方式)。考虑分别使用put,take,put1,take1方法使用c3,c4(以标准await()/ signalAll()方式)的P2,T2。
7)当我做c1.signalAll()时,将仅等待/由于condition1的线程将接收到信号。我有道理吗?
8)考虑一个等待/通知机制来实现相同的说法,
private static final Object lock= new Object();
synchronized(lock)
Run Code Online (Sandbox Code Playgroud)
考虑put,take,put1,take1,因此,如果任何线程对任何一个条件实现执行lock.notifyAll(),即使由于其他条件而正在等待/启动的线程也将收到通知。真的吗 ?。那可以算作使用条件机制中的等待/通知的缺点吗?
我要求在GC无法控制的可用RAM中使用空格.我读了几篇同样的文章,介绍了两种方法.它们在以下代码中指定.
package com.directmemory;
Run Code Online (Sandbox Code Playgroud)
import java.lang.reflect.Field; import java.nio.ByteBuffer;
import sun.misc.Unsafe;
公共类DirectMemoryTest {
public static void main(String[] args) {
//Approach 1
ByteBuffer directByteBuffer = ByteBuffer.allocateDirect(8);
directByteBuffer.putDouble(1.0);
directByteBuffer.flip();
System.out.println(directByteBuffer.getDouble());
//Approach 2
Unsafe unsafe = getUnsafe();
long pointer = unsafe.allocateMemory(8);
unsafe.putDouble(pointer, 2.0);
unsafe.putDouble(pointer+8, 3.0);
System.out.println(unsafe.getDouble(pointer));
System.out.println(unsafe.getDouble(pointer+8));
System.out.println(unsafe.getDouble(pointer+16));
}
public static Unsafe getUnsafe() {
try {
Field f = Unsafe.class.getDeclaredField("theUnsafe");
f.setAccessible(true);
return (Unsafe) f.get(null);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
Run Code Online (Sandbox Code Playgroud)
}
我有一些问题
1)为什么我应该注意代码中提到的方法1,因为根据我的理解,ByteBuffer.allocateDirect()不能返回一个存储容量大于2GB的缓冲区?因此,如果我的要求是存储3 GB的数据,我必须创建一个新的缓冲区并将数据存储在那里,这意味着除了存储数据之外,我还有额外的责任来识别相应的缓冲区(在'n列表中) 'buffers),它维护一个指向直接内存的指针.
2)不是方法2比方法1快一点,因为我不必首先找到缓冲区然后找到数据,我只需要一个对象字段的索引机制并使用getDouble/getInt方法并传递绝对值地址 ?
3)与PID相关的直接内存分配(关于堆内存吗?)?如果在一台机器上,我有2个java进程,在PID 1中的allocateMemory调用和PID 2给我永远不会交叉使用的内存块?
4)为什么最后一个sysout语句没有导致0.0?这个想法是每个double使用8个字节,所以我在allocateMemory返回的地址处存储1.0,表示地址= …
我编写了一段简单的代码来使用 java 8 api 解析日期。我还研究了有关此主题的各种其他堆栈溢出问题,但未能解决该错误。
package com.test.java8api;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.ResolverStyle;
import java.util.Locale;
public class Test {
public static void main(String[] args) {
// TODO Auto-generated method stub
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("EEE, MM/DD/YYYY - HH:mm", Locale.ENGLISH).withResolverStyle(ResolverStyle.STRICT);
LocalDateTime date = LocalDateTime.parse("Sun, 04/22/2018 - 09:45",formatter);
System.out.println(date);
}
}
Run Code Online (Sandbox Code Playgroud)
错误日志是
Exception in thread "main" java.time.format.DateTimeParseException: Text 'Sun, 04/22/2018 - 09:45' could not be parsed: Unable to obtain LocalDateTime from TemporalAccessor: {DayOfWeek=7, WeekBasedYear[WeekFields[SUNDAY,1]]=2018, MonthOfYear=4, DayOfYear=22},ISO resolved to 09:45 of type java.time.format.Parsed
at …
Run Code Online (Sandbox Code Playgroud)