CopyOnWriteArrayList怎么用
- 什么是CopyOnWriteArrayList
- CopyOnWriteArrayList常用方法
- CopyOnWriteArrayList源码详解
- CopyOnWriteArrayList使用注意点
- CopyOnWriteArrayList存在的性能问题
- CopyOnWriteArrayList 使用实例
- 基本应用实例
- 并发应用实例
- 拓展
- 写时复制
什么是CopyOnWriteArrayList
CopyOnWriteArrayList 是一个线程安全的ArrayList,它使用了一种称为“写时复制”(Copy-on-Write)的策略来保证线程安全。
在CopyOnWriteArrayList中,每个元素都存储在一个数组中。当一个线程要对数组进行修改(例如添加、删除元素)时,它会首先复制一份当前数组的副本,对副本进行修改,然后将新的数组替换掉旧的数组。这样做的好处是,其他线程在读取数组时始终会看到一个一致的、不会改变的数组,从而避免了线程间的竞争条件。
由于CopyOnWriteArrayList采用写时复制的策略,因此在高并发的情况下可能会导致频繁的复制操作,这会消耗一定的系统资源。但是,如果读操作的频率远远高于写操作的频率,那么CopyOnWriteArrayList可以提供较好的并发性能和较高的读操作吞吐量。
总的来说,CopyOnWriteArrayList适用于读操作远多于写操作的场景,它提供了一种线程安全的解决方案,使得在并发环境下也能够保证数据的一致性和可靠性。
CopyOnWriteArrayList常用方法
CopyOnWriteArrayList常用的方法有:
-
- get(int index):获取指定索引位置的元素。
-
- set(int index, E element):将指定索引位置的元素替换为新元素。
-
- add(E element):在集合的末尾添加新元素。
-
- remove(Object o):从集合中移除指定的元素。
-
- size():返回集合的大小。
-
- contains(Object o):检查集合中是否包含指定的元素。
-
- iterator():返回一个迭代器,用于遍历集合中的元素。
-
- toArray():将集合转换为数组。
-
- addAll(Collection c):将指定集合中的所有元素添加到CopyOnWriteArrayList中。
-
- removeAll(Collection c):从CopyOnWriteArrayList中移除指定集合中的所有元素。
-
- retainAll(Collection c):仅保留CopyOnWriteArrayList中包含在指定集合中的元素。
这些方法可以帮助你在使用CopyOnWriteArrayList时完成更复杂的操作。需要注意的是,由于CopyOnWriteArrayList是线程安全的,因此在多线程环境下使用时需要注意并发问题。
CopyOnWriteArrayList源码详解
以下是CopyOnWriteArrayList的源码详解,让我们一起来看一下每一个步骤做的一些事情:
- 创建数组
在CopyOnWriteArrayList中,每个元素都存储在一个数组中。在创建CopyOnWriteArrayList时,需要传入一个初始大小。这个初始大小决定了初始数组的大小。例如,创建一个大小为10的CopyOnWriteArrayList时,会创建一个长度为10的数组。
public CopyOnWriteArrayList(Collection<? extends E> c) {Object[] elements = c.toArray();this.capacity = ArraysSupport.arrayLength(elements);myData = ArraysSupport.newArray(E.class, capacity);System.arraycopy(elements, 0, myData, 0, elements.length);size = elements.length;
}
- 获取元素
get方法根据索引获取数组中指定位置的元素。由于CopyOnWriteArrayList是线程安全的,因此在获取元素时不需要加锁。
public E get(int index) {if (index < 0 || index >= size) {throw new IndexOutOfBoundsException("Index: " + index + ", Size " + size);}return myData[index];
}
- 修改元素
set方法将指定索引位置的元素替换为新元素。它首先会检查索引的有效性,然后将当前索引位置的元素替换为新元素。与get方法一样,set方法也不需要加锁,因为它会在对数组进行修改时复制一份新的数组。
public E set(int index, E element) {if (index < 0 || index >= size) {throw new IndexOutOfBoundsException("Index: " + index + ", Size " + size);}E oldValue = myData[index];myData[index] = element;return oldValue;
}
- 添加元素
在CopyOnWriteArrayList
中,添加元素的主要方法是add(E e)
。以下是该方法的大致源码解析:
public boolean add(E e) {final ReentrantLock lock = this.lock;lock.lock();try {Object[] elements = getArray();int len = elements.length;// 确保数组容量足够Object[] newElements = Arrays.copyOf(elements, len + 1);// 在新数组的最后位置添加元素newElements[len] = e;// 将新数组设置为当前数组setArray(newElements);return true;} finally {lock.unlock();}
}
解析:
- 首先,该方法获取了
CopyOnWriteArrayList
的内部锁,以确保线程安全。 - 接着,它获取当前的数组,并计算其长度。
- 使用
Arrays.copyOf()
方法创建一个新的数组,其容量比原始数组多1。这样做是为了容纳新添加的元素。 - 在新数组的最后一个位置添加元素。
- 最后,使用
setArray()
方法将新数组设置为当前的数组。 - 无论操作是否成功,最后都要释放锁。
值得注意的是,每次对CopyOnWriteArrayList
进行修改(如添加、删除元素)时,它都会创建一个新的数组。这种“写时复制”的策略确保了线程安全,但也意味着在频繁修改的情况下,可能会引起内存和性能上的问题。因此,CopyOnWriteArrayList
最适用于读操作远多于写操作的场景。
- 删除元素
remove方法从集合中移除指定的元素。它会遍历数组,找到要删除的元素,并将其从数组中移除。然后,它会创建一个新的数组,将原始数组中剩余的元素复制到新数组中,并将新数组设置为当前数组。与add方法一样,remove方法也只需要在扩容时同步一次即可。
public E remove(int index) {final Object[] elements;final int length;elements = myData;length = size;if (index < 0 || index >= length) {throw new IndexOutOfBoundsException("Index: " + index + ", Size " + size);}// not inlined: HotSpot inlines only if the condition is false (it is not always true)E oldValue = (E) elements[index];int numMoved = length - index - 1;if (numMoved == 0) {// nothing to move, so just null out the removed element and returnelements[index] = null;} else {// shift all elements down one position to fill the gap left by the removed elementSystem.arraycopy(elements, index + 1, elements, index, numMoved);}// decrement size and clear the last element (which is now冗余)size--;elements[length - 1] = null;return oldValue;
}
- 迭代器
CopyOnWriteArrayList还提供了一个迭代器,用于遍历集合中的元素。由于CopyOnWriteArrayList是线程安全的,因此在迭代过程中不需要加锁。但是,如果在迭代过程中修改了集合,那么迭代器可能不会反映这些更改。因此,迭代器只能保证在创建时集合的一致性。
- 并发性能
CopyOnWriteArrayList采用写时复制的策略来保证线程安全。这种策略在高并发的情况下可能会导致频繁的复制操作,消耗一定的系统资源。但是,如果读操作的频率远远高于写操作的频率,那么CopyOnWriteArrayList可以提供较好的并发性能和较高的读操作吞吐量。此外,由于CopyOnWriteArrayList在修改集合时不需要加锁,因此它可以避免死锁和其他线程同步问题。
总的来说,CopyOnWriteArrayList适用于读操作远多于写操作的场景,它提供了一种线程安全的解决方案,使得在并发环境下也能够保证数据的一致性和可靠性。同时,我们也需要注意在使用CopyOnWriteArrayList时需要考虑其并发性能和适用场景。
CopyOnWriteArrayList使用注意点
使用CopyOnWriteArrayList
时,需要注意以下几点:
- 写同步,读非同步:多个线程对
CopyOnWriteArrayList
进行写操作是线程同步的,因为内部使用了可重入锁,并且在进行修改时,内部先拷贝了一份数据源,再进行操作后,将原数据覆盖,解锁。但是读操作是非线程同步的,如果在for循环中使用下标的方式去读取数据,可能报错ArrayIndexOutOfBoundsException
。 - 内存占用问题:因为CopyOnWrite的写时复制机制,所以在进行写操作的时候,内存里会同时驻扎两个对象的内存,旧的对象和新写入的对象。
- 数据一致性问题:CopyOnWrite容器只能保证数据的最终一致性,不能保证数据的实时一致性。因为复制和操作元素需要一点儿时间,所以会有延迟。如果希望写入的数据马上能读到,要求数据强一致性的话,请不要使用CopyOnWrite容器。
- 迭代器的使用:
CopyOnWriteArrayList
的迭代器实现了ListIterator
接口,但是add()
、set()
和remove()
方法都直接抛出了UnsupportedOperationException
异常。所以应该避免使用迭代器的这几个方法。
请注意,
CopyOnWriteArrayList
适用于读操作远多于写操作的场景。如果写操作非常频繁,那么可能会引起内存和性能上的问题。在选择是否使用它时,需要根据具体的应用场景进行考虑。
CopyOnWriteArrayList存在的性能问题
CopyOnWriteArrayList
的性能问题主要集中在以下几个方面:
- 写操作开销大:每次对列表进行修改操作(如add、set等),
CopyOnWriteArrayList
都会复制一份新的数据数组,这对内存和CPU都是较大的开销。如果写操作非常频繁,那么可能会引起内存占用过高和GC频繁,从而影响性能。 - 读操作可能不是实时的:由于写操作的复制机制,读操作可能不会立即看到最新的写入数据,这会导致数据的一致性问题。如果应用需要强一致性,那么
CopyOnWriteArrayList
可能不是一个好的选择。 - 迭代器操作可能抛出异常:如前所述,
CopyOnWriteArrayList
的迭代器不支持add、set和remove操作,如果尝试使用这些方法,会抛出UnsupportedOperationException
异常。这可能会在使用迭代器进行遍历操作时引发问题。 - 不适合大量数据:由于写操作需要复制整个数据数组,如果列表中包含大量数据,那么写操作的开销会非常大。这种情况下,其他线程安全的列表实现(如
ConcurrentLinkedQueue
或BlockingQueue
)可能是更好的选择。
CopyOnWriteArrayList
适用于读多写少的场景,且数据一致性要求不那么严格的情况。在使用时,需要根据应用的具体需求进行权衡和选择。
CopyOnWriteArrayList 使用实例
基本应用实例
下面是一个简单的Java代码实例,它演示了如何使用CopyOnWriteArrayList
:
import java.util.concurrent.CopyOnWriteArrayList;public class Example {public static void main(String[] args) {CopyOnWriteArrayList<String> list = new CopyOnWriteArrayList<>();// 添加元素list.add("Hello");list.add("World");list.add("Java");// 输出列表中的元素for (String str : list) {System.out.println(str);}// 移除元素list.remove("World");// 输出列表中的元素for (String str : list) {System.out.println(str);}}
}
在这个例子中,我们创建了一个CopyOnWriteArrayList
对象,并向其中添加了三个字符串元素。然后,我们使用一个简单的for-each循环遍历列表并输出其中的元素。接着,我们移除了一个元素,并再次遍历列表并输出剩余的元素。这个例子展示了CopyOnWriteArrayList
的基本用法和特点。
并发应用实例
在并发环境中,CopyOnWriteArrayList
的一个典型应用实例是实现一个线程安全的日志记录器。下面是一个示例代码,它使用了CopyOnWriteArrayList
来存储日志条目,并确保在多线程环境下对日志的读取和写入操作都是安全的。
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;public class ThreadSafeLogger {private final CopyOnWriteArrayList<String> logEntries;private static final Logger LOGGER = Logger.getLogger(ThreadSafeLogger.class.getName());public ThreadSafeLogger() {logEntries = new CopyOnWriteArrayList<>();}public void log(String message) {logEntries.add(message);LOGGER.log(Level.INFO, message);}public void log(Exception ex) {logEntries.add(ex.getMessage());LOGGER.log(Level.SEVERE, ex.getMessage(), ex);}public void printLog() {for (String entry : logEntries) {System.out.println(entry);}}
}
在这个示例中,ThreadSafeLogger
类使用CopyOnWriteArrayList
来存储日志条目。log()
方法用于将消息和异常添加到日志列表中,并使用Java的内置日志记录器(Logger
)将消息记录到标准输出。printLog()
方法遍历日志列表并打印所有条目。由于logEntries
列表是线程安全的,因此可以在多线程环境中安全地添加、读取和打印日志条目。
拓展
写时复制
写时复制(Copy-On-Write,简称COW)是一种用于处理数据的计算机技术,其基本思想是当需要修改数据时,先将数据复制一份,然后在复制的数据上进行修改,这样原数据不会被改变,从而保证了数据的一致性和安全性。这种技术主要应用于并发环境,以避免多个线程或进程同时修改同一份数据而引发的问题。
在Java的CopyOnWriteArrayList
中,写时复制技术被用来实现线程安全。当对列表进行修改操作(如add、set等)时,CopyOnWriteArrayList
会先复制一份当前的数据数组,然后在复制的数据上进行修改,最后再将修改后的数据数组替换掉原来的数据数组。这样可以保证在进行写操作的同时,读操作可以无锁地访问原来的数据数组,从而实现线程安全。
写时复制技术的优点是可以实现高效的并发读写操作,因为读操作不需要加锁,可以并发进行。但是,写操作的开销比较大,因为每次写操作都需要复制一份数据,这会消耗较多的内存和CPU资源。因此,写时复制技术适用于读多写少的场景,如果写操作非常频繁,那么可能会影响性能。
需要注意的是,写时复制技术并不能完全保证数据的一致性。因为复制和操作元素需要一定的时间,所以可能会出现延迟,导致读操作不能立即看到最新的写入数据。因此,如果应用需要强一致性,那么写时复制技术可能不是一个好的选择。
写时复制技术的优点包括:
-
如果调用者没有修改该资源,就不会有副本被建立,因此多个调用者只是读取操作可以共享同一份资源。
-
写时复制可以减少不必要的资源分配。如fork进程时,并不是所有的页面都需要复制,父进程的代码段和只读数据段都不被允许修改,所以无需复制。
-
当实体有需要对资源进行修改时才真正为实体分配私有资源,减少了分配和复制大量资源带来的延时。写时复制技术是一种很重要的优化手段,核心是懒惰处理实体资源请求,在多个实体资源之间只是共享资源,起初并不真正实现资源复制,只有当实体有需要对资源进行修改时才真正为实体分配私有资源。
总的来说,写时复制技术的优点主要是减少资源占用和提高效率。
ConcurrentLinkedDeque详解-Deque接口链表实现方案
ArrayDeque详解-Deque接口数组实现方案
LinkedList详解-Deque接口链表实现方案
Java中Deque接口方法解析
相关文章:
CopyOnWriteArrayList怎么用
什么是CopyOnWriteArrayListCopyOnWriteArrayList常用方法CopyOnWriteArrayList源码详解CopyOnWriteArrayList使用注意点CopyOnWriteArrayList存在的性能问题CopyOnWriteArrayList 使用实例基本应用实例并发应用实例 拓展写时复制 什么是CopyOnWriteArrayList CopyOnWriteArra…...
旋转设备状态监测与预测性维护:提高设备可靠性的关键
在工业领域的各个行业中,旋转设备都扮演着重要的角色。为了确保设备的可靠运行和预防潜在的故障,旋转设备状态监测及预测性维护变得至关重要。本文将介绍一些常见的旋转设备状态监测方法,并探讨如何利用这些方法来实施预测性维护,…...
类和对象——(7)this指针
归纳编程学习的感悟, 记录奋斗路上的点滴, 希望能帮到一样刻苦的你! 如有不足欢迎指正! 共同学习交流! 🌎欢迎各位→点赞 👍 收藏⭐ 留言📝 人生就像骑单车,想保持平衡…...
回溯算法题型分类
题型一:排列、组合、子集相关问题 提示:这部分练习可以帮助我们熟悉「回溯算法」的一些概念和通用的解题思路。解题的步骤是:先画图,再编码。去思考可以剪枝的条件, 为什么有的时候用 used 数组,有的时候设…...
ApplicationRunner 类
优质博文:IT-BLOG-CN 在开发中可能会有这样的情景。需要在容器启动的时候执行一些内容。比如读取配置文件,数据库连接之类的。SpringBoot给我们提供了两个接口来帮助我们实现这种需求。这两个接口分别为CommandLineRunner和ApplicationRunner。他们的执…...
QT中的 容器(container)-大全
一、介绍 Qt库提供了一套通用的基于模板的容器类,可以用这些类存储指定类型的项。比如,你需要一个大小可变的QString的数组,则使用QVector<QString>。 这些容器类比STL(C标准模板库)容器设计得更轻量、更安全并…...
Docker配置镜像加速器
Ubuntu 安装/升级Docker客户端 推荐安装1.10.0以上版本的Docker客户端,参考文档docker-ce配置镜像加速器 针对Docker客户端版本大于 1.10.0 的用户 您可以通过修改daemon配置文件/etc/docker/daemon.json来使用加速器 sudo mkdir -p /etc/docker sudo t…...
飞致云1panel + 雷池WAF
可能有许多人都有这个需求:为自己的个人站点套上WAF,增加安全性,本文将介绍如何将1panel面板深度结合长亭雷池防火墙,实现为个人站点套上WAF并且自动续签ssl证书。 前提条件: 服务器IP已绑定域名 完整的1panel环境 …...
策略梯度简明教程
策略梯度方法 (PG:Policy Gradient) 是强化学习 (RL:Reinforcement Learning) 中常用的算法。 1、从库里的本能开始 PG的原理很简单:我们观察,然后行动。人类根据观察采取行动。 引用斯蒂芬库里的一句话: 你必须依靠…...
鸿蒙原生应用/元服务开发-利用picker选择器来多选相册图片
前言 在之前的时候,测试一个应用进入相册选择图片demo,利用了startAbilityForResult()方法,启动相对应的Ability来完成效果,但是这种方法有限制,一次只能获取一张图片,在完成某些功能测试的时候就很不方便。…...
java:封装统一的响应体code、data、msg、paging
背景 我们在写接口的时候一般不会直接返回给前端数据,而是会有响应体,比如 code、data、msg,这样就有一个统一的结构方便前端处理,那么今天就来封装一个统一的响应体 封装基本响应体 1、在 config 包里新建 ApiResponse.java …...
leetcode算法之栈
目录 1.删除字符串中的所有相邻重复项2.比较含退格的字符串3.基本计算器II4.字符串解码5.验证栈序列 1.删除字符串中的所有相邻重复项 删除字符串中的所有相邻重复项 class Solution { public:string removeDuplicates(string s) {string ret;//使用数组模拟栈操作for(auto …...
电脑上mp4视频文件无缩略图怎么办
前言:有时候电脑重装后电脑上的mp4视频文件无缩略图,视频文件数量比较多的时候查找比较麻烦 以下方法亲测有效: 1、下载MediaPreview软件 2、软件链接地址:https://pan.baidu.com/s/1bzVJpmcHyGxXNjnzltojtQ?pwdpma0 提取码&…...
【Centos8】配置网络镜像源
文章目录 配置 yum 源配置网络 yum 源备份下载阿里 centos-base.repo 到 /etc/yum.repos.d/安装 EPEL 源测试安装 配置 yum 源 # 检查是否安装了 yum rpm -qa|grep yum# 查看本地已安装的所有软件包 yum list installed# 查看软件包安装位置 # 查看某个东西的软件包 rpm -qa|g…...
深入学习Synchronized各种使用方法
文章目录 前言一、synchronized关键字通用在下面四个地方:1.1synchronized修饰实例方法1.2synchronized修饰静态方法:1.3synchronized修饰实例方法的代码块1.4synchronized修饰静态方法的代码块2.读入数据 二.Sychronized关键特性2.1互斥2.2 刷新内存2.3…...
【idea】设置鼠标滚轮控制缩放大小
1、点击file 选择Setting 2、点击Editor 下面的 General 3、勾选 Mouse Control 下面的 Change font size with CtrlMouse Wheel in 4、点级apply 5、按 ctrl键 鼠标滚轮缩放字体的大小...
合并两个有序数组(leetcode_刷题1)
目录 题目:合并两个有序数组 题目分析方向1: 题目分析方向2: 题目:合并两个有序数组 题目要求: 给你两个按 非递减顺序 排列的整数数组 nums1 和 nums2,另有两个整数 m 和 n ,分别表示 nums…...
麒麟linux将图片批量生成PDF的方法
笔者手里有一批国产linu系统,目前开始用在日常的工作生产环境中,我这个老程序猿勉为其难的充当运维的或网管的角色。 国产linux系统常见的为麒麟Linux,统信UOS等,基本都是基于debian再开发的linux。 问题描述: wind…...
Linux——vim编辑文件时——.swp文件解决方案
test.cpp样例 当我们vim test.cpp进入编辑文件。 却忘记了保存退出 再次进入就会出现一下画面 当你摁下Enter键位 出现以下几个选项 O——是只读不写 E——是正常打开文件但不会载入磁盘内容 R——覆盖——是加载存储磁盘的文件(当我们忘记保存时,系统会自动帮我…...
【Maven】清理 maven 仓库
初始情况下,我们的本地仓库是没有任何jar包的,此时会从私服去下载(如果没有配置,就直接从中央仓库去下载)。 可能由于网络的原因,jar包下载不完全,这些不完整的jar包都是以lastUpdated结尾。此…...
APOLLO自动驾驶技术沙龙:未来已来,共创智能交通新时代
在这次Apollo会议上,我深刻地感受到了人工智能自动驾驶技术领域的最新进展和未来趋势。作为一名从事软件开发工作的人员,我深感荣幸能够参加这次盛会。 前言 本次活动是百度Apollo社区工程师齐聚首钢Park,带来现场实操与技术分享。主要围绕Ap…...
Java面试题12
1.redis 怎么实现分布式锁? Redis可以通过以下方式实现分布式锁: 使用RedLock算法:多个Redis节点组合使用,通过竞争锁来达到分布式锁的效果。使用SETNX命令:利用SETNX(SET if Not eXists)命令…...
ubuntu上创建服务启动python脚本
场景 最近在使用ubuntu服务器部署MySQL和同步数据,同步数据使用的是python,但是我不能直接操作服务器,只能通过Xshell远程访问服务器,但是启动python脚本的时候如果关掉xshell会停止Python脚本,所以如果要让python脚本…...
51单片机制作数字频率计
文章目录 简介设计思路工作原理Proteus软件仿真软件程序实验现象测量误差和范围总结 简介 数字频率计是能实现对周期性变化信号频率测量的仪器。传统的频率计通常是用很多的逻辑电路和时序电路来实现的,这种电路一般运行较慢,而且测量频率的范围较小。这…...
java中强引用、软引用、弱引用、虚引用的区别是什么?
Java中的引用类型主要分为强引用、软引用、弱引用和虚引用,它们之间的区别主要体现在垃圾回收的行为上。 强引用(Strong Reference):这是使用最普遍和默认的引用类型。如果一个对象具有强引用,那么垃圾回收器就永远不会…...
springboot -事务管理
事务 概念 事务是一组操作的集合,它是一个不可分割的工作单位,这些操作要么同时成功,要么同时失败。 操作 开启事务: start transaction / begin提交事务:commit回滚事务: rollback 注解 Transactional …...
商城系统通过Kafka消息队列,实现订单的处理和状态更新
以下是一个简单的Spring Boot应用程序示例,演示如何使用Kafka实现订单的处理和状态更新。 首先,我们创建一个名为“order”的topic,在application.yaml配置文件中添加Kafka的配置: spring:kafka:bootstrap-servers: localhost:9…...
IntelRealSense深度相机D455在ROS1运行中的消息内容
IntelRealSense深度相机D455在ROS1运行中的消息内容 通过下面命令所有相关信息通过ros topic的方式发布出去rosnode查看rqt_graph查看rostopic查看通过下面命令直接查看RVIZ中点云信息rosnode查看rqt_graph查看rostopic查看 Physical Port:: /sys/devices/pci0000:0…...
公有云迁移研究——AWS Translate
大纲 1 什么是Translate2 Aws Translate是怎么运作的3 Aws Translate和Google Translate的区别4 迁移任务4.1 迁移原因 5 Aws Translate的Go demo6 迁移中遇到的问题6.1 账号和权限问题:6.2 小语种 1 什么是Translate Translate是一种文本翻译服务,它使…...
【laBVIEW学习】4.声音播放,自定义图标,滚动条设置,保存参数以及恢复参数
一。声音播放(报错,未实现) 1.报错4810 2.解决方法: 暂时未解决。 二。图片修改 1.目标:灯泡---》自定义灯泡 2.步骤: 1.右键点击--》自定义运行 表示可以制作自定义类型 2.右键--》打开自定义类型 这样就…...
新开传奇网站195合击/网站优化内容
父类和子类 子类对象也是是父类的对象。 子类继承所有父类的属性。 父类的属性,在子类中都有,各子类中还有自己特有的属性。 父类上的关联关系,会体现在每个子类身上。子类身上的关联关系仅仅体现在子类自己身上。 这里,每个病人…...
银川网站建设价格/百度推广关键词和创意
1. 支持手机、pad等移动设备远程控制功能。2、支持DLNA、Airplay、QPaly等协议。3、Cortex-A9四核,7寸电容触摸屏,1024*600高清分辨屏,标配通用的网络接口,内置wifi无线连接。4、功率:35W*45、4声道输出,支…...
松江做网站/帆软社区app
A: 今天同学遇到了一个FCKeditor如何删除文件中图片的问题,我也是第一次遇到,为了解决这个问题从网上搜到了一点资料。与大家共享一下。最近在做项目时做了这样一个功能,已减少垃圾图片!用正则表达式得到图片的路径与名称。 PageV…...
郑州网站制作天强科技/站长之家 seo查询
转自:MongoDB常用28条查询语句 1、查询所有记录 db.userInfo.find(); 相当于: select* from userInfo; 默认每页显示20条记录,当显示不下的情况下,可以用it迭代命令查询下一页数据。注意:键入it命令不能带“࿱…...
初学网站开发需要书籍/百度网站收录
汇率换算V1.0 案例描述: 设计一个汇率换算器程序,其功能是将外币换算成人民币,或者相反 案例分析: 分析问题:分析问题的计算部分; 确定问题:将问题划分为输入、处理及输出部分; 设计…...
代做网站名称优化/成都网站建设软件
本文转载自:http://blog.csdn.net/leixiaohua1020/article/details/15811977 在CSDN上的这一段日子,接触到了很多同行业的人,尤其是使用FFMPEG进行视音频编解码的人,有的已经是有多年经验的“大神”,有的是刚开始学习的…...