首页 > 编程语言 >【面试宝典】28道Java集合高频题库整理(附答案背诵版)

【面试宝典】28道Java集合高频题库整理(附答案背诵版)

时间:2024-06-23 19:30:57浏览次数:3  
标签:Map Java HashMap 28 接口 线程 集合 题库

常见的集合有哪些?

常见的Java集合可以分为两大类:Collection 和 Map。

  1. Collection 接口下主要有以下几种实现:
    • List:有序的集合,其中的元素可以重复。
      • ArrayList:基于动态数组实现,查询速度快,但在中间插入和删除元素时速度较慢。
      • LinkedList:基于双向链表实现,插入和删除速度快,但查询速度较慢。
      • Vector:与ArrayList类似,但它是线程安全的。
    • Set:无序的集合,其中的元素不可以重复。
      • HashSet:基于哈希表实现,不保证有序。
      • LinkedHashSet:维护元素的插入顺序。
      • TreeSet:基于红黑树实现,元素按照自然顺序或者自定义的比较器顺序进行排序。
    • Queue:一种先进先出 (FIFO) 的数据结构。
      • LinkedList:除了实现List接口外,还实现了Deque接口,可以作为双端队列使用。
      • PriorityQueue:基于优先堆实现,元素可以按照自然顺序或者自定义的比较器顺序出队。
    • Deque:双端队列,可以在队头和队尾进行元素的插入和删除。
      • ArrayDeque:基于动态数组实现的双端队列。
      • LinkedList:同样可以作为双端队列使用。
  2. Map:存储键值对,其中键是唯一的。
    • HashMap:基于哈希表实现,不保证有序。
    • LinkedHashMap:保持键的插入顺序。
    • TreeMap:基于红黑树实现,键按照自然顺序或者自定义的比较器顺序进行排序。
    • Hashtable:与HashMap类似,但它是线程安全的。

在并发编程中,常用的集合类型有哪些?

Java并发集合主要是java.util.concurrent包中的一些线程安全的集合类,它们能够在多线程环境下提供良好的性能。以下是一些常用的并发集合:

  1. ConcurrentHashMap:这是一个线程安全的HashMap的变体。与HashTable相比,ConcurrentHashMap在并发环境下提供了更好的性能,因为它只会锁定部分段(segment),而不是整个数据结构。
  2. CopyOnWriteArrayListCopyOnWriteArraySet:这两个集合类在每次修改(例如添加或删除元素)时都会复制整个底层数组,从而实现线程安全。这使得在迭代期间可以不需要锁定,因此在读多写少的并发环境下表现很好。
  3. ConcurrentLinkedQueue:一个线程安全的队列,使用链表实现。它采用了一种非阻塞的算法来实现线程安全,因此在高并发环境下性能很好。
  4. ConcurrentLinkedDeque:一个线程安全的双端队列,同样使用链表实现和非阻塞算法。
  5. BlockingQueue 接口和它的实现类,如 ArrayBlockingQueueLinkedBlockingQueuePriorityBlockingQueueSynchronousQueue 等:这些队列在尝试获取元素但队列为空,或者尝试添加元素但队列已满时,会导致线程阻塞。这在生产者-消费者模式中非常有用。
  6. BlockingDeque 接口和它的实现类 LinkedBlockingDeque:这是一个双端版本的BlockingQueue。
  7. ConcurrentSkipListSetConcurrentSkipListMap:这两个集合类是线程安全的有序集合。它们内部使用跳表(Skip List)数据结构,可以提供与TreeSet和TreeMap类似的功能,但在并发环境下具有更好的性能。

以上这些并发集合都是设计用来替代传统的线程安全集合(如Vector和HashTable),以及通过Collections.synchronized*方法得到的同步集合。

哪些集合类支持对元素的随机访问?

在Java中,"随机访问"意味着我们可以直接通过索引访问集合中的元素,而不需要从开始位置遍历到所需位置。这通常在基于数组的集合中实现,因为数组支持通过索引的方式直接访问元素。

以下集合类支持对元素的随机访问:

  1. ArrayList:ArrayList内部使用动态数组来存储元素,因此可以很快地通过索引访问元素。例如,你可以直接使用list.get(index)来获取指定索引位置的元素。

  2. Vector:Vector和ArrayList类似,内部也是基于数组实现的。Vector是线程安全的,所以在多线程环境下,如果需要随机访问元素,Vector是一个好的选择。

  3. CopyOnWriteArrayList:这是一个线程安全的ArrayList的变体,它也支持通过索引随机访问元素。

需要注意的是,其他一些集合类,如LinkedList、HashSet、TreeSet等,虽然提供了getcontains等方法,但是它们不支持通过索引直接访问元素,而是通过遍历或其他方式来查找元素,因此它们不支持随机访问。

例如,LinkedList虽然也有get(index)方法,但是它需要从头(或尾)开始遍历到指定索引的位置,所以它不被认为是支持随机访问的。

Comparable接口和Comparator接口的主要区别是什么?

ComparableComparator 都是Java中的接口,它们都用于定义对象的排序方式,但是它们的使用场景和方法有所不同。

  1. Comparable接口:如果一个类实现了Comparable接口,那么它的对象就具有可比性,可以进行排序。Comparable接口中只有一个方法,即compareTo(T o),用于比较当前对象与参数对象的大小。实现Comparable接口的类需要覆盖compareTo(T o)方法,定义对象的自然排序规则。例如,Java的String类和Integer类都实现了Comparable接口,定义了自然的字典序和数值大小排序规则。

    应用场景:当你需要定义一个类的默认排序方式时,可以让这个类实现Comparable接口。

  2. Comparator接口:Comparator接口则更加灵活,它可以定义任意两个对象之间的比较规则。Comparator接口中有两个方法,compare(T o1, T o2)equals(Object obj)。通常我们只需要实现compare(T o1, T o2)方法,定义两个对象的比较规则。使用Comparator的好处是你可以定义多种排序规则,并在排序时动态选择使用哪种规则。

    应用场景:当你需要对一些对象进行排序,但是这些对象的类没有实现Comparable接口,或者你需要使用不同于其自然排序规则的排序规则时,可以使用Comparator。

举例:假设我们有一个Person类,包含姓名和年龄两个字段。我们可以让Person类实现Comparable接口,按照姓名的字典序排序。但是在某些情况下,我们可能需要按照年龄排序,这时我们就可以定义一个实现了Comparator接口的类,按照年龄进行排序。

Collection接口和Collections类的主要区别是什么?

CollectionCollections 在Java中都是非常重要的,但它们的功能和用途是不同的:

  1. Collection

    • 类型:它是一个接口。
    • 所在包:java.util
    • 描述:Collection是Java集合框架的根接口,它定义了用于操作数据集合的最基本的方法,例如add(), remove(), contains(), size()等。
    • 子接口:主要的子接口包括List, Set, Queue等。这些子接口提供了更具体的数据结构的操作。
    • 使用:通常,我们不直接使用Collection接口,而是使用它的具体实现类(例如ArrayList, HashSet等)或它的子接口。
  2. Collections

    • 类型:它是一个工具类。
    • 所在包:java.util
    • 描述:Collections类提供了一系列的静态方法,用于对集合对象进行操作,例如排序、反转、同步包装、查找等。
    • 主要方法sort(), reverse(), synchronizedList(), min(), max(), emptyList()等。
    • 使用:这是一个帮助类,不能被实例化。它为我们提供了许多操作集合的常用的静态方法。

Enumeration接口和Iterator接口有哪些不同?

EnumerationIterator 都是Java中的接口,用于遍历和操作数据集合的元素,但它们之间存在一些差异:

  1. Enumeration

    • 版本:Enumeration接口在JDK 1.0中引入,它是早期Java版本的遗留。
    • 方法:Enumeration接口中有两个方法:hasMoreElements()nextElement()
    • 功能:Enumeration接口只能用于遍历集合,不能进行元素的删除操作。
    • 安全性:Enumeration接口的方法不是fail-fast的,在使用Enumeration进行遍历时,其他线程可以修改集合,不会抛出ConcurrentModificationException。
  2. Iterator

    • 版本:Iterator接口在JDK 1.2中引入,作为Enumeration的替代,更加强大和灵活。
    • 方法:Iterator接口中有三个方法:hasNext(), next()remove()
    • 功能:除了遍历集合,Iterator接口还可以通过remove()方法删除遍历过程中的元素。
    • 安全性:Iterator接口的方法是fail-fast的,如果在使用Iterator进行遍历时,其他线程修改了集合,会立即抛出ConcurrentModificationException。

总的来说,Iterator接口在功能上比Enumeration接口更加强大和灵活,现在的Java程序中,更推荐使用Iterator接口,而不是Enumeration接口。

使用泛型在集合中有哪些优势?

使用泛型(Generics)可以带来很多优点,尤其在集合中使用泛型更能体现出这些优点:

  1. 类型安全:泛型强制在编译时检查类型,这意味着如果你试图将错误类型的对象添加到集合中,编译器将立即报错。这可以防止在运行时出现ClassCastException(类转换异常)。

  2. 避免类型转换:如果一个集合没有使用泛型,那么当你从集合中获取元素时,你需要将它显式地转换为正确的类型。但是如果使用了泛型,那么这个类型转换就是自动的,使得代码更简洁,易读。

  3. 代码重用:你可以写一个能够操作不同类型的对象的通用代码,而不是为每一种类型都写一个版本。这大大提高了代码的重用性。

举个例子,如果你有一个存储字符串的ArrayList,你可以这样定义它:

ArrayList<String> list = new ArrayList<String>();

这样,你就可以在编译时确保只有字符串被添加到这个列表中。当你从列表中获取元素时,编译器知道它们是字符串,所以你不需要进行类型转换。例如:

String str = list.get(0);  // 不需要类型转换

如果你试图添加一个不是字符串的对象,编译器会报错:

list.add(123);  // 编译错误,不能添加非字符串对象到列表中

因此,使用泛型可以使你的代码更安全,更易读,更易于重用。

请解释Map接口不继Collection接口的原因?

这是一个经常被问及的问题,尤其是在面试中。MapCollection 在概念上是有区别的,这也是为什么在 Java 集合框架中它们没有继承关系的原因。以下是主要的理由:

  1. 基本差异

    • Collection 接口代表一组单一的元素(如ListSet等)。
    • Map 接口则表示键值对,每一个键映射到一个值。
  2. 功能不匹配

    • 许多Collection接口的方法(如add(E e), remove(Object o)等)在语义上并不适用于Map。例如,add(E e)方法是为了向集合中添加一个单一元素,但Map需要添加键值对。
    • 同样地,Map具有特定的方法(如put(K key, V value), get(Object key)等),这些方法在Collection接口中没有对应的概念。
  3. 复杂性问题

    • 如果Map继承了Collection,那么它可能会继承许多并不适用的方法。这会增加实现Map的类的复杂性,因为它们需要提供这些不相关方法的实现或抛出不支持的操作异常。
  4. 语义清晰性

    • 保持MapCollection分开可以使每个接口的语义更为明确和清晰。Collection主要关注于单一元素的集合操作,而Map则专注于键值对映射的操作。
  5. 实用性考虑

    • 实际上,Map接口有几个方法(例如keySet(), values(), entrySet())可以返回集合视图,这使得你可以将Map的键或值视为Collection来处理。

总之,由于MapCollection的基本概念、操作和目的存在显著差异,因此Java设计者们决定它们应该是两个独立的接口。

常用的线程安全的 Map 有哪些?

常用的线程安全的 Map 实现有以下几种:

  1. Hashtable

    • Hashtable 是 Java 较早提供的一个线程安全的 Map 实现。它使用同步方法(synchronized methods)来保证线程安全。
    • 但由于整个方法都是同步的,导致其在高并发环境下的性能不佳。
    • 在现代Java应用中,Hashtable 已经不太推荐使用了,因为还有其他更好的线程安全 Map 实现。
  2. Collections.synchronizedMap(Map<K,V> m)

    • 使用 Collections.synchronizedMap 方法,你可以将任何 Map 实现转换为线程安全的版本。
    • 它返回的 Map 所有的方法都被同步了,这意味着任何对这个 Map 的并发访问都会进行同步,从而保证线程安全。
    • 但与 Hashtable 一样,由于同步的粒度较大,所以在高并发环境下可能会遇到性能瓶颈。
  3. ConcurrentHashMap

    • ConcurrentHashMap 是 Java 并发包(java.util.concurrent)中提供的一个线程安全且高性能的 Map 实现。
    • 它采用分段锁技术,这意味着多个线程可以同时写入不同段的 Map,大大提高了并发写操作的性能。
    • 除了常见的 Map 操作外,ConcurrentHashMap 还提供了一些其他有用的原子操作,如 putIfAbsent, remove, 和 replace
  4. ConcurrentSkipListMap

    • ConcurrentSkipListMap 是一个线程安全的跳表实现,支持并发访问。
    • 它内部使用跳表数据结构,并允许高效的并发读写操作。
    • ConcurrentHashMap 相比,ConcurrentSkipListMap 的一个特点是它会对键进行排序。

选择建议

  • 对于大多数需要线程安全的场景,ConcurrentHashMap 往往是首选,因为它提供了很好的并发性能。
  • 如果需要一个排序的线程安全的 Map,那么 ConcurrentSkipListMap 是一个不错的选择。

当然,对于线程安全的数据结构,除了选择合适的实现外,还需要注意正确的使用方式,避免诸如死锁、竞态条件等并发问题。

HashMap和Hashtable之间有哪些主要区别?

当谈到Java集合框架中的HashMapHashtable时,它们之间存在若干关键的区别。我将列举这些区别并尽量用简单的语言和例子来解释它们。

  1. 同步性:

    • Hashtable: 是同步的,这意味着它是线程安全的。多个线程同时访问它时不需要外部同步。
    • HashMap: 是不同步的,如果多个线程同时访问并至少有一个线程对其进行结构性修改,那么它必须被同步。

    应用场景: 如果你的应用中没有多线程,或者你可以确保只有一个线程修改映射,并且其他线程只读取,那么HashMap可能是一个更好的选择,因为它通常比Hashtable更快。但如果你需要确保线程安全性,那么Hashtable或者使用Collections.synchronizedMap()HashMap包装起来可能更适合。

  2. 允许null值:

    • Hashtable: 不允许键或值为null。
    • HashMap: 允许键和值为null(但只允许一个null键)。

    示例:

    Hashtable<String, String> table = new Hashtable<>();
    // table.put(null, "value");  // 这会抛出NullPointerException
    HashMap<String, String> map = new HashMap<>();
    map.put(null, "value");  // 这是合法的
    
  3. 继承:

    • Hashtable: 继承了Dictionary类。
    • HashMap: 继承了AbstractMap类。
  4. 性能:

  • 由于Hashtable的同步特性,它在多线程环境中通常比HashMap慢。
  1. 遍历:
  • HashMap是通过Iterator遍历的,而Hashtable是通过EnumeratorIterator遍历的。
  1. 方法:

    • 除了历史原因造成的一些小差异,HashMapHashtable的大多数方法都很相似。

说明一下使用HashMap或TreeMap的情况?

HashMapTreeMap 都是 Java 集合框架中的 Map 实现,它们存储键值对,但根据不同的场景和需求,它们有各自的优势。以下是何时选择它们的一些建议:

  1. 插入和查找性能

    • HashMap: 提供常数时间的平均性能 O(1) 来添加和检索键值对。但在某些不利情况下,可能会退化到线性时间 O(n)(例如,当所有的键都落入同一个bucket时)。
    • TreeMap: 提供对数时间的性能 O(log n) 来添加、删除和检索键值对。

    应用场景: 当性能是关键因素并且你不需要键的任何排序功能时,HashMap 通常是首选。

  2. 键的顺序

    • HashMap: 不保证键的顺序。即键值对插入的顺序与键的迭代顺序可能不一致。
    • TreeMap: 根据键的自然顺序或者通过构造函数传入的Comparator来维护键的顺序。

    应用场景: 如果你需要一个按键排序的 Map,例如在一个区间查找或者返回有序的键集合时,TreeMap 是一个更好的选择。

  3. 空键和空值

    • HashMap: 允许一个空键和多个空值。
    • TreeMap: 不允许空键(因为键需要排序),但允许空值。
  4. 线程安全性

  • 两者都不是线程安全的。但可以通过外部同步来实现线程安全。
  1. 功能

    • TreeMap 提供了一些导航方法(如 firstKey(), lastKey(), lowerKey() 等),这在 HashMap 中不可用。

    应用场景: 如果你需要这些导航功能,例如查找距离某个键最近的键,则 TreeMap 更适合。

  2. 空间复杂性

    • 通常,TreeMap 由于其红黑树结构通常使用的空间会比 HashMap 多。

总结

  • 如果需要快速的插入、删除和查找操作,且不需要任何排序功能,那么 HashMap 是一个很好的选择。
  • 如果需要有序的键、导航功能或者特定的排序要求,那么 TreeMap 是更好的选择。

在实际应用中,你的具体需求和数据特性将决定选择哪种实现。

HashMap的内部数据结构是怎样的?

好的,关于HashMap的数据结构,我来为您解释。

HashMap是Java中非常流行的键值对存储结构。它基于哈希表来实现,具体的数据结构包括以下部分:

  1. 数组:这是HashMap的主体,用于存储Node<K,V>类型的元素,其中每一个Node代表了一个键值对。

  2. 链表:当多个键值对的哈希值冲突时(也就是说,它们在数组中的位置是相同的),它们会以链表的形式存储。这也是为什么HashMap有时会被称为“链表哈希”的原因。

  3. 红黑树:从Java 8开始,为了进一步提高效率,当一个数组位置上的链表长度超过一定的阈值时(默认为8),那么这个链表会转变为红黑树。这样,即使哈希冲突增多,HashMap的查询效率也仍然可以在O(log n)的复杂度内。

应用场景
假设你正在开发一个在线购物商城。每一个商品都有一个唯一ID。你需要快速地根据商品ID查找商品的详细信息。在这种情况下,HashMap是一个非常合适的选择。商品ID作为键,商品的详细信息作为值。由于HashMap的查找速度平均为O(1),这可以让用户在查找商品时获得很快的响应时间。

简单的例子

HashMap<String, String> productMap = new HashMap<>();
productMap.put("P12345", "手机");
productMap.put("P67890", "电脑");

String productName = productMap.get("P12345");  // 这会得到 "手机"

希望我的答案对您有所帮助。如果还有其他问题,欢迎继续提问!

HashMap的键可以使用任意对象吗?

是的,HashMap的键可以是任何对象,只要该对象正确地实现了hashCode()equals()方法。这两个方法是HashMap正确工作的基础。

  1. hashCode():这个方法返回对象的哈希码,它被用来确定对象在HashMap数组中的位置。如果两个对象被视为相同(即它们的equals()方法返回true),它们必须返回相同的哈希码。

  2. equals():这个方法用于比较两个对象是否相等。在HashMap中,当两个键的哈希值相同时,equals()方法被用来进一步确认两个键是否真的相等。

应用场景

假设你正在管理一个学生系统,每一个学生都有一个独特的学生ID和相关的详细信息。学生ID是一个自定义的StudentID类,其中包含了学院代码和学号。为了在HashMap中使用这个StudentID作为键,你需要确保它正确地实现了hashCode()equals()方法。

简单的例子

class StudentID {
    private String collegeCode;
    private String studentNumber;

    // 构造方法、getter、setter省略...

    @Override
    public int hashCode() {
        return Objects.hash(collegeCode, studentNumber);
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) return true;
        if (obj == null || getClass() != obj.getClass()) return false;
        StudentID other = (StudentID) obj;
        return Objects.equals(collegeCode, other.collegeCode) &&
               Objects.equals(studentNumber, other.studentNumber);
    }
}

HashMap<StudentID, String> studentMap = new HashMap<>();
studentMap.put(new StudentID("CS", "001"), "张三");

在上述例子中,我们使用了StudentID对象作为HashMap的键,并且确保了正确地实现了hashCode()equals()方法。

总的来说,只要对象正确地实现了hashCode()equals()方法,它就可以被用作HashMap的键。

HashMap键可以使用可变对象吗?

使用可变对象作为 HashMap 的键是有风险的,但它是允许的。当你使用可变对象作为 HashMap 的键时,必须非常小心,因为对象的状态改变可能会导致它的哈希码变化,进而影响其在 HashMap 中的定位。

风险

  1. 如果一个可变对象作为键被插入到 HashMap,然后它的状态发生了改变(导致其哈希码变化),那么你可能会在 HashMap 中找不到该键,或者误删除其他键。

  2. 这样的操作可能会导致意外的行为,比如 HashMap 包含多个看似相同的键,或者某些键变得不可访问。

  3. 此外,如果两个对象在插入 HashMap 时具有相同的哈希码但在后续被修改并变得不相等,那么这会导致 HashMap 出现意外的行为。

应用场景

考虑一个简单的例子,你有一个 Person 类,该类有一个属性 name。你创建了一个 Person 对象并将其作为键插入到 HashMap。之后,你更改了 Person 对象的 name 属性:

class Person {
    String name;
    
    Person(String name) {
        this.name = name;
    }

    @Override
    public int hashCode() {
        return name.hashCode();
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) return true;
        if (obj == null || getClass() != obj.getClass()) return false;
        Person person = (Person) obj;
        return Objects.equals(name, person.name);
    }
}

HashMap<Person, String> map = new HashMap<>();
Person person = new Person("Alice");
map.put(person, "Engineer");

person.name = "Bob"; // 修改了作为键的对象

String profession = map.get(person); // 这里可能会返回 null,因为键的哈希码已经改变了

建议

  1. 尽量避免使用可变对象作为 HashMap 的键。

  2. 如果确实需要使用可变对象作为键,确保对象的状态改变不会影响其 hashCode()equals() 方法的结果。

  3. 更好的选择是使用不可变对象作为键,或者在将对象作为键使用之前,先创建其深拷贝并使用该拷贝作为键。

总之,虽然可以使用可变对象作为 HashMap 的键,但这样做需要非常小心,并确保了解相关的风险和限制。

由于内容太多,更多内容以链接形势给大家,点击进去就是答案了

16. ConcurrentHashMap 的实现原理是什么?

17. HashSet 的实现原理?

18. HashSet 怎么保证元素不重复的?

19. LinkedHashMap 的实现原理?

20. Iterator 怎么使用?有什么特点?

21. Iterator 和 ListIterator 有什么区别?

22. Iterator 和 Enumeration 接口的区别?

23. fail-fast 与 fail-safe 有什么区别?

24. Collection 和 Collections 有什么区别?

25. HashMap的hash算法相关连环炮

26. HashMap的加载因子连环炮

27. HashMap的初始容量连环炮

28. HashMap树化连环炮

标签:Map,Java,HashMap,28,接口,线程,集合,题库
From: https://blog.csdn.net/tailonh/article/details/139756050

相关文章

  • Leetcode150.逆波兰表达式求值(Java)
    题目:        给你一个字符串数组 tokens ,表示一个根据 逆波兰表示法 表示的算术表达式。请你计算该表达式。返回一个表示表达式值的整数。    栈的典型例题。题目要求为:求后缀表达式值。示例 1:输入:tokens=["2","1","+","3","*"]输出:9解释:该算式......
  • Java链表
    在Java中,链表是一种动态数据结构,它不需要在内存中分配一块连续的空间,而是通过指针将节点连接起来。链表由节点(Node)的集合组成,每个节点包含两部分内容:数据(data)和指向下一个节点的引用(next)。Java中常见的链表类型有单向链表、双向链表和循环链表:单向链表(SinglyLinkedList):每......
  • javascript浏览器对象模型
    BOM对象:BOM是浏览器对象模型的简称。JavaScript将整个浏览器窗口按照实现的功能不同拆分成若干个对象;包含:window对象、history对象、location对象和document对象等window对象:常用方法:1.prompt();显示可提示用户输入的对话框window.prompt("请输入您的名字");返......
  • Day28.property使用part2
    1.property使用part2_多次调用类中的函数方法property用法,案例一代码如下:'''案例一'''classPeople:def__init__(self,name):self.__name=namedefget_name(self):returnself.__namedefset_name(self,val):......
  • Java语言常用注解(Annotation)收录
    Java语言常用注解(Annotation)收录注解(Annotation)是一种用于在代码中插入元数据的方式,以便为编译器、开发工具或运行时环境提供信息。自Java5引入以来,注解已成为Java平台不可或缺的一部分,用于各种场景,如编译时检查、框架集成、依赖注入等。下面收录了一些开发过程中常用......
  • 基于JavaSpringBoot+Vue+uniapp技术的微信小程序鲜花商城购物系统设计与实现
    博主介绍:硕士研究生,专注于Java技术领域开发与管理,以及毕业项目实战✌    从事基于javaBS架构、CS架构、c/c++编程工作近16年,拥有近12年的管理工作经验,拥有较丰富的技术架构思想、较扎实的技术功底和资深的项目管理经验。    先后担任过技术总监、部门经理、......
  • [Java并发]Thread
    Java开启线程的四种方式实现runnable接口这个方法有一个很大的缺点就是重写的run方法是没有返回值的,如果想要返回值,需要使用下面的方法publicclassRunnableImplimplementsRunnable{/**创建步骤如下:*1,定义Runnable接口的实现类,并且实现run方法,这个方法......
  • JAVA类与对象的基础概念(JAVA基础)
    类的定义1.定义:类可以看做是一个模版,或者图纸,系统根据类的定义来造出对象2.属性:用于定义该类或该类对象包含的数据或者说静态特征3.初始化∶定义成员变量时可以对其初始化,如果不对其初始化,Java使用默认的值对其初始化4.方法:用于定义该类或该类实例的行为特征和功能实现......
  • 价格减免(Lc2288)——模拟
    句子 是由若干个单词组成的字符串,单词之间用单个空格分隔,其中每个单词可以包含数字、小写字母、和美元符号 '$' 。如果单词的形式为美元符号后跟着一个非负实数,那么这个单词就表示一个 价格 。例如 "$100"、"$23" 和 "$6" 表示价格,而 "100"、"$" 和 "$1e5 不是。......
  • [Java并发]ConcurrentHashMap
    ConcurrentHashMapHashMap和ConcurrentHashMap的区别主要区别就是hashmap线程不安全,ConcurrentHashMap线程安全HashMap线程不安全,有以下两个问题put覆盖问题比如有两个线程A和B,首先A希望插入一个key-value对到HashMap中,首先计算记录所要落到的桶的索引坐标,然后获取到该桶......