`

多线程摘录 002

阅读更多
设计线程安全的类需要考虑哪些因素?
1) 找出哪些变量属于对象的状态
2) 找出哪些不变量属于对象的状态
3) 使用合适的并发策略来管理对状态的访问

考虑线程安全的需求
1) 同步范围多大? 整个方法? 一个大块? 小块?
2) 有哪些限制和先决条件?

java内建的监视器模型, 通过锁定, 即在锁对象添加监视器, 一旦锁定释放, 监视器通知其他等待的线程. Object.wait/notity/notifyAll

"代理"线程安全性
如果一个类合理的使用了一个已经实现线程安全的类, 就是把线程安全性交给内部对象"代理"了.
JDK提供一些线程安全的类, 如Vector, HashTable, ConcurrentHashMap, Collections.concurrentXXX(Obj), BlockingQueue等. 例子:

public class DelegatingVehicleTracker {
    private final ConcurrentMap<String, Point> locations;
    private final Map<String, Point> unmodifiableMap;

    public DelegatingVehicleTracker(Map<String, Point> points) {
        locations = new
ConcurrentHashMap<String, Point>(points);
        unmodifiableMap =
Collections.unmodifiableMap(locations);
    }

    public Map<String, Point> getLocations() {
        return unmodifiableMap;
    }

    public Point getLocation(String id) {
        return locations.get(id);
    }

    public void setLocation(String id, int x, int y) {
        if (locations.replace(id, new Point(x, y)) == null)
            throw new IllegalArgumentException(
                "invalid vehicle name: " + id);
    }
}


对于只有单个需要代理的对象, 可以很方便的应用上述的"代理"方式, 对于多个相互独立的对象而已, 也可以使用
public class VisualComponent {
    private final List<KeyListener> keyListeners = new CopyOnWriteArrayList<KeyListener>();
    private final List<MouseListener> mouseListeners = new CopyOnWriteArrayList<MouseListener>();
    public void add(..);
    public void remove(...);
}


但是如果这些对象有相互关系, 就出问题了
public class NumberRange {
    // INVARIANT: lower <= upper
    private final AtomicInteger lower = new AtomicInteger(0);
    private final AtomicInteger upper = new AtomicInteger(0);

    public void setLower(int i) {
        // Warning -- unsafe check-then-act
        if (i > upper.get())
            throw new IllegalArgumentException(
                    "can't set lower to " + i + " > upper");
        lower.set(i);
    }

    public void setUpper(int i) {
        // Warning -- unsafe check-then-act
        if (i < lower.get())
            throw new IllegalArgumentException(
                    "can't set upper to " + i + " < lower");
        upper.set(i);
    }

    public boolean isInRange(int i) {
        return (i >= lower.get() && i <= upper.get());
    }
}

}
显然setLower, setUpper, isInRange三个方法的调用没有原子性保障, 而且isInRange同时依赖到两个相关的值, 很容易导致结果错误. 需要增加某些锁定来保证. 或者运行的情况下, 把两个对象合并为一个

如何给线程安全的类增加方法
1) 修改源代码, 最好. 需了解原来的线程安全的策略
2) 继承类, 并增加synchronized方法.
3) 用Decorator模式, 把类包起来, 增加新方法, 然而需要注意锁定的对象. 比如下面是不对的
public class ListHelper<E> {
   
//锁定对象为返回的list
    public List<E> list = Collections.synchronizedList(new ArrayList<E>());
    ...
    public synchronized boolean putIfAbsent(E x) {
//锁定对象为ListHelper对象
        boolean absent = !list.contains(x);
        if (absent)
            list.add(x);
        return absent;
    }
}

因为两个同步的锁定不是同一个对象, 因此不同的线程可以分别操作putIfAbsent方法和list对象固有的方法. 如果要让这个类正确运行, 需要修正如下
public class ListHelper<E> {
   
//锁定对象为list
    public List<E> list =Collections.synchronizedList(new ArrayList<E>());
    ...
    public boolean putIfAbsent(E x) {
        synchronized (list) {
//锁定对象为list
            boolean absent = !list.contains(x);
            if (absent)
                list.add(x);
            return absent;
        }
    }
}


使用synchronized collection的原子性的问题
比如下面的代码:
public class VectorHelper{
public static Object getLast(Vector list) {
    int lastIndex = list.size() - 1;
    return list.get(lastIndex);
}

public static void deleteLast(Vector list) {
    int lastIndex = list.size() - 1;
    list.remove(lastIndex);
}
}
非常简单, 很多代码都是这样写的, 但是, 这段代码如果要正常运行, 必须是在假设Vertor对象是不被多个线程共享的情况下. 因为虽然Vector本身是线程安全的, 但VectorHelper不是, 并且getLast和deleteLast同时依赖于Vector.size()来判断最后一个元素. 很容易造成ArrayIndexOutOfBoundsException. 如果Vector被多个线程共享, 最简单的就是加上同步, 然后对一个集合的同步会带来很大的性能代价, 因为阻止了其他线程对集合的访问, 特别是当集合很大并且处理的任务非常大的情况下.

另一种变通的方法是, 在遍历集合之前, 复制一份集合的引用. 当然集合复制也有细微的性能代价.

被隐藏的Iterator
public class HiddenIterator {
    @GuardedBy("this")
    private final Set<Integer> set = new HashSet<Integer>();

    public synchronized void add(Integer i) { set.add(i); }
    public synchronized void remove(Integer i) { set.remove(i); }

    public void addTenThings() {
        Random r = new Random();
        for (int i = 0; i < 10; i++)
            add(r.nextInt());
        System.out.println("DEBUG: added ten elements to " + set);
   }
}
能想象这么简单的代码会在什么地方出错么? 答案是最后一行, System.out.println, 因为用到的set.toString(), 而toString()内部是会用Iterator来访问set的, 一旦此过程中set被修改, 就抛出ConcurrentModificationException.

JDK5的并发集合
ConcurrentMap(接口)和 ConcurrentHashMap, 并发环境下HashMap的替代品
CopyOnWriteArrayList, 并发环境下List的替代品
Queue:
ConcurrentLinkedQueue, PriorityQueue(非并发). 不阻塞, 如果队列为空, get()返回null
BlockingQueue: 它的方法是阻塞的, 当队列为空, get()会阻塞直到队列有元素加入, 当队列满脸, insert()也会阻塞

ConcurrentHashMap使用一种
lock striping的机制来实现并发控制, 并且提供了弱一致性的Iterator, 允许在迭代期间被修改而不抛出ConcurrentModificationException(例如,忽略被删除的元素). 然而作为代价, size()返回的值不是精确的元素的数量, 不过size()在并发环境的作用比get, put, containsKey的用途小得多

看一小段程序
        ConcurrentHashMap<String, String> m = new ConcurrentHashMap<String, String>();
        m.put("1", "one");
        m.put("2", "two");
        m.put("3", "three");
       
        Iterator keyIt = m.keySet().iterator();
       
        // !! remove some element, remove-if-equals 风格的操作
        m.remove("1", "one");
       
        while (keyIt.hasNext()) {
            String k = (String)keyIt.next();
            System.out.println("key: " + k + ", value: " + m.get(k));
        }

输出结果:
key: 1, value: null
key: 3, value: three
key: 2, value: two

很短的代码, 一下执行完了, 没有再报错, 可以发现remove操作没有影响到遍历抛出异常. 然而, key: 1, value: null 这行输出说明了我们还留着对这个key的引用.

ConcurrentHashMap有几种新的风格的方法, put-if-absent, remove-if-equal, replace-if-equal, 比如上面的 m.remove("1", "one"); 就是, 如果改为 m.remove("1", "two"); 那么["1","one"]这一对就被保留下来了

CopyOnWriteArrayList, 顾名思义, 就能猜到每次都这个类做了改动, 就会copy一份原来的数组, 在改动后替换原来的数组, 再返回给调用者

BlockingQueue是基于 生产者-消费者 的模式构建的, 包括LinkedBlockingQueue, ArrayBlockingQueue, PriorityBlockingQueue,SynchronousQueue 4个实现类. 看一点示例代码:
    public static void putAndOffer() throws InterruptedException {
        BlockingQueue<String> q = new ArrayBlockingQueue<String>(1);
        q.offer("1");
        System.out.println("offer A done");
        q.offer("2");
        System.out.println("offer B done");
       
        q.clear();
        q.put("A");
        System.out.println("put A done");
        q.put("B");
        System.out.println("put B done");
    }

输出结果:
offer A done
offer B done
put A done

我们指定了BlockingQueue的容量为1, offer方法是不阻塞的, 所以q.offer("2");直接返回false, 而put方法是阻塞的, 所以System.out.println("put B done");一直没有执行.

PriorityBlockingQueue: 对于加入队列的元素是可排序的
SynchronousQueue: 不能算是queue的实现, 但是模仿了queue的行为, 更像是worker模式的实现. 因为它内部维护了一组用于处理元素的线程, 并且直接把加入队列的元素分配给处理该元素的线程. 如果没有可用线程, 就阻塞了.

BlockingQueue实例代码
下面是摘录的代码, 使用BlockingQueue, 分配N个线程执行文件索引的任务, 很经典:
public class FileCrawler implements Runnable { //这个是producer角色
    private final BlockingQueue<File> fileQueue;
    private final FileFilter fileFilter;
    private final File root;
    ...
    public FileCrawler(File root, BlockingQueue queue, FileFilter filter){ ... }
    public void run() {
        try {
            crawl(root);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }

    /*把该目录下所有的文件夹都放进一个queue, 如果满了, 就阻塞*/
    private void crawl(File root) throws InterruptedException { 
        File[] entries = root.listFiles(fileFilter);
        if (entries != null) {
            for (File entry : entries)
                if (entry.isDirectory())
                    crawl(entry);
                else if (!alreadyIndexed(entry))
                    fileQueue.put(entry); //把找到的目录放入队列
        }
    }
}

public class Indexer implements Runnable { //这个是consumer角色
    private final BlockingQueue<File> queue;

    public Indexer(BlockingQueue<File> queue) { // queue在indexer和FileCrawler之间共享
        this.queue = queue;
    }

    public void run() {
        try {
            while (true)
                indexFile(queue.take()); //从queue中获取一个File对象进行索引
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }
}

//这个是客户端的方法, 可以假设roots是在界面设置的几个目录
public static void startIndexing(File[] roots) {
BlockingQueue<File> queue = new LinkedBlockingQueue<File>(BOUND);
    FileFilter filter = new FileFilter() {
        public boolean accept(File file) { return true; }
    };

    for (File root : roots)
        new Thread(new FileCrawler(queue, filter, root)).start(); 
        //此处是否可以考虑使用线程池更有效? 而且, 如果有些目录层次非常深, 
        //就会有某些线程运行时间非常长, 相反有些线程非常快就执行完毕.
        //最恶劣的情况是可能其他线程都完成了, 而退化到只有一个线程中运行,
        //成为"单线程"程序?

    for (int i = 0; i < N_CONSUMERS; i++)
        new Thread(new Indexer(queue)).start();  //此处是否可以考虑使用线程池更有效?
}

基于上述这种"单线程"的考虑, 不谋而合的, JDK6引入了一种"Work Stealing"的模式, 即N个线程中运行, 
每个线程处理自己的事情, 一旦自己手头的事情处理, 那么就去尝试"偷"来其他线程的任务来运行. 这样一来, 
系统就会时刻保持多个线程中处理任务, 而不是出现"一人忙活,大家凉快"的情况

转自:http://hi.baidu.com/iwishyou2/blog/item/552e162adab77f305243c116.html

分享到:
评论

相关推荐

    小程序毕业设计-基于微信小程序的影院选座系统+ssm(包括源码,数据库,教程).zip

    Java 毕业设计,小程序毕业设计,小程序课程设计,含有代码注释,新手也可看懂。毕业设计、期末大作业、课程设计、高分必看,下载下来,简单部署,就可以使用。 包含:项目源码、数据库脚本、软件工具等,该项目可以作为毕设、课程设计使用,前后端代码都在里面。 该系统功能完善、界面美观、操作简单、功能齐全、管理便捷,具有很高的实际应用价值。 项目都经过严格调试,确保可以运行!可以放心下载 1. 技术组成 前端: 小程序 后台框架:SSM/SpringBoot(如果有的话) 开发环境:idea,微信开发者工具 数据库:MySql(建议用 5.7 版本,8.0 有时候会有坑) 数据库可视化工具:使用 Navicat 部署环境:Tomcat(建议用 7.x 或者 8.x 版本),maven

    大二下算法作业,迷宫生成算法以及基于递归的求解,可以在blender中生成3D模型.zip

    大二下算法作业,迷宫生成算法以及基于递归的求解,可以在blender中生成3D模型.zip

    小程序毕业设计-基于微信小程序的在线视频教育系统+ssm(包括源码,数据库,教程).zip

    Java 毕业设计,小程序毕业设计,小程序课程设计,含有代码注释,新手也可看懂。毕业设计、期末大作业、课程设计、高分必看,下载下来,简单部署,就可以使用。 包含:项目源码、数据库脚本、软件工具等,该项目可以作为毕设、课程设计使用,前后端代码都在里面。 该系统功能完善、界面美观、操作简单、功能齐全、管理便捷,具有很高的实际应用价值。 项目都经过严格调试,确保可以运行!可以放心下载 1. 技术组成 前端: 小程序 后台框架:SSM/SpringBoot(如果有的话) 开发环境:idea,微信开发者工具 数据库:MySql(建议用 5.7 版本,8.0 有时候会有坑) 数据库可视化工具:使用 Navicat 部署环境:Tomcat(建议用 7.x 或者 8.x 版本),maven

    基于SpringBoot+Vue.JS前后端分离的游乐园管理系统 源码+数据库+录屏(毕业设计)

    游乐园管理系统是一个综合性的软件解决方案,旨在为游乐园提供高效的日常运营支持。该系统采用现代的前后端分离架构,前端使用Vue.js框架,后端则基于SpringBoot框架进行开发。Vue.js是一个渐进式JavaScript框架,它易于上手且灵活,非常适合构建用户界面。SpringBoot则提供了快速开发的能力,简化了配置和部署过程,使得后端服务的开发更加高效。 用户管理:允许管理员管理游客信息,包括注册、登录、权限分配等。 设施管理:对游乐园内的游乐设施进行管理,包括设施信息的录入、更新和维护。 票务系统:处理门票销售、折扣策略、在线预订等功能。 安全监控:实时监控游乐园内的安全状况,确保游客的安全。 数据分析:收集和分析游客行为数据,为游乐园的运营决策提供支持。 客户服务:提供客户服务功能,如失物招领、投诉处理等。 启动教程:https://www.bilibili.com/video/BV1SzbFe7EGZ

    《深度学习入门 基于Python的理论与实现》学习笔记.zip

    深度学习是机器学习的一个子领域,它基于人工神经网络的研究,特别是利用多层次的神经网络来进行学习和模式识别。深度学习模型能够学习数据的高层次特征,这些特征对于图像和语音识别、自然语言处理、医学图像分析等应用至关重要。以下是深度学习的一些关键概念和组成部分: 1. **神经网络(Neural Networks)**:深度学习的基础是人工神经网络,它是由多个层组成的网络结构,包括输入层、隐藏层和输出层。每个层由多个神经元组成,神经元之间通过权重连接。 2. **前馈神经网络(Feedforward Neural Networks)**:这是最常见的神经网络类型,信息从输入层流向隐藏层,最终到达输出层。 3. **卷积神经网络(Convolutional Neural Networks, CNNs)**:这种网络特别适合处理具有网格结构的数据,如图像。它们使用卷积层来提取图像的特征。 4. **循环神经网络(Recurrent Neural Networks, RNNs)**:这种网络能够处理序列数据,如时间序列或自然语言,因为它们具有记忆功能,能够捕捉数据中的时间依赖性。 5. **长短期记忆网络(Long Short-Term Memory, LSTM)**:LSTM 是一种特殊的 RNN,它能够学习长期依赖关系,非常适合复杂的序列预测任务。 6. **生成对抗网络(Generative Adversarial Networks, GANs)**:由两个网络组成,一个生成器和一个判别器,它们相互竞争,生成器生成数据,判别器评估数据的真实性。 7. **深度学习框架**:如 TensorFlow、Keras、PyTorch 等,这些框架提供了构建、训练和部署深度学习模型的工具和库。 8. **激活函数(Activation Functions)**:如 ReLU、Sigmoid、Tanh 等,它们在神经网络中用于添加非线性,使得网络能够学习复杂的函数。 9. **损失函数(Loss Functions)**:用于评估模型的预测与真实值之间的差异,常见的损失函数包括均方误差(MSE)、交叉熵(Cross-Entropy)等。 10. **优化算法(Optimization Algorithms)**:如梯度下降(Gradient Descent)、随机梯度下降(SGD)、Adam 等,用于更新网络权重,以最小化损失函数。 11. **正则化(Regularization)**:技术如 Dropout、L1/L2 正则化等,用于防止模型过拟合。 12. **迁移学习(Transfer Learning)**:利用在一个任务上训练好的模型来提高另一个相关任务的性能。 深度学习在许多领域都取得了显著的成就,但它也面临着一些挑战,如对大量数据的依赖、模型的解释性差、计算资源消耗大等。研究人员正在不断探索新的方法来解决这些问题。

    java-ssh-jsp-mysql小区物业管理系统实现源码(项目源码-说明文档)

    本系统采用了BS架构的模式开发,利用浏览器就可以随处打开,也就是说小区的住户在家里就能进行上网,打开网站,进行物业费的缴费。系统采用了SSH框架技术开发,数据库采用了mysql数据库进行管理 物业管理系统,分为前后台的管理,系统的主要功能包括:业主信息管理,小区新闻,小区风景的展示,在线水电费的缴费,在线对小区设备的报修等 项目关键技术 开发工具:IDEA 、Eclipse 编程语言: Java 数据库: MySQL5.7+ 后端技术:ssh 前端技术:jsp 关键技术:jsp、spring、ssm、ssh、MYSQL、MAVEN 数据库工具:Navicat、SQLyog

    高仿网易云课堂小程序源码学习

    高仿网易云课堂小程序源码学习

    SAP S4新建用户,分配用户,激活用户

    SAP S4的BAISIS 已经取消,但 新建用户,分配用户,以及权限分配 激活用户的均是需要掌握的

    智能翻译官cpc-bd07-20752777288491826.exe

    ‌智能翻译官获得了广泛的好评‌,这主要得益于其高效、准确以及用户友好的特性。以下是一些具体的评价细节: ‌用户界面和操作体验‌:智能翻译官提供了一个直观且易于使用的界面,使得用户能够轻松地进行翻译操作。无论是文字输入、拍照翻译还是语音输入,智能翻译官都能提供流畅的使用体验,大大提高了用户的工作和沟通效率‌12。 ‌翻译准确性和速度‌:智能翻译官在翻译准确性和速度方面表现出色。它支持多种语言的翻译,包括但不限于英语、日语、韩语等,并且能够在短时间内完成翻译,确保了沟通的实时性和有效性‌23。 ‌功能多样性‌:除了基本的翻译功能外,智能翻译官还提供了同声传译、录音文件保存、实景AR翻译等多种功能。这些功能使得智能翻译官成为开会、旅行等多种场景下的理想选择‌2。 ‌用户反馈‌:从用户反馈来看,智能翻译官不仅受到了普通用户的欢迎,也得到了专业人士的认可。无论是学生、商务人士还是旅游者,都对其表示满意,认为它极大地便利了他们的学习和生活‌12。 综上所述,智能翻译官以其高效、准确、用户友好的特点,赢得了广泛的好评和推荐。无论是对于需要频繁进行语言沟通的用户,还是对于需要学习不同语言的学

    喜鹤付费V3(1).zip

    喜鹤付费V3(1).zip

    c#代码介绍23种设计模式-03工厂模式(附代码)

    1. 工厂方法模式之所以可以解决简单工厂的模式: 是因为它的实现把具体产品的创建推迟到子类中,此时工厂类不再负责所有产品的创建,而只是给出具体工厂必须实现的接口, 这样工厂方法模式就可以允许系统不修改工厂类逻辑的情况下来添加新产品,这样也就克服了简单工厂模式中缺点 2. 使用工厂方法实现的系统,如果系统需要添加新产品时: 我们可以利用多态性来完成系统的扩展,对于抽象工厂类和具体工厂中的代码都不需要做任何改动。 例如,我们我们还想点一个“肉末茄子”,此时我们只需要定义一个肉末茄子具体工厂类和肉末茄子类就可以。而不用像简单工厂模式中那样去修改工厂类中的实现 3. 从UML图可以看出,在工厂方法模式中,工厂类与具体产品类具有平行的等级结构,它们之间是一一对应的。针对UML图的解释如下: Creator类:充当抽象工厂角色,任何具体工厂都必须继承该抽象类 TomatoScrambledEggsFactory和ShreddedPorkWithPotatoesFactory类:充当具体工厂角色,用来创建具体产品 Food类:充当抽象产品角色,具体产品的抽象类。任何具体产品都应该继承该类 Tom

    基于深度学习的手语识别项目.zip

    深度学习是机器学习的一个子领域,它基于人工神经网络的研究,特别是利用多层次的神经网络来进行学习和模式识别。深度学习模型能够学习数据的高层次特征,这些特征对于图像和语音识别、自然语言处理、医学图像分析等应用至关重要。以下是深度学习的一些关键概念和组成部分: 1. **神经网络(Neural Networks)**:深度学习的基础是人工神经网络,它是由多个层组成的网络结构,包括输入层、隐藏层和输出层。每个层由多个神经元组成,神经元之间通过权重连接。 2. **前馈神经网络(Feedforward Neural Networks)**:这是最常见的神经网络类型,信息从输入层流向隐藏层,最终到达输出层。 3. **卷积神经网络(Convolutional Neural Networks, CNNs)**:这种网络特别适合处理具有网格结构的数据,如图像。它们使用卷积层来提取图像的特征。 4. **循环神经网络(Recurrent Neural Networks, RNNs)**:这种网络能够处理序列数据,如时间序列或自然语言,因为它们具有记忆功能,能够捕捉数据中的时间依赖性。 5. **长短期记忆网络(Long Short-Term Memory, LSTM)**:LSTM 是一种特殊的 RNN,它能够学习长期依赖关系,非常适合复杂的序列预测任务。 6. **生成对抗网络(Generative Adversarial Networks, GANs)**:由两个网络组成,一个生成器和一个判别器,它们相互竞争,生成器生成数据,判别器评估数据的真实性。 7. **深度学习框架**:如 TensorFlow、Keras、PyTorch 等,这些框架提供了构建、训练和部署深度学习模型的工具和库。 8. **激活函数(Activation Functions)**:如 ReLU、Sigmoid、Tanh 等,它们在神经网络中用于添加非线性,使得网络能够学习复杂的函数。 9. **损失函数(Loss Functions)**:用于评估模型的预测与真实值之间的差异,常见的损失函数包括均方误差(MSE)、交叉熵(Cross-Entropy)等。 10. **优化算法(Optimization Algorithms)**:如梯度下降(Gradient Descent)、随机梯度下降(SGD)、Adam 等,用于更新网络权重,以最小化损失函数。 11. **正则化(Regularization)**:技术如 Dropout、L1/L2 正则化等,用于防止模型过拟合。 12. **迁移学习(Transfer Learning)**:利用在一个任务上训练好的模型来提高另一个相关任务的性能。 深度学习在许多领域都取得了显著的成就,但它也面临着一些挑战,如对大量数据的依赖、模型的解释性差、计算资源消耗大等。研究人员正在不断探索新的方法来解决这些问题。

    【5层】2800平米框架商务写字楼毕业设计(含计算书,建筑、结构图).zip

    【5层】2800平米框架商务写字楼毕业设计(含计算书,建筑、结构图) 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 、6可私信博主看论文后选择购买源代码。

    大气污染控制工程课程设计某厂燃煤锅炉烟气除尘处理工程方案设计.doc

    大气污染控制工程课程设计某厂燃煤锅炉烟气除尘处理工程方案设计.doc

    EXCLE批量写入模版

    你是否遇到过老板各种苛刻的要求?例如,你手上有份excel表格汇总着上千信息条,老板却要求你把每条信息保存为独立一份excel工作薄,上千条信息条就是要生成上千份工作薄,怎么做?手动录入?有加班工资吗?没有的话,以下的excel模版能帮到你!只需按一下按钮,加班?NO!直接摸鱼~~(WPS、EXCEL均可正常使用)

    win64 CC2024.zip

    SmartTools InDesign插件

    火焰火圈喷火特效:Stylized Fire Effects Pack v3.0

    该包包含 10 个预制体: - 火焰喷射器 - 火球 - 火之魔球 - 火把 - 篝火 - 小型篝火 - 烟雾 - 火墙 - 火环 - 火区域。 这个在 3D 和 2D 视图中都能使用。

    2023中国大陆薪资指南.pdf

    2023中国大陆薪资指南.pdf

    基于深度学习来实现序列到序列.zip

    深度学习是机器学习的一个子领域,它基于人工神经网络的研究,特别是利用多层次的神经网络来进行学习和模式识别。深度学习模型能够学习数据的高层次特征,这些特征对于图像和语音识别、自然语言处理、医学图像分析等应用至关重要。以下是深度学习的一些关键概念和组成部分: 1. **神经网络(Neural Networks)**:深度学习的基础是人工神经网络,它是由多个层组成的网络结构,包括输入层、隐藏层和输出层。每个层由多个神经元组成,神经元之间通过权重连接。 2. **前馈神经网络(Feedforward Neural Networks)**:这是最常见的神经网络类型,信息从输入层流向隐藏层,最终到达输出层。 3. **卷积神经网络(Convolutional Neural Networks, CNNs)**:这种网络特别适合处理具有网格结构的数据,如图像。它们使用卷积层来提取图像的特征。 4. **循环神经网络(Recurrent Neural Networks, RNNs)**:这种网络能够处理序列数据,如时间序列或自然语言,因为它们具有记忆功能,能够捕捉数据中的时间依赖性。 5. **长短期记忆网络(Long Short-Term Memory, LSTM)**:LSTM 是一种特殊的 RNN,它能够学习长期依赖关系,非常适合复杂的序列预测任务。 6. **生成对抗网络(Generative Adversarial Networks, GANs)**:由两个网络组成,一个生成器和一个判别器,它们相互竞争,生成器生成数据,判别器评估数据的真实性。 7. **深度学习框架**:如 TensorFlow、Keras、PyTorch 等,这些框架提供了构建、训练和部署深度学习模型的工具和库。 8. **激活函数(Activation Functions)**:如 ReLU、Sigmoid、Tanh 等,它们在神经网络中用于添加非线性,使得网络能够学习复杂的函数。 9. **损失函数(Loss Functions)**:用于评估模型的预测与真实值之间的差异,常见的损失函数包括均方误差(MSE)、交叉熵(Cross-Entropy)等。 10. **优化算法(Optimization Algorithms)**:如梯度下降(Gradient Descent)、随机梯度下降(SGD)、Adam 等,用于更新网络权重,以最小化损失函数。 11. **正则化(Regularization)**:技术如 Dropout、L1/L2 正则化等,用于防止模型过拟合。 12. **迁移学习(Transfer Learning)**:利用在一个任务上训练好的模型来提高另一个相关任务的性能。 深度学习在许多领域都取得了显著的成就,但它也面临着一些挑战,如对大量数据的依赖、模型的解释性差、计算资源消耗大等。研究人员正在不断探索新的方法来解决这些问题。

    react-hooks实现-前端《无缝轮播图》

    使用react hooks + antd + sass实现一个简易的无缝轮播图,整体核心代码不到30行,当然如果想自定义一些配置,可以继续扩展,目前只配置了支持展示多少个轮播片。 如果想了解无缝轮播图的原理,可以直接无脑入这个,真的对于新手或者对于动画弱项的前端小伙伴们学习!

Global site tag (gtag.js) - Google Analytics