前端技术
HTML
CSS
Javascript
前端框架和UI库
VUE
ReactJS
AngularJS
JQuery
NodeJS
JSON
Element-UI
Bootstrap
Material UI
服务端和客户端
Java
Python
PHP
Golang
Scala
Kotlin
Groovy
Ruby
Lua
.net
c#
c++
后端WEB和工程框架
SpringBoot
SpringCloud
Struts2
MyBatis
Hibernate
Tornado
Beego
Go-Spring
Go Gin
Go Iris
Dubbo
HessianRPC
Maven
Gradle
数据库
MySQL
Oracle
Mongo
中间件与web容器
Redis
MemCache
Etcd
Cassandra
Kafka
RabbitMQ
RocketMQ
ActiveMQ
Nacos
Consul
Tomcat
Nginx
Netty
大数据技术
Hive
Impala
ClickHouse
DorisDB
Greenplum
PostgreSQL
HBase
Kylin
Hadoop
Apache Pig
ZooKeeper
SeaTunnel
Sqoop
Datax
Flink
Spark
Mahout
数据搜索与日志
ElasticSearch
Apache Lucene
Apache Solr
Kibana
Logstash
数据可视化与OLAP
Apache Atlas
Superset
Saiku
Tesseract
系统与容器
Linux
Shell
Docker
Kubernetes
[VLAN标签在Docker网络中的应用 ]的搜索结果
这里是文章列表。热门标签的颜色随机变换,标签颜色没有特殊含义。
点击某个标签可搜索标签相关的文章。
点击某个标签可搜索标签相关的文章。
转载文章
...连看等消除类游戏中的应用,展示了通过机器学习预测最佳消除路径的可能性。 总的来说,在继续深入实践HTML、CSS、JavaScript基础开发的同时,紧跟Web技术前沿进展,结合先进的编程语言、图形处理技术和AI算法,将有助于开发者打造出更为丰富、流畅且富有挑战性的消除类游戏产品,不断满足日益增长的用户体验需求。
2023-06-08 15:26:34
516
转载
转载文章
...技术的最新进展和实际应用案例。近期,随着数字化转型加速,MySQL 8.0版本凭借其增强的安全性、更高的性能以及对JSON文档支持的改进,得到了广泛应用。例如,在云服务领域,AWS RDS已全面支持MySQL 8.0,用户可以更加便捷地构建高性能、高可用的应用程序。 此外,对于数据库管理及优化方面,一篇来自InfoQ的技术文章《MySQL 8.0新特性解读及其在大规模数据处理中的实践》深度剖析了MySQL 8.0的各项新功能,包括窗口函数、通用表表达式等,并通过实例演示如何利用这些新特性提高查询效率,降低存储成本。 同时,针对日益增长的数据安全需求,《企业如何借助MySQL强化数据库安全性》一文强调了实施严格访问控制、审计跟踪、加密传输和透明数据加密等功能的重要性,并引用了最新的行业标准和法规要求作为依据。 对于开发者而言,学习并掌握MySQL的高级特性以及最佳实践至关重要。近日,Oracle发布了MySQL HeatWave,这是一种融合分析型数据库引擎,能在同一个MySQL数据库中实现事务处理与实时分析,极大简化了大数据处理流程,提升了业务决策速度。 综上所述,了解MySQL的最新动态和技术演进不仅可以帮助我们更好地进行日常的数据库管理工作,还能洞悉未来数据库技术的发展趋势,从而为我们的系统设计与优化提供有力支撑。在实战中,结合具体业务场景灵活运用SQL语句及数据库管理系统,将有效提升整个系统的稳定性和效率。
2024-02-16 12:44:07
544
转载
转载文章
...acle中的一种高级应用,每个版本都在不断的加强,使用DBMS_AQ系统包进行相应的操作,是Oracle的默认组件,只要安装了Oracle数据库就可以使用。使用AQ可以在多个Oracle数据库、Oracle与Java、C等系统中进行数据传输。 下面分步骤说明如何创建Oracle AQ 1. 创建消息负荷payload Oracle AQ中传递的消息被称为有效负荷(payloads),格式可以是用户自定义对象或XMLType或ANYDATA。本例中我们创建一个简单的对象类型用于传递消息。 create type demo_queue_payload_type as object (message varchar2(4000)); 2. 创建队列表 队列表用于存储消息,在入队时自动存入表中,出队时自动删除。使用DBMS_AQADM包进行数据表的创建,只需要写表名,同时设置相应的属性。对于队列需要设置multiple_consumers为false,如果使用发布/订阅模式需要设置为true。 begin dbms_aqadm.create_queue_table( queue_table => 'demo_queue_table', queue_payload_type => 'demo_queue_payload_type', multiple_consumers => false ); end; 执行完后可以查看oracle表中自动生成了demo_queue_table表,可以查看影响子段(含义比较清晰)。 3. 创建队列并启动 创建队列并启动队列: begin dbms_aqadm.create_queue ( queue_name => 'demo_queue', queue_table => 'demo_queue_table' ); dbms_aqadm.start_queue( queue_name => 'demo_queue' ); end; 至此,我们已经创建了队列有效负荷,队列表和队列。可以查看以下系统创建了哪些相关的对象: SELECT object_name, object_type FROM user_objects WHERE object_name != 'DEMO_QUEUE_PAYLOAD_TYPE'; OBJECT_NAME OBJECT_TYPE ------------------------------ --------------- DEMO_QUEUE_TABLE TABLE SYS_C009392 INDEX SYS_LOB0000060502C00030$$ LOB AQ$_DEMO_QUEUE_TABLE_T INDEX AQ$_DEMO_QUEUE_TABLE_I INDEX AQ$_DEMO_QUEUE_TABLE_E QUEUE AQ$DEMO_QUEUE_TABLE VIEW DEMO_QUEUE QUEUE 我们看到一个队列带出了一系列自动生成对象,有些是被后面直接用到的。不过有趣的是,创建了第二个队列。这就是所谓的异常队列(exception queue)。如果AQ无法从我们的队列接收消息,将记录在该异常队列中。 消息多次处理出错等情况会自动转移到异常的队列,对于异常队列如何处理目前笔者还没有找到相应的写法,因为我使用的场景并不要求消息必须一对一的被处理,只要起到通知的作用即可。所以如果消息转移到异常队列,可以执行清空队列表中的数据 delete from demo_queue_table; 4. 队列的停止和删除 如果需要删除或重建可以使用下面的方法进行操作: BEGIN DBMS_AQADM.STOP_QUEUE( queue_name => 'demo_queue' ); DBMS_AQADM.DROP_QUEUE( queue_name => 'demo_queue' ); DBMS_AQADM.DROP_QUEUE_TABLE( queue_table => 'demo_queue_table' ); END; 5. 入队消息 入列操作是一个基本的事务操作(就像往队列表Insert),因此我们需要提交。 declare r_enqueue_options DBMS_AQ.ENQUEUE_OPTIONS_T; r_message_properties DBMS_AQ.MESSAGE_PROPERTIES_T; v_message_handle RAW(16); o_payload demo_queue_payload_type; begin o_payload := demo_queue_payload_type('what is you name ?'); dbms_aq.enqueue( queue_name => 'demo_queue', enqueue_options => r_enqueue_options, message_properties => r_message_properties, payload => o_payload, msgid => v_message_handle ); commit; end; 通过SQL语句查看消息是否正常入队: select from aq$demo_queue_table; select user_data from aq$demo_queue_table; 6. 出队消息 使用Oracle进行出队操作,我没有实验成功(不确定是否和DBMS_OUTPUT的执行权限有关),代码如下,读者可以进行调试: declare r_dequeue_options DBMS_AQ.DEQUEUE_OPTIONS_T; r_message_properties DBMS_AQ.MESSAGE_PROPERTIES_T; v_message_handle RAW(16); o_payload demo_queue_payload_type; begin DBMS_AQ.DEQUEUE( queue_name => 'demo_queue', dequeue_options => r_dequeue_options, message_properties => r_message_properties, payload => o_payload, msgid => v_message_handle ); DBMS_OUTPUT.PUT_LINE( ' Browse message is [' || o_payload.message || ']' ); end; 二、Java使用JMS监听并处理Oracle AQ队列 Java使用JMS进行相应的处理,需要使用Oracle提供的jar,在Oracle安装目录可以找到:在linux中可以使用find命令进行查找,例如 find pwd -name 'jmscommon.jar' 需要的jar为: app/oracle/product/12.1.0/dbhome_1/rdbms/jlib/jmscommon.jar app/oracle/product/12.1.0/dbhome_1/jdbc/lib/ojdbc7.jar app/oracle/product/12.1.0/dbhome_1/jlib/orai18n.jar app/oracle/product/12.1.0/dbhome_1/jlib/jta.jar app/oracle/product/12.1.0/dbhome_1/rdbms/jlib/aqapi_g.jar 1. 创建连接参数类 实际使用时可以把参数信息配置在properties文件中,使用Spring进行注入。 package org.kevin.jms; / @author 李文锴 连接参数信息 / public class JmsConfig { public String username = "ckevin"; public String password = "a111111111"; public String jdbcUrl = "jdbc:oracle:thin:@127.0.0.1:1521:orcl"; public String queueName = "demo_queue"; } 2. 创建消息转换类 因为消息载荷是Oracle数据类型,需要提供一个转换工厂类将Oracle类型转换为Java类型。 package org.kevin.jms; import java.sql.SQLException; import oracle.jdbc.driver.OracleConnection; import oracle.jdbc.internal.OracleTypes; import oracle.jpub.runtime.MutableStruct; import oracle.sql.CustomDatum; import oracle.sql.CustomDatumFactory; import oracle.sql.Datum; import oracle.sql.STRUCT; / @author 李文锴 数据类型转换类 / @SuppressWarnings("deprecation") public class QUEUE_MESSAGE_TYPE implements CustomDatum, CustomDatumFactory { public static final String _SQL_NAME = "QUEUE_MESSAGE_TYPE"; public static final int _SQL_TYPECODE = OracleTypes.STRUCT; MutableStruct _struct; // 12表示字符串 static int[] _sqlType = { 12 }; static CustomDatumFactory[] _factory = new CustomDatumFactory[1]; static final QUEUE_MESSAGE_TYPE _MessageFactory = new QUEUE_MESSAGE_TYPE(); public static CustomDatumFactory getFactory() { return _MessageFactory; } public QUEUE_MESSAGE_TYPE() { _struct = new MutableStruct(new Object[1], _sqlType, _factory); } public Datum toDatum(OracleConnection c) throws SQLException { return _struct.toDatum(c, _SQL_NAME); } public CustomDatum create(Datum d, int sqlType) throws SQLException { if (d == null) return null; QUEUE_MESSAGE_TYPE o = new QUEUE_MESSAGE_TYPE(); o._struct = new MutableStruct((STRUCT) d, _sqlType, _factory); return o; } public String getContent() throws SQLException { return (String) _struct.getAttribute(0); } } 3. 主类进行消息处理 package org.kevin.jms; import java.util.Properties; import javax.jms.Message; import javax.jms.MessageConsumer; import javax.jms.MessageListener; import javax.jms.Queue; import javax.jms.QueueConnection; import javax.jms.QueueConnectionFactory; import javax.jms.Session; import oracle.jms.AQjmsAdtMessage; import oracle.jms.AQjmsDestination; import oracle.jms.AQjmsFactory; import oracle.jms.AQjmsSession; / @author 李文锴 消息处理类 / public class Main { public static void main(String[] args) throws Exception { JmsConfig config = new JmsConfig(); QueueConnectionFactory queueConnectionFactory = AQjmsFactory.getQueueConnectionFactory(config.jdbcUrl, new Properties()); QueueConnection conn = queueConnectionFactory.createQueueConnection(config.username, config.password); AQjmsSession session = (AQjmsSession) conn.createQueueSession(false, Session.AUTO_ACKNOWLEDGE); conn.start(); Queue queue = (AQjmsDestination) session.getQueue(config.username, config.queueName); MessageConsumer consumer = session.createConsumer(queue, null, QUEUE_MESSAGE_TYPE.getFactory(), null, false); consumer.setMessageListener(new MessageListener() { @Override public void onMessage(Message message) { System.out.println("ok"); AQjmsAdtMessage adtMessage = (AQjmsAdtMessage) message; try { QUEUE_MESSAGE_TYPE payload = (QUEUE_MESSAGE_TYPE) adtMessage.getAdtPayload(); System.out.println(payload.getContent()); } catch (Exception e) { e.printStackTrace(); } } }); Thread.sleep(1000000); } } 使用Oracle程序块进行入队操作,在没有启动Java时看到队列表中存在数据。启动Java后,控制台正确的输出的消息;通过Oracle程序块再次写入消息,发现控制台正确处理消息。Java的JMS监听不是立刻进行处理,可能存在几秒中的时间差,时间不等。 三、监控表记录变化通知Java 下面的例子创建一个数据表,然后在表中添加触发器,当数据变化后触发器调用存储过程给Oracle AQ发送消息,然后使用Java JMS对消息进行处理。 1. 创建表 创建student表,包含username和age两个子段,其中username时varchar2类型,age时number类型。 2. 创建存储过程 创建send_aq_msg存储过程,因为存储过程中调用dbms数据包,系统包在存储过程中执行需要进行授权(使用sys用户进行授权): grant execute on dbms_aq to ckevin; 注意存储过程中包含commit语句。 create or replace PROCEDURE send_aq_msg (info IN VARCHAR2) as r_enqueue_options DBMS_AQ.ENQUEUE_OPTIONS_T; r_message_properties DBMS_AQ.MESSAGE_PROPERTIES_T; v_message_handle RAW(16); o_payload demo_queue_payload_type; begin o_payload := demo_queue_payload_type(info); dbms_aq.enqueue( queue_name => 'demo_queue', enqueue_options => r_enqueue_options, message_properties => r_message_properties, payload => o_payload, msgid => v_message_handle ); commit; end send_aq_msg; 3. 创建触发器 在student表中创建触发器,当数据写入或更新时,如果age=18,则进行入队操作。需要调用存储过程发送消息,但触发器中不能包含事物提交语句,因此需要使用pragma autonomous_transaction;声明自由事物: CREATE OR REPLACE TRIGGER STUDENT_TR AFTER INSERT OR UPDATE OF AGE ON STUDENT FOR EACH ROW DECLARE pragma autonomous_transaction; BEGIN if :new.age = 18 then send_aq_msg(:new.username); end if; END; 创建完触发器后向执行插入或更新操作: insert into student (username,age) values ('jack.lee.3k', 18); update student set age=18 where username='jack003'; Java JMS可以正确的处理消息。 本篇文章为转载内容。原文链接:https://blog.csdn.net/weixin_42309178/article/details/115241521。 该文由互联网用户投稿提供,文中观点代表作者本人意见,并不代表本站的立场。 作为信息平台,本站仅提供文章转载服务,并不拥有其所有权,也不对文章内容的真实性、准确性和合法性承担责任。 如发现本文存在侵权、违法、违规或事实不符的情况,请及时联系我们,我们将第一时间进行核实并删除相应内容。
2023-12-17 14:22:22
138
转载
转载文章
...处理、机器学习等新兴应用场景。而诸如Kafka、Flink等流处理框架的兴起,也为海量数据的实时分析提供了强大支持。 不仅如此,学术界对于Trie树、Bitmap等数据结构的研究也在不断深入,结合新型硬件如SSD、GPU等进行并行优化,使得这些经典数据结构在现代海量数据处理场景下焕发新生。未来,随着量子计算和边缘计算等前沿技术的发展,海量数据处理的方法将更加丰富多元,效率也将有质的飞跃。 综上所述,海量数据处理技术正以前所未有的速度发展和完善,从理论研究到工程实践,各类创新技术和解决方案层出不穷,为大数据时代的数据价值挖掘奠定了坚实基础。广大读者可以通过关注最新的科研成果、行业报告和技术博客,深入了解这一领域的发展趋势和应用案例,以便更好地应对和解决实际工作中的海量数据挑战。
2024-03-01 12:40:17
541
转载
转载文章
...IO技术的最新进展和应用案例。近期,一项名为“Visual-Inertial Re-localization and Mapping in Dynamic Environments”的研究(来源:IEEE Robotics and Automation Letters, 2023)提出了一种能够适应动态环境变化的新型VIO定位与建图算法,它结合深度学习方法提升了在复杂场景中的重定位精度和鲁棒性。 同时,在自动驾驶领域,Waymo等公司在其无人驾驶车辆上广泛采用了基于视觉惯性导航的技术,并不断优化以提高实时定位和姿态估计的准确性。例如,一篇发布于《Nature》子刊《Machine Intelligence》上的文章揭示了他们如何将VIO与高精地图信息深度融合,以应对城市道路中的各种挑战。 此外,对于学术界和工业界来说,开源项目如OpenVINS、OKVIS以及本文提及的VINS-Fusion等持续迭代更新,不仅推动了VIO技术的发展,也为广大研究者提供了宝贵的实验平台。这些项目通过融合多传感器数据,实现了在无人机、机器人以及其他移动设备上的高效稳定定位导航。 总的来说,随着硬件性能的提升和算法优化的深化,视觉惯性里程计正逐渐成为自主导航系统中不可或缺的核心组件。在未来,我们期待看到更多创新性的研究成果和技术突破,进一步提升VIO在复杂环境下的适用性和可靠性。
2023-09-13 20:38:56
310
转载
转载文章
...TVM在边缘设备上的应用也越来越受到关注。一项最新研究显示,通过TVM进行模型压缩和量化,能够在保持模型精度的同时,显著减少推理时延,有效提升了诸如自动驾驶、无人机监控等场景中边缘设备的实时处理能力。 对于希望深入了解TVM内部工作原理和技术细节的读者,推荐查阅其官方文档和论文《TVM: An Automated End-to-End Optimizing Compiler for Deep Learning》。该论文详细阐述了TVM的设计理念和关键技术,为开发者提供了理论基础和实践指导。同时,积极参与TVM社区的讨论和贡献,也是提升自己在深度学习编译器领域技能的重要途径。不少开发人员分享了他们在使用TVM过程中优化模型性能、解决实际问题的经验心得,这些内容均可在GitHub项目页面及相关的技术论坛中找到,值得深入研读和参考。
2023-12-12 20:04:26
87
转载
转载文章
... 以上就是线形回归在应用时的注意事项。 本篇文章为转载内容。原文链接:https://blog.csdn.net/baidu_26137595/article/details/123766191。 该文由互联网用户投稿提供,文中观点代表作者本人意见,并不代表本站的立场。 作为信息平台,本站仅提供文章转载服务,并不拥有其所有权,也不对文章内容的真实性、准确性和合法性承担责任。 如发现本文存在侵权、违法、违规或事实不符的情况,请及时联系我们,我们将第一时间进行核实并删除相应内容。
2023-11-23 15:52:56
106
转载
Kafka
...为分布式消息中间件的应用场景愈发广泛。特别是在微服务架构日益普及的背景下,Kafka因其高吞吐量、低延迟的特点,成为了企业级数据流处理的首选方案。然而,这也带来了新的挑战。例如,国内某大型电商企业在双十一促销活动中,由于订单峰值激增,其基于Kafka构建的实时交易系统一度面临消息堆积的问题。经过紧急排查,发现主要是由于分区数量不足导致的负载不均。为此,该企业迅速调整了分区策略,并优化了消息生产和消费逻辑,最终顺利应对了高峰流量。 与此同时,国外科技巨头也对Kafka进行了持续改进。近日,Confluent公司宣布推出Kafka 3.6版本,该版本引入了多项新特性,包括增强型事务API、更高效的压缩算法以及对多租户环境的支持。这些更新旨在帮助企业更好地满足复杂业务场景的需求,同时也反映了Kafka社区对于技术创新的不懈追求。 此外,关于Kafka与ZooKeeper的关系,业界普遍关注其未来的演进方向。尽管Confluent正在推动KRaft(Kafka Raft-based Controller)项目,试图完全摆脱ZooKeeper的依赖,但在短期内,ZooKeeper仍将在许多传统部署环境中占据主导地位。因此,对于正在使用Kafka的企业而言,如何平衡现有基础设施与新技术之间的过渡,成为了一个值得深思的问题。 从长远来看,Kafka的成功离不开开源社区的支持。正如Apache软件基金会所倡导的理念,“开放、协作、共享”始终是推动技术创新的核心动力。在未来,随着更多企业和开发者加入到Kafka生态中,我们有理由相信,这一技术将继续保持旺盛的生命力,并在更多领域发挥重要作用。
2025-04-05 15:38:52
95
彩虹之上
转载文章
...引用还是未引用。实际应用中JVM在垃圾回收的时候需要更多的状态,如果增加至一个字节来描述状态,则位图需要256KB的空间,这个数字太大,开销占了25%。所以一个可能的做法位图不再描述一个字,而是一个区域,JVM选择512字节为单位,即用一个字节描述512字节的引用关系。选择一个区域除了空间利用率的问题之外,实际上还有现实的意义。我们知道Java对象实际上不是一个字能描述的(有一个参数可以控制对象最小对齐的大小,默认是8字节,实际上Java在JVM中还有一些附加信息,所以对齐后最小的Java对象是16字节),很多Java对象可能是几十个字节或者几百个字节,所以用一个字节描述一个区域是有意义的。但是我没有找到512的来源,为什么512效果最好?没有相应的数据来支持这个数字,而且这个值不可以配置,不能修改,但是有理由相信512字节的区域是为了节约内存额外开销。按照这个值,1MB的内存只需要2KB的额外空间就能描述引用关系。这又带来另一个问题,就是512字节里面的内存可能被引用多次,所以这是一个粗略的关系描述,那么在使用的时候需要遍历这512字节。 再举一个例子,假设有两个对象B、C都在这512字节的区域内。为了方便处理,记录对象引用关系的时候,都使用对象的起始位置,然后用这个地址和512对齐,因此B和C对象的卡表指针都指向这一个卡表的位置。那么对于引用处理也有可有两种处理方法:·处理的时候会以堆分区为处理单位,遍历整个堆分区,在遍历的时候,每次都会以对象大小为步长,结合卡表,如果该卡表中对应的位置被设置,则说明对象和其他分区的对象发生了引用。具体内容在后文中介绍Refine的时候还会详细介绍。·处理的时候借助于额外的数据结构,找到真正对象的位置,而不需要从头开始遍历。在后文的并发标记处理时就使用了这种方法,用于找到第一个对象的起始位置。在G1除了512字节粒度的卡表之外,还有bitMap,例如使用bitMap可以描述一个分区对另外一个分区的引用情况。在JVM中bitMap使用非常多,例如还可以描述内存的分配情况。 在G1除了512字节粒度的卡表之外,还有bitMap,例如使用bitMap可以描述一个分区对另外一个分区的引用情况。在JVM中bitMap使用非常多,例如还可以描述内存的分配情况。G1在混合收集算法中用到了并发标记。在并发标记的时候使用了bitMap来描述对象的分配情况。例如1MB的分区可以用16KB(16KB×ObjectAlignmentInBytes×8=1MB)来描述,即16KB额外的空间。其中ObjectAlignmentInBytes是8字节,指的是对象对齐,第二个8是指一个字节有8位。即每一个位可以描述64位。例如一个对象长度对齐之后为24字节,理论上它占用3个位来描述这个24字节已被使用了,实际上并不需要,在标记的时候只需要标记这3个位中的第一个位,再结合堆分区对象的大小信息就能准确找出。其最主要的目的是为了效率,标记一个位和标记3个位相比能节约不少时间,如果对象很大,则更划算。这些都是源码的实现细节,大家在阅读源码时需要细细斟酌。 本篇文章为转载内容。原文链接:https://blog.csdn.net/qq_16500963/article/details/132133125。 该文由互联网用户投稿提供,文中观点代表作者本人意见,并不代表本站的立场。 作为信息平台,本站仅提供文章转载服务,并不拥有其所有权,也不对文章内容的真实性、准确性和合法性承担责任。 如发现本文存在侵权、违法、违规或事实不符的情况,请及时联系我们,我们将第一时间进行核实并删除相应内容。
2023-12-16 20:37:50
246
转载
转载文章
...与J2EE与J2SE应用程序相结合也可以单独使用。Quartz可以用来创建简单或为运行十个,百个,甚至是好几万个Jobs这样复杂的程序。Jobs可以做成标准的Java组件或 EJBs。Quartz 是个开源的作业调度框架,为在 Java 应用程序中进行作业调度提供了简单却强大的机制。Quartz 允许开发人员根据时间间隔(或天)来调度作业。它实现了作业和触发器的多对多关系,还能把多个作业与不同的触发器关联。整合了 Quartz 的应用程序可以重用来自不同事件的作业,还可以为一个事件组合多个作业。虽然可以通过属性文件(在属性文件中可以指定 JDBC 事务的数据源、全局作业和/或触发器侦听器、插件、线程池,以及更多)配置 Quartz,但它根本没有与应用程序服务器的上下文或引用集成在一起。结果就是作业不能访问 Web 服务器的内部函数;例如,在使用 WebSphere 应用服务器时,由 Quartz 调度的作业并不能影响服务器的动态缓存和数据源。 二、java中实现定时任务分类 从实现的技术上来分类,目前主要有三种技术(或者说有三种产品): Java自带的java.util.Timer类,这个类允许你调度一个java.util.TimerTask任务。使用这种方式可以让你的程序按照某一个频度执行,但不能在指定时间运行。一般用的较少,这篇文章将不做详细介绍。 使用Quartz,这是一个功能比较强大的的调度器,可以让你的程序在指定时间执行,也可以按照某一个频度执行,配置起来稍显复杂,稍后会详细介绍。 Spring3.0以后自带的task,可以将它看成一个轻量级的Quartz,而且使用起来比Quartz简单许多,稍后会介绍。 从作业类的继承方式来讲,可以分为两类: 作业类需要继承自特定的作业类基类,如Quartz中需要继承自org.springframework.scheduling.quartz.QuartzJobBean;java.util.Timer中需要继承自java.util.TimerTask。 作业类即普通的java类,不需要继承自任何基类。 注:个人推荐使用第二种方式,因为这样所以的类都是普通类,不需要事先区别对待。 从任务调度的触发时机来分,这里主要是针对作业使用的触发器,主要有以下两种: 每隔指定时间则触发一次,在Quartz中对应的触发器为:org.springframework.scheduling.quartz.SimpleTriggerBean 每到指定时间则触发一次,在Quartz中对应的调度器为:org.springframework.scheduling.quartz.CronTriggerBean 注:并非每种任务都可以使用这两种触发器,如java.util.TimerTask任务就只能使用第一种。Quartz和spring task都可以支持这两种触发条件。 三、Quartz与Spring的集成 第一种,作业类继承自特定的基类:org.springframework.scheduling.quartz.QuartzJobBean。 第一步:定义作业类 Java代码 import org.quartz.JobExecutionContext; import org.quartz.JobExecutionException; import org.springframework.scheduling.quartz.QuartzJobBean; public class Job1 extends QuartzJobBean { private int timeout; private static int i = 0; //调度工厂实例化后,经过timeout时间开始执行调度 public void setTimeout(int timeout) { this.timeout = timeout; } / 要调度的具体任务 / @Override protected void executeInternal(JobExecutionContext context) throws JobExecutionException { System.out.println("定时任务执行中…"); } } 第二步:spring配置文件中配置作业类JobDetailBean Xml代码 <bean name="job1" class="org.springframework.scheduling.quartz.JobDetailBean"> <property name="jobClass" value="com.gy.Job1" /> <property name="jobDataAsMap"> <map> <entry key="timeout" value="0" /> </map> </property> </bean> 说明:org.springframework.scheduling.quartz.JobDetailBean有两个属性,jobClass属性即我们在java代码中定义的任务类,jobDataAsMap属性即该任务类中需要注入的属性值。 第三步:配置作业调度的触发方式(触发器) Quartz的作业触发器有两种,分别是 org.springframework.scheduling.quartz.SimpleTriggerBean org.springframework.scheduling.quartz.CronTriggerBean 第一种SimpleTriggerBean,只支持按照一定频度调用任务,如每隔30分钟运行一次。 配置方式如下: Xml代码 <bean id="simpleTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerBean"> <property name="jobDetail" ref="job1" /> <property name="startDelay" value="0" /><!-- 调度工厂实例化后,经过0秒开始执行调度 --> <property name="repeatInterval" value="2000" /><!-- 每2秒调度一次 --> </bean> 第二种CronTriggerBean,支持到指定时间运行一次,如每天12:00运行一次等。 配置方式如下: Xml代码 <bean id="cronTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean"> <property name="jobDetail" ref="job1" /> <!—每天12:00运行一次 --> <property name="cronExpression" value="0 0 12 ?" /> </bean> 关于cronExpression表达式的语法参见附录。 第四步:配置调度工厂 Xml代码 <bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean"> <property name="triggers"> <list> <ref bean="cronTrigger" /> </list> </property> </bean> 说明:该参数指定的就是之前配置的触发器的名字。 第五步:启动你的应用即可,即将工程部署至tomcat或其他容器。 第二种,作业类不继承特定基类。 Spring能够支持这种方式,归功于两个类: org.springframework.scheduling.timer.MethodInvokingTimerTaskFactoryBean org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean 这两个类分别对应spring支持的两种实现任务调度的方式,即前文提到到java自带的timer task方式和Quartz方式。这里我只写MethodInvokingJobDetailFactoryBean的用法,使用该类的好处是,我们的任务类不再需要继承自任何类,而是普通的pojo。 第一步:编写任务类 Java代码 public class Job2 { public void doJob2() { System.out.println("不继承QuartzJobBean方式-调度进行中..."); } } 可以看出,这就是一个普通的类,并且有一个方法。 第二步:配置作业类 Xml代码 <bean id="job2" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean"> <property name="targetObject"> <bean class="com.gy.Job2" /> </property> <property name="targetMethod" value="doJob2" /> <property name="concurrent" value="false" /><!-- 作业不并发调度 --> </bean> 说明:这一步是关键步骤,声明一个MethodInvokingJobDetailFactoryBean,有两个关键属性:targetObject指定任务类,targetMethod指定运行的方法。往下的步骤就与方法一相同了,为了完整,同样贴出。 第三步:配置作业调度的触发方式(触发器) Quartz的作业触发器有两种,分别是 org.springframework.scheduling.quartz.SimpleTriggerBean org.springframework.scheduling.quartz.CronTriggerBean 第一种SimpleTriggerBean,只支持按照一定频度调用任务,如每隔30分钟运行一次。 配置方式如下: Xml代码 <bean id="simpleTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerBean"> <property name="jobDetail" ref="job2" /> <property name="startDelay" value="0" /><!-- 调度工厂实例化后,经过0秒开始执行调度 --> <property name="repeatInterval" value="2000" /><!-- 每2秒调度一次 --> </bean> 第二种CronTriggerBean,支持到指定时间运行一次,如每天12:00运行一次等。 配置方式如下: Xml代码 <bean id="cronTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean"> <property name="jobDetail" ref="job2" /> <!—每天12:00运行一次 --> <property name="cronExpression" value="0 0 12 ?" /> </bean> 以上两种调度方式根据实际情况,任选一种即可。 第四步:配置调度工厂 Xml代码 <bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean"> <property name="triggers"> <list> <ref bean="cronTrigger" /> </list> </property> </bean> 说明:该参数指定的就是之前配置的触发器的名字。 第五步:启动你的应用即可,即将工程部署至tomcat或其他容器。 到此,spring中Quartz的基本配置就介绍完了,当然了,使用之前,要导入相应的spring的包与Quartz的包,这些就不消多说了。 其实可以看出Quartz的配置看上去还是挺复杂的,没有办法,因为Quartz其实是个重量级的工具,如果我们只是想简单的执行几个简单的定时任务,有没有更简单的工具,有! 四、Spring-Task 上节介绍了在Spring 中使用Quartz,本文介绍Spring3.0以后自主开发的定时任务工具,spring task,可以将它比作一个轻量级的Quartz,而且使用起来很简单,除spring相关的包外不需要额外的包,而且支持注解和配置文件两种 形式,下面将分别介绍这两种方式。 第一种:配置文件方式 第一步:编写作业类 即普通的pojo,如下: Java代码 import org.springframework.stereotype.Service; @Service public class TaskJob { public void job1() { System.out.println(“任务进行中。。。”); } } 第二步:在spring配置文件头中添加命名空间及描述 Xml代码 <beans xmlns="http://www.springframework.org/schema/beans" xmlns:task="http://www.springframework.org/schema/task" 。。。。。。 xsi:schemaLocation="http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.0.xsd"> 第三步:spring配置文件中设置具体的任务 Xml代码 <task:scheduled-tasks> <task:scheduled ref="taskJob" method="job1" cron="0 ?"/> </task:scheduled-tasks> <context:component-scan base-package=" com.gy.mytask " /> 说明:ref参数指定的即任务类,method指定的即需要运行的方法,cron及cronExpression表达式,具体写法这里不介绍了,详情见上篇文章附录。 <context:component-scan base-package="com.gy.mytask" />这个配置不消多说了,spring扫描注解用的。 到这里配置就完成了,是不是很简单。 第二种:使用注解形式 也许我们不想每写一个任务类还要在xml文件中配置下,我们可以使用注解@Scheduled,我们看看源文件中该注解的定义: Java代码 @Target({java.lang.annotation.ElementType.METHOD, java.lang.annotation.ElementType.ANNOTATION_TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface Scheduled { public abstract String cron(); public abstract long fixedDelay(); public abstract long fixedRate(); } 可以看出该注解有三个方法或者叫参数,分别表示的意思是: cron:指定cron表达式 fixedDelay:官方文档解释:An interval-based trigger where the interval is measured from the completion time of the previous task. The time unit value is measured in milliseconds.即表示从上一个任务完成开始到下一个任务开始的间隔,单位是毫秒。 fixedRate:官方文档解释:An interval-based trigger where the interval is measured from the start time of the previous task. The time unit value is measured in milliseconds.即从上一个任务开始到下一个任务开始的间隔,单位是毫秒。 下面我来配置一下。 第一步:编写pojo Java代码 import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; @Component(“taskJob”) public class TaskJob { @Scheduled(cron = "0 0 3 ?") public void job1() { System.out.println(“任务进行中。。。”); } } 第二步:添加task相关的配置: Xml代码 <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:task="http://www.springframework.org/schema/task" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/jdbc/spring-jdbc-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.0.xsd" default-lazy-init="false"> <context:annotation-config /> <!—spring扫描注解的配置 --> <context:component-scan base-package="com.gy.mytask" /> <!—开启这个配置,spring才能识别@Scheduled注解 --> <task:annotation-driven scheduler="qbScheduler" mode="proxy"/> <task:scheduler id="qbScheduler" pool-size="10"/> 说明:理论上只需要加上<task:annotation-driven />这句配置就可以了,这些参数都不是必须的。 Ok配置完毕,当然spring task还有很多参数,我就不一一解释了,具体参考xsd文档http://www.springframework.org/schema/task/spring-task-3.0.xsd。 附录: cronExpression的配置说明,具体使用以及参数请百度google 字段 允许值 允许的特殊字符 秒 0-59 , - / 分 0-59 , - / 小时 0-23 , - / 日期 1-31 , - ? / L W C 月份 1-12 或者 JAN-DEC , - / 星期 1-7 或者 SUN-SAT , - ? / L C 年(可选) 留空, 1970-2099 , - / - 区间 通配符 ? 你不想设置那个字段 下面只例出几个式子 CRON表达式 含义 "0 0 12 ?" 每天中午十二点触发 "0 15 10 ? " 每天早上10:15触发 "0 15 10 ?" 每天早上10:15触发 "0 15 10 ? " 每天早上10:15触发 "0 15 10 ? 2005" 2005年的每天早上10:15触发 "0 14 ?" 每天从下午2点开始到2点59分每分钟一次触发 "0 0/5 14 ?" 每天从下午2点开始到2:55分结束每5分钟一次触发 "0 0/5 14,18 ?" 每天的下午2点至2:55和6点至6点55分两个时间段内每5分钟一次触发 "0 0-5 14 ?" 每天14:00至14:05每分钟一次触发 "0 10,44 14 ? 3 WED" 三月的每周三的14:10和14:44触发 "0 15 10 ? MON-FRI" 每个周一、周二、周三、周四、周五的10:15触发 Cron 表达式包括以下 7 个字段: 秒 分 小时 月内日期 月 周内日期 年(可选字段) 特殊字符 Cron 触发器利用一系列特殊字符,如下所示: 反斜线(/)字符表示增量值。例如,在秒字段中“5/15”代表从第 5 秒开始,每 15 秒一次。 问号(?)字符和字母 L 字符只有在月内日期和周内日期字段中可用。问号表示这个字段不包含具体值。所以,如果指定月内日期,可以在周内日期字段中插入“?”,表示周内日期值无关紧要。字母 L 字符是 last 的缩写。放在月内日期字段中,表示安排在当月最后一天执行。在周内日期字段中,如果“L”单独存在,就等于“7”,否则代表当月内周内日期的最后一个实例。所以“0L”表示安排在当月的最后一个星期日执行。 在月内日期字段中的字母(W)字符把执行安排在最靠近指定值的工作日。把“1W”放在月内日期字段中,表示把执行安排在当月的第一个工作日内。 井号()字符为给定月份指定具体的工作日实例。把“MON2”放在周内日期字段中,表示把任务安排在当月的第二个星期一。 星号()字符是通配字符,表示该字段可以接受任何可能的值。 字段 允许值 允许的特殊字符 秒 0-59 , - / 分 0-59 , - / 小时 0-23 , - / 日期 1-31 , - ? / L W C 月份 1-12 或者 JAN-DEC , - / 星期 1-7 或者 SUN-SAT , - ? / L C 年(可选) 留空, 1970-2099 , - / 表达式意义 "0 0 12 ?" 每天中午12点触发 "0 15 10 ? " 每天上午10:15触发 "0 15 10 ?" 每天上午10:15触发 "0 15 10 ? " 每天上午10:15触发 "0 15 10 ? 2005" 2005年的每天上午10:15触发 "0 14 ?" 在每天下午2点到下午2:59期间的每1分钟触发 "0 0/5 14 ?" 在每天下午2点到下午2:55期间的每5分钟触发 "0 0/5 14,18 ?" 在每天下午2点到2:55期间和下午6点到6:55期间的每5分钟触发 "0 0-5 14 ?" 在每天下午2点到下午2:05期间的每1分钟触发 "0 10,44 14 ? 3 WED" 每年三月的星期三的下午2:10和2:44触发 "0 15 10 ? MON-FRI" 周一至周五的上午10:15触发 "0 15 10 15 ?" 每月15日上午10:15触发 "0 15 10 L ?" 每月最后一日的上午10:15触发 "0 15 10 ? 6L" 每月的最后一个星期五上午10:15触发 "0 15 10 ? 6L 2002-2005" 2002年至2005年的每月的最后一个星期五上午10:15触发 "0 15 10 ? 63" 每月的第三个星期五上午10:15触发 每天早上6点 0 6 每两个小时 0 /2 晚上11点到早上8点之间每两个小时,早上八点 0 23-7/2,8 每个月的4号和每个礼拜的礼拜一到礼拜三的早上11点 0 11 4 1-3 1月1日早上4点 0 4 1 1 本篇文章为转载内容。原文链接:https://zhanghaiyang.blog.csdn.net/article/details/51397459。 该文由互联网用户投稿提供,文中观点代表作者本人意见,并不代表本站的立场。 作为信息平台,本站仅提供文章转载服务,并不拥有其所有权,也不对文章内容的真实性、准确性和合法性承担责任。 如发现本文存在侵权、违法、违规或事实不符的情况,请及时联系我们,我们将第一时间进行核实并删除相应内容。
2023-10-27 18:50:19
344
转载
转载文章
...大机制在实际开发中的应用。近期,随着Python 3.10版本的发布,官方对一些特殊方法进行了优化和新增,例如__match__方法用于支持模式匹配语法,使得代码更加简洁易读。此外,在数据科学领域,NumPy库通过自定义特殊方法实现了与Python内置类型无缝衔接的高性能数组运算,如__array_ufunc__方法允许用户控制NumPy如何处理用户自定义的数据类型。 而在软件工程实践中,特殊方法更是无处不在。比如Django框架内Model类的设计就大量运用了特殊方法,如__str__用于模型对象的字符串表示,__getattr__、__setattr__等用于属性管理,以及save()方法背后的__init__、__new__等构造逻辑。这些都充分体现了Python特殊方法在构建复杂系统时的重要性。 不仅如此,对于面向对象设计原则的理解,诸如封装、多态和继承,也能够在特殊方法的使用上得到生动体现。以重载比较操作符为例,通过实现__eq__、__lt__等方法,开发者能够根据业务需求为自定义类赋予灵活而精准的比较逻辑,从而实现更符合领域特性的行为表现。 总之,Python特殊方法不仅提供了丰富的扩展能力,还在不同场景下展现了其强大的灵活性和实用性。无论是跟进最新的Python语言特性更新,还是深入研究经典开源项目源码,或是解决实际编程问题,理解并熟练运用特殊方法都是提升Python编程水平的关键所在。
2023-04-19 14:30:42
132
转载
转载文章
...Java注解功能及其应用后,我们可以看到这一特性在现代软件开发中发挥着重要作用。事实上,注解不仅被广泛应用于Android开发,如Butter Knife这样的库,也在Java企业级开发、Spring框架等领域有着不可或缺的地位。例如,Spring通过注解驱动的编程模型(Annotation-based programming model),开发者可以便捷地实现依赖注入、事务管理等功能。 近期,随着JDK17的发布,Java社区对注解的关注度进一步提升。在新版本中,尽管注解的基本使用方式没有变化,但对模块化系统(JPMS)的支持使得注解在模块间的交互和权限控制上有了新的应用场景。同时,社区也在探索更高效的注解处理机制,以减少反射带来的性能开销,例如Project Lombok项目就尝试通过注解处理器自动生成代码,从而避免运行时反射。 此外,Google在今年初宣布了Jetpack Compose的稳定版,这是一种声明式UI构建工具,同样大量运用了注解技术来简化界面组件的创建与维护。这意味着注解在Android领域的应用将进一步深化,帮助开发者提高生产力并优化代码结构。 综上所述,无论是在传统的Java SE领域还是在新兴的Android开发中,注解的重要性都在不断提升,并且随着技术的发展,注解的应用场景将会更加丰富多元,成为现代编程语言不可忽视的关键特性之一。对于开发者来说,持续关注注解相关的最新研究进展和技术实践,将有助于提高自身编码效率和程序设计质量。
2023-03-28 22:30:35
104
转载
转载文章
...,对大部分表比较少的应用备份开销也小到几乎可以忽略, 成功恢复后能还原损坏时最新的数据,不受备份时限影响。 坏处是,和Dump一样,如果损坏到表的中间部分,比如非叶子节点,将导致后续数据无法读出。 落地实践: 剥离封装RepairKit: 从WCDB框架中,剥离修复组件,并且封装其C++的原始API为OC管理类。 备份 master 表的时机: 我们发现 SQLite 里面 B+树 算法的实现是 向下分裂 的,也就是说当一个叶子页满了需要分裂时,原来的叶子页会成为内部节点,然后新申请两个页作为他的叶子页。这就保证了根节点一旦下来,是再也不会变动的。master 表只会在新创建表或者删除一个表时才会发生变化,而CoreData的机制表明每一次数据库的变动都要改动版本标识,那么我通过缓存和查询版本标识的变动来确定何时进行备份,避免频繁备份。 备份文件有效性: 既然 DB 可以损坏,那么这个备份文件也会损坏,怎么办呢?我用了双备份,每一个版本备份两个文件,如果一个备份恢复失败,就会启动另一个备份文件恢复。 介入恢复时机: 当CoreData初始化SQLite前,校验SQLite的Head完整性,如果不完整,进行介入修复。 经过我深入研究证明了这已经是最佳做法。 本篇文章为转载内容。原文链接:https://blog.csdn.net/a66666225/article/details/81637368。 该文由互联网用户投稿提供,文中观点代表作者本人意见,并不代表本站的立场。 作为信息平台,本站仅提供文章转载服务,并不拥有其所有权,也不对文章内容的真实性、准确性和合法性承担责任。 如发现本文存在侵权、违法、违规或事实不符的情况,请及时联系我们,我们将第一时间进行核实并删除相应内容。
2023-11-23 18:22:40
127
转载
转载文章
...oovy为基础的桌面应用框架)等新兴框架,它们为开发者提供了更简洁直观的API和强大的功能集。 3. 跨平台UI工具包Qt Jambi:尽管Java Swing是纯Java环境下的GUI解决方案,但也有其他跨平台工具包值得关注,例如Qt Jambi,它允许开发者使用Java编写原生速度和外观的应用程序,并兼容多种操作系统。 4. 无障碍性设计原则在Swing中的应用:针对日益增长的无障碍需求,开发者应了解并遵循WCAG标准,在Swing应用程序中实施无障碍设计,如提供键盘导航支持、可调整的文字大小及高对比度模式等。 5. Swing组件最佳实践分享:查阅最新的开发者博客和论坛讨论,可以发现众多关于如何优化Swing组件性能、处理并发问题以及改善用户体验的实际案例和建议,这些都能帮助你更好地运用Swing进行复杂GUI的设计与实现。 综上所述,不断跟进最新的GUI开发趋势和技术发展,结合实际项目需求,灵活运用和扩展Swing或其他相关框架,将有助于打造更为出色和易用的桌面应用程序。
2023-01-18 08:36:23
525
转载
转载文章
...ml 关于软件工程和应用开发领域的各种免费的实践知识、时事信息和资料文件下载,包括了测试方面的内容 http://www.mtsu.ceu/-storm/ 软件测试在线资源,包括提供目前有哪些人在研究测试,测试工具列表连接,测试会议,测试新闻和讨论,软件测试文学(包括各种测试杂志,测试报告),各种测试研究组织等内容 http://www.psqtcomference.com/ 实用软件质量技术和实用软件测试技术国际学术会议宣传网站,每年都会举行两次 http://www.qacity.com/front.htm 测试工程师资源网站,包含各种测试技术及相关资料下载 http://www.qaforums.com/ 关于软件质量保证方面的一个论坛,需要注册 http://www.qaiusa.com/ QAI是一个提供质量保证方面咨询的国际著名机构,提供各种质量和测试方面证书认证 http://www.qualitytree.com/ 一个测试咨询提供商,有一些测试可供下载,有几篇关于缺陷管理方面的文章值得参考 http://www.rational.com/ IBM Rational的官方网站,可以在这里寻找测试方面的工具信息。IBM Rational提供测试方面一系列的工具,比较全面 http://rexblackconsulting.com/Pages/publicat-ions.htm Rex Black的个人主页,有一些测试和测试管理方面的资料可供下载 http://www.riceconsulting.com/ 一个测试咨询提供商,有一些测试资料可供下载,但不多 http://www.satisfice.com/ 包含James Bach关于软件测试和过程方面的很多论文,尤其在启发式测试策略方面值得参考 http://www.satisfice.com/seminars.shtml 一个黑盒软件测试方面的研讨会,主要由测试专家Cem Kanar和James Bach组织,有一些值得下载的资料 http://www.sdmagazine.com/ 软件开发杂志,经常会有一些关于测试方面好的论文资料,同时还包括了项目和过程改进方面的课题,并且定期会有一些关于质量和测试方面的问题讨论 http://www.sei.cmu.edu/ 著名的软件工程组织,承担美国国防部众多软件工程研究项目,在这里你可以获俄各类关于工程质量和测试方面的资料。该网站提供强有力的搜索功能,可以快速检索到你想要的论文资料,并且可以免费下载 http://www.soft.com/Institute/HotList/ 提供了网上软件质量热点连接,包括:专业团体组织连接、教育机构连接、商业咨询公司连接、质量相关技术会议连接、各类测试技术专题连接等 http://www.soft.com/News/QTN-Online/ 质量技术时事,提供有关测试质量方面的一些时事介绍信息,对于关心测试和质量发展的人士来说是很有价值的 http://www.softwaredioxide.com/ 包括软件工程(CMM,CMMI,项目管理)软件测试等方面的资源 http://www.softwareqatest.com/ 软件质量/测试资源中心。该中心提供了常见的有关测试方面的FAQ资料,各质量/测试网站介绍,各质量/测试工具介绍,各质量/策划书籍介绍以及与测试相关的工作网站介绍 http://www.softwaretestinginstitute.com 一个软件测试机构,提供软件质量/测试方面的调查分析,测试计划模板,测试WWW的技术,如何获得测试证书的指导,测试方面书籍介绍,并且提供了一个测试论坛 http://www.sqatester.com/index.htm 一个包含各种测试和质量保证方面的技术网站,提供咨询和培训服务,并有一些测试人员社团组织,特色内容是缺陷处理方面的技术 http://www.sqe.com/ 一个软件质量工程服务性网站,组织软件测试自动化、STAR-EASE、STARWEST等方面的测试学术会议,并提供一些相关信息资料和课程服务 http://www.stickyminds.com/ 提供关于软件测试和质量保证方面的当前发展信息资料,论文等资源 http://www.stqemagazine.com/ 软件策划和质量工程杂志,经常有一些好的论文供下载,不过数量较少,更多地需要通过订购获得,内容还是很有价值的 http://www.tantara.ab.ca/ 软件质量方面的一个咨询网站,有过程改进方面的一些资料提供 http://www.tcse.org/ IEEE的一个软件工程技术委员会,提供技术论文下载,并有一个功能强大的分类下载搜索功能,可以搜索到测试类型、测试管理、 测试分析等各方面资料 http://www.testing.com/ 测试技术专家Brain Marick的主页,包含了Marick 研究的一些资料和论文,该网页提供了测试模式方面的资料,值得研究。总之,如果对测试实践感兴趣,该网站一定不能错过 http://www.testingcenter.com/ 有一些测试方面的课程体系,有一些价值 http://www.testingconferences.com/asiastar/home 著名的AsiaStar测试国际学术会议官方网站,感兴趣的人一定不能错过 http://www.testingstuff.com/ Kerry Zallar的个人主页,提供一些有关培训、工具、会议、论文方面的参考信息 http://www-sqi.cit.gu.edu.au/ 软件质量机构,有一些技术资料可以供下载,包括软件产品质量模型、再工程、软件质量改进等 这里有些网站已经不能使用了. 转载于:https://www.cnblogs.com/mmsky/p/4581975.html 本篇文章为转载内容。原文链接:https://blog.csdn.net/aizongzhuang2281/article/details/101129638。 该文由互联网用户投稿提供,文中观点代表作者本人意见,并不代表本站的立场。 作为信息平台,本站仅提供文章转载服务,并不拥有其所有权,也不对文章内容的真实性、准确性和合法性承担责任。 如发现本文存在侵权、违法、违规或事实不符的情况,请及时联系我们,我们将第一时间进行核实并删除相应内容。
2023-08-29 09:17:46
134
转载
转载文章
...规模高性能、高并发的网络架构经验分享 互联网技术(java框架、分布式、集群)干货视频大全,不看后悔!(免费下载) 本文转自:公众号老板思维与智库(ID:laobanzhiku88),欢迎大家关注 笔者搬家前有个邻居,两口子典型的中年夫妻。 时不时由着一些鸡毛蒜皮的小事突然爆发争吵,但为了孩子老人和自己的颜面又要在人前假装和睦。 吵架的内容无非几样,孩子学业、老人赡养... 以及,丈夫人到中年,却还只是个普普通通的员工,业绩上不高不低,不至于垫底,也不足以升迁,家庭经济压力不小。 老话说,贫贱夫妻百事衰,一点没错。 一生压力最大的时期无非上有老下有小的中年。 事业上年纪已经失去了竞争力,脑力体力精力都比不过后来的年轻人。 无数的争吵、矛盾、压力,说明白点,大都来自于经济上的缺乏。 这样的家庭在中国并不少见。 扪心自问,兢兢业业十几年,没有功劳也有苦劳,为什么现在还只是个普通员工? 甚至比自己晚入行几年的新人都早早升迁小有成就了。 无目标无计划 大部分到了中年仍旧一事无成的人多在年轻时对自己的人生没有长远的规划。 年纪轻轻就失去梦想,只想当咸鱼。 做一天和尚撞一天钟,不知不觉,最适合奋斗的那几年都在这种平淡中弹指一挥间,回过神来人已经不惑之年。 普通员工不可怕,可怕的是你是个没有自己“小目标”的普通员工。 过度满足于现状只会增加你的职场生存隐患,很可能老板没有开除你单单念在你勤恳付出多年的三分情面上。 但是仅仅不犯过错不应该成为工作的准则。 都说学如逆水行舟,只要处在不断前进的社会里,人就要努力向前,才不至于被抛在人后。 原地停留,不过是变相的倒退罢了。 无论青年还是中年,当着手当下,给自己定下前行的目标,不断寻求突破与进展。 人要做的,是永远比昨天的自己更优秀。 实际行动力差 笔者接触到的中年人,大部分实际行动力都不强。 说起人生道理、励志格言他们如数家珍,一说一箩筐,分分钟能登台做演讲。 但真真切切落实到实际行动里,完全又是另外一回事。 具体到某一件事的时候,他们会有各种各样的理由来拒绝改变和行动。 好似他们的境况永远特殊,永远比别人更加糟糕,旁人永远难以体会。 常听朋友抱怨起他的父亲,说父亲年轻时喜欢钓鱼,偶尔也会在周末带他出去垂钓。 这本是极好的一项爱好,修身养性还能给餐桌添些鲜味。 但随着他的长大,父亲步入中年,钓鱼这项活动就只存在于父亲和外人的谈天说地里。 当他邀请父亲一同出门垂钓的时候,总是被各种理由拒绝。 那可能是伯父真的有重要的事情要做嘛,笔者笑道。 朋友无奈直摇头,他给我的理由无非几样。 要么是嫌钓鱼地方不好,找到了好地方又嫌路途远,两者都不错的又说天气不适合,林林总总说起来无非就三个字,不想动。 一件自己喜欢的事都不愿意花时间去享受,更不用说繁琐的工作了。 再高的思想觉悟、再充分的理论知识,没有实战,终究不过是纸上谈兵,虚吹一场,没有任何实际效用。 脚踏实地,踏踏实实做实事,才可能有收获。 不懂得投资自己 股神巴菲特在《福布斯》杂志的采访中说道,有一种投资好过其他所有的投资,那就是投资自己。 没有人能夺走你自身学到的东西,每个人都有这样的投资潜力。 无论处在什么阶段,保持学习都是十分重要的一件事。 工作的十几年间,为什么别人都升职了自己却留在原地? 常常会疑惑,刚进公司的时候也是优秀的潜力股一枚,升职的时候老板怎么就看不见我? 很简单,因为潜力股要经过挖掘投资才能成为优质股。 人就像一方活水,有源源不断的补给才能保持自身不干涸,才能掀得起浪花。 不断增加自己的学识、磨练出过硬的技能,在职场中你的综合考察才会不断加分! 不懂的投资自己,提升能力,只会让你被淘汰的更快。 心态老得比身体快 明明还是个中年人,精神面貌看着还不如小区里跳广场舞的大妈大爷们。 整个人的心态衰老程度已经远远超过身体的衰老程度。 从内里散发出消极颓废的负能量。 试想谁会把重要的工作交给一个丧气满满的人呢? 职场上的中年人在做事的时候难免受家庭、他人眼光、年龄的牵绊,畏手畏脚,瞻前顾后。 他们总在想,我这样做,会显得自己过于出彩,会畏惧别人“一把年纪还想出风头”的闲言碎语和轻信别人“老了老了,都是年轻人的天下”的衰言败语。 妈妈常教导我,让我养成良好习惯。这样长大才能成为一个有用的人。良好的习惯是尊敬师长这样长大才能成为一个有用的人。良好的习惯是尊敬师长,爱护同学,对人有礼貌;是不粗心,做事情不拖拉;还是爱护公物,不浪费粮食。为什么呢?因为拥有良好习惯,做一个品德高尚的人,懂得尊重别人,才会得到别人的尊重。我要努力地做到这些。我有一些坏习惯,有时候学习很粗心,把一些会做的题做错。在生活上,也很粗心,有一次早上起床居然穿反了衣服。我吃饭很慢,有的时候还剩饭。我还起床磨蹭,本来应该迅速地穿好衣服,但是,我总是磨磨蹭蹭地,速度很慢。“我打算在这学期里,改掉这些坏习惯。早上起来,迅速地穿好衣服,不拖拉。学习不粗心,仔细完成每一道题。吃饭的时候,要很快的把饭吃完,不剩饭。我要从一点一滴做起,逐渐养成良好习惯。我相信自己一定能成为一名品学兼优的好学生!我打算在这学期里,改掉这些坏习惯。早上起来,迅速地穿好衣服,不拖拉。学习不粗心,仔细完成每一道题。吃饭的时候,要很快的把饭吃完,不剩饭。我要从一点一滴做起,逐渐养成良好习惯。我相信自己一定能成为一名品学兼优的好学生!” 在上幼儿园以前,我什么也不会干,就连穿衣服也是妈妈给我穿好,就要上幼儿园了,这样可不行,妈妈锻炼我要学会自己穿衣服。 有一天,妈妈把衣服摆在我面前,开始让我自己穿。一开始。我又哭又叫就是不穿,还把衣服扔的满地都是,然后坐在地上开始大哭,等了好长时间,妈妈还是不理我,我只好自己乖乖的把衣服穿好, 一出了房间门,妈妈就笑了起来,再看看我的衣服,毛衣和裤子都穿反了,我赶紧回房间又重新穿了一遍,这次穿好了,拿起外套,可是外套的扣子又扣不上了,扣子可调皮了,好像故意和我作对,我把扣子往扣眼——人类邪恶的根源;爱情——幸福和光明的源泉。我一直在这些思想的舞台上徘徊。突然我发现两个身影从我面前经过,坐在不远的草地上。这是一对从农田那边走过来的青年男女。农田那边有农民的茅舍。在一阵令人伤心的沉默之后,随着一声长叹,我听见从一个肺痨病人的嘴里说出了这样的话:幸福和光明的源泉。我一直在这些思想的舞台上徘徊。突然我发现两个身影从我面前经过,坐在不远的草地上。这是一对从农田那边走过来的青年男女。农田那边有农民的茅舍。在一阵令人伤心的沉默之后,随着一声长叹,我听见从一个肺痨病人的嘴里说出了这样的话幸福和光明的源泉。我一直在这些思想的舞台上徘徊。突然我发现两个身影从我面前经过,坐在不远的草地上。这是一对从农田那边走过来的青年男女。农田那边有农民的茅舍。在一阵令人伤心的沉默之后,随着一声长叹,我听见从一个肺痨病人的嘴里说出了这样的话幸福和光明的源泉。我一直在这些思想的舞台上徘徊。突然我发现两个身影从我面前经过,坐在不远的草地上。这是一对从农田那边走过来的青年男女。农田那边有农民的茅舍。在一阵令人伤心的沉默之后,随着一声长叹,我听见从一个肺痨病人的嘴里说出了这样的话幸福和光明的源泉。我一直在这些思想的舞台上徘徊。突然我发现两个身影从我面前经过,坐在不远的草地上。这是一对从农田那边走过来的青年男女。农田那边有农民的茅舍。在一阵令人伤心的沉默之后,随着一声长叹,我听见从一个肺痨病人的嘴里说出了这样的话幸福和光明的源泉。我一直在这些思想的舞台上徘徊。突然我发现两个身影从我面前经过,坐在不远的草地上。这是一对从农田那边走过来的青年男女。农田那边有农民的茅舍。在一阵令人伤心的沉默之后,随着一声长叹,我听见从一个肺痨病人的嘴里说出了这样的话幸福和光明的源泉。我一直在这些思想的舞台上徘徊。突然我发现两个身影从我面前经过,坐在不远的草地上。这是一对从农田那边走过来的青年男女。农田那边有农民的茅舍。在一阵令人伤心的沉默之后,随着一声长叹,我听见从一个肺痨病人的嘴里说出了这样的话幸福和光明的源泉。我一直在这些思想的舞台上徘徊。突然我发现两个身影从我面前经过,坐在不远的草地上。这是一对从农田那边走过来的青年男女。农田那边有农民的茅舍。在一阵令人伤心的沉默之后,随着一声长叹,我听见从一个肺痨病人的嘴里说出了这样的话幸福和光明的源泉。我一直在这些思想的舞台上徘徊。突然我发现两个身影从我面前经过,坐在不远的草地上。这是一对从农田那边走过来的青年男女。农田那边有农民的茅舍。在一阵令人伤心的沉默之后,随着一声长叹,我听见从一个肺痨病人的嘴里说出了这样的话“亲爱的!擦干你的眼泪,至高无上的爱情已经打开了我们的眼界,使我们成了它的崇拜者。是它, 妈妈常教导我,让我养成良好习惯。这样长大才能成为一个有用的人。良好的习惯是尊敬师长这样长大才能成为一个有用的人。良好的习惯是尊敬师长,爱护同学,对人有礼貌;是不粗心,做事情不拖拉;还是爱护公物,不浪费粮食。为什么呢?因为拥有良好习惯,做一个品德高尚的人,懂得尊重别人,才会得到别人的尊重。我要努力地做到这些。我有一些坏习惯,有时候学习很粗心,把一些会做的题做错。在生活上,也很粗心,有一次早上起床居然穿反了衣服。我吃饭很慢,有的时候还剩饭。我还起床磨蹭,本来应该迅速地穿好衣服,但是,我总是磨磨蹭蹭地,速度很慢。“我打算在这学期里,改掉这些坏习惯。早上起来,迅速地穿好衣服,不拖拉。学习不粗心,仔细完成每一道题。吃饭的时候,要很快的把饭吃完,不剩饭。我要从一点一滴做起,逐渐养成良好习惯。我相信自己一定能成为一名品学兼优的好学生!我打算在这学期里,改掉这些坏习惯。早上起来,迅速地穿好衣服,不拖拉。学习不粗心,仔细完成每一道题。吃饭的时候,要很快的把饭吃完,不剩饭。我要从一点一滴做起,逐渐养成良好习惯。我相信自己一定能成为一名品学兼优的好学生!” 在上幼儿园以前,我什么也不会干,就连穿衣服也是妈妈给我穿好,就要上幼儿园了,这样可不行,妈妈锻炼我要学会自己穿衣服。 有一天,妈妈把衣服摆在我面前,开始让我自己穿。一开始。我又哭又叫就是不穿,还把衣服扔的满地都是,然后坐在地上开始大哭,等了好长时间,妈妈还是不理我,我只好自己乖乖的把衣服穿好, 一出了房间门,妈妈就笑了起来,再看看我的衣服,毛衣和裤子都穿反了,我赶紧回房间又重新穿了一遍,这次穿好了,拿起外套,可是外套的扣子又扣不上了,扣子可调皮了,好像故意和我作对,我把扣子往扣眼——人类邪恶的根源;爱情——幸福和光明的源泉。我一直在这些思想的舞台上徘徊。突然我发现两个身影从我面前经过,坐在不远的草地上。这是一对从农田那边走过来的青年男女。农田那边有农民的茅舍。在一阵令人伤心的沉默之后,随着一声长叹,我听见从一个肺痨病人的嘴里说出了这样的话:“亲爱的!擦干你的眼泪,至高无上的爱情已经打开了我们的眼界,使我们成了它的崇拜者。是它, 每一个碌碌无为的中年人都改明白的一个道理是,职场所谓的新人老人,取决于你的成就,而不是入行时间。 入行十余年还不如别人入行三五年来的专业,所谓老人不过是虚谈。 只要一天还出成绩,对待工作就当保持一个新人该有的拼劲和争上游的心态,抛开顾虑,努力向前便是! -END- 声明:本文属于老板思维与智库(ID:laobanzhiku88),图片来源于网络 看完本文有收获?请转发分享给更多人 欢迎关注“互联网架构师”,我们分享最有价值的互联网技术干货文章,助力您成为有思想的全栈架构师,我们只聊互联网、只聊架构,不聊其他!打造最有价值的架构师圈子和社区。 本公众号覆盖中国主要首席架构师、高级架构师、CTO、技术总监、技术负责人等人 群。分享最有价值的架构思想和内容。打造中国互联网圈最有价值的架构师圈子。 长按下方的二维码可以快速关注我们 如想加群讨论学习,请点击右下角的“加群学习”菜单入群 本篇文章为转载内容。原文链接:https://blog.csdn.net/emprere/article/details/98859913。 该文由互联网用户投稿提供,文中观点代表作者本人意见,并不代表本站的立场。 作为信息平台,本站仅提供文章转载服务,并不拥有其所有权,也不对文章内容的真实性、准确性和合法性承担责任。 如发现本文存在侵权、违法、违规或事实不符的情况,请及时联系我们,我们将第一时间进行核实并删除相应内容。
2023-06-29 14:16:29
119
转载
转载文章
...Vue3的发布和广泛应用,开发者们对其生态建设的关注度与日俱增。近期,Vue3社区不断推出新的工具和库以适应更高效、规范化的开发需求。例如,Vite作为由Vue.js作者尤雨溪亲自操刀的新型构建工具,以其快速热更新、按需编译等特性深受开发者喜爱,配合TypeScript可以进一步提升项目代码质量及可维护性。 在UI组件库方面,Element-Plus作为Vue3生态的重要一环,持续迭代升级,提供更多丰富且易于使用的组件供开发者选择。与此同时,状态管理库Pinia也在Vue3的状态管理解决方案中崭露头角,其简洁易用的设计理念让状态管理更为灵活便捷。 在工程化配置上,Eslint和Prettier的组合已成为业界标准,保证代码风格一致性的同时提升了团队协作效率。此外,TailwindCSS这类实用的原子化CSS框架被更多项目采纳,简化了样式编写流程,尤其适合后台管理系统等复杂项目的样式设计。 至于测试环节,Jest凭借其强大的断言库和模拟功能,在单元测试领域占据主导地位。对于Vue3应用,Vue Test Utils提供了对Vue组件进行单元测试的强大支持,确保代码质量与稳定性。 综上所述,Vue3生态正在以前所未有的速度发展和完善,无论是核心框架还是周边工具链都在与时俱进,为开发者带来更加先进、高效的开发体验。建议读者关注官方文档、技术博客以及GitHub上的最新动态,紧跟社区步伐,不断提升自身的技能树,以应对未来日益复杂的前端开发挑战。
2023-10-05 12:27:41
116
转载
转载文章
... Direct3D®应用程序需要熟悉三维几何学原理。本节介绍创建三维场景所需的最重要的几何概念。本节涉及到以下主题。 三维坐标系 三维图元 表面和顶点法向 三角形光栅化法则 矩形 三角形插值 向量、顶点和四元数 这些主题给读者提供了一个对Direct3D应用程序所涉及到的基本概念的高层描述。更多有关这些主题的信息,请参阅更多的信息。 三维坐标系 通常三维图形应用程序使用两种笛卡尔坐标系:左手系和右手系。在这两种坐标系中,正x轴指向右面,正y轴指向上面。通过沿正x轴方向到正y轴方向握拳,大姆指的指向就是相应坐标系统的正z轴的指向。下图显示了这两种坐标系统。 Microsoft® Direct3D®使用左手坐标系。如果正在移植基于右手坐标系的应用程序,必须将传给Direct3D的数据做两点改变。 颠倒三角形顶点的顺序,这样系统会从正面以顺时针的方向遍历它们。换句话说,如果顶点是v0,v1,v2,那么以v0,v2,v1的顺序传给Direct3D。 用观察矩阵对世界空间中的z值取反。要做到这一点,将表示观察矩阵的D3DMATRIX结构的_31、_32、_33和_34成员的符号取反。 要得到等同于右手系的效果,可以使用D3DXMatrixPerspectiveRH和D3DXMatrixOrthoRH函数定义投影矩阵。但是,要小心使用D3DXMatrixLookAtRH函数,并相应地颠倒背面剔除的顺序及放置立方体贴图。 虽然左手坐标系和右手坐标系是最为常用的系统,但在三维软件中还使用许多其它坐标系。例如,对三维建模应用程序而言,使用y轴指向或背向观察者的坐标系统并非罕见。在这种情况下,任意轴(x,y或z)的正半轴指向观察者的被定义为右手系。任意轴(x,y或z)的正半轴背向观察者的被定义为左手系。如果正在移植一个基于左手系进行建模的应用程序,z轴向上,那么除了前面的步骤外,还必须旋转所有的顶点数据(译注:如果原来的坐标系为正x轴向里,正y轴向左,正z轴向上,那么传给Direct3D的顶点的x值对应原来的y值,y值对应原来的z值,z值对应原来的x值,亦即旋转顶点数据)。 对三维坐标系统中定义的三维物体执行的最基本操作是变换、旋转和缩放。可以合并这些基本变换以创建一个新的变换矩阵。细节请参阅三维变换。 即使合并相同的变换操作,不同的合并顺序得到的结果是不可交换的——矩阵相乘的顺序很重要。 三维图元 三维图元是组成单个三维实体的顶点集合。三维坐标系统中最简单的图元是点的集合,称为点表。 通常三维图元是多边形。一个多边形是由至少三个顶点描绘的三维形体。最简单的多边形是三角形。Microsoft® Direct3D®使用三角形组成大多数多边形,因为三角形的三个顶点一定是共面的。应用程序可以用三角形组合成大而复杂的多边形及网格(mesh)。 下图显示了一个立方体。立方体的每个面由两个三角形组成。整个三角形的集合构成了一个立方体图元。可以将纹理和材质应用于图元的表面使它们看起来像是实心的。 可以使用三角形创建具有光滑曲面的图元。下图显示了如何用三角形模拟一个球体。应用了材质后,渲染得到的球体看起来是弯曲的。如果使用高洛德着色,结果更是如此。更多信息请参阅高洛德着色。 表面和顶点法向量 网格中的每个面有一个垂直的法向量。该向量的方向由定义顶点的顺序及坐标系统是左手系还是右手系决定。表面法向量从表面上指向正向面那一侧,如果把表面水平放置,正向面朝上,背向面朝下,那么表面法向量为垂直于表面从下方指向上方。在Microsoft® Direct3D®中,只有面的正向是可视的。一个正向面是顶点按照顺时针顺序定义的面。 任何不是正向面的面都是背向面。由于Direct3D不总是渲染背向面,因此背向面要被剔除。如果想要渲染背向面的话,可以改变剔除模式。更多信息请参阅剔除状态。 Direct3D在计算高洛德着色、光照和纹理效果时使用顶点法向。 Direct3D使用顶点法向计算光源和表面间的夹角,对多边形进行高洛德着色。Direct3D计算每个顶点的颜色和亮度值,并对图元表面所覆盖的所有像素点进行插值。Direct3D使用夹角计算光强度,夹角越大,表面得到的光照就越少。 如果正在创建的物体是平直的,可将顶点法向设为与表面垂直,如下图所示。该图定义了一个由两个三角形组成的平直表面。 但是,更可能的情况是物体由三角形带(triangle strips)组成且三角形不共面。要对整个三角形带的三角形平滑着色的一个简单方法是首先计算与顶点相关联的每个多边形表面的表面法向量。可以这样计算顶点法向,使顶点法向与顶点所属的每个表面的法向的夹角相等。但是,对复杂图元来说这种方法可能不够有效。 这种方法如下图所示。图中有两个表面,S1与S2,它们的邻边在上方。S1与S2的法向量用蓝色显示。顶点的法向量用红色显示。顶点法向量与S1表面法向的夹角和顶点法向量与S2表面法向的夹角相同。当对这两个表面进行光照计算和高洛德着色时,得到结果是中间的边被平滑着色,看起来像是弧形的(而不是有棱角的)。 如果顶点法向偏向与它相关联的某个面,那么会导致那个面上的点光强度的增加或减少。下图显示了一个例子。这些面的邻边依然朝上。顶点法向倾向S1,与顶点法向与表面法向有相同的夹角相比,这使顶点法向与光源间的夹角变小。 可以用高洛德着色在三维场景中显示一些有清晰边缘的物体。要达到这个目的,只要在需要产生清晰边缘的表面交线处,把表面法向复制给交线处顶点的法向,如下图所示。 如果使用DrawPrimitive方法渲染场景,要将有锋利边缘的物体定义为三角形表,而非三角形带。当将物体定义为三角形带时,Direct3D会将它作为由多个三角形组成的单个多边形处理。高洛德着色被同时应用于多边形每个表面的内部和表面之间。结果产生表面之间平滑着色的物体。因为三角形表由一系列不相连的三角形面组成,所以Direct3D对多边形每个面的内部使用高洛德着色。但是,没有在表面之间应用高洛德着色。如果三角形表的两个或更多的三角形是相邻的,那么在它们之间看起来会有一条锋利边缘。 另一种可选的方法是在渲染具有锋利边缘的物体时改变到平面着色模式。这在计算上是最有效的方法,但它可能导致场景中的物体不如用高洛德着色渲染的物体真实。 三角形光栅化法则 顶点指定的点经常不能精确地对应到屏幕上的像素。此时,Microsoft® Direct3D®使用三角形光栅化法则决定对于给定三角形使用哪个像素。 三角形光栅化法则 点、线光栅化法则 点精灵光栅化法则 三角形光栅化法则 Direct3D在填充几何图形时使用左上填充约定(top-left filling convention)。这与Microsoft Windows®的图形设备接口(GUI)和OpenGL中的矩形使用的约定相同。Direct3D中,像素的中心是决定点。如果中心在三角形内,那么该像素就是三角形的一部分。像素中心用整数坐标表示。 这里描述的Direct3D使用的三角形光栅化法则不一定适用于所有可用的硬件。测试可以发现这些法则的实现间的细微变化。 下图显示了一个左上角为(0,0),右下角为(5,5)的矩形。正如大家想象的那样,此矩形填充25个像素。矩形的宽度由right减left定义。高度由bottom减top定义。 在左上填充约定中,上表示水平span在垂直方向上的位置,左表示span中的像素在水平方向上的位置。一条边除非是水平的,否则不可能是顶边——一般来说,大多数三角形只有左边或右边。 左上填充约定确定当一个三角形穿过像素的中心时Direct3D采取的动作。下图显示了两个三角形,一个在(0,0),(5,0)和(5,5),另一个在(0,5),(0,0)和(5,5)。在这种情况下第一个三角形得到15个像素(显示为黑色),而第二个得到10个像素(显示为灰色),因为公用边是第一个三角形的左边。 如果应用程序定义一个左上角为(0.5,0.5),右下角为(2.5,4.5)的矩形,那么这个矩形的中心在(1.5,2.5)。当Direct3D光栅化器tessellate这个矩形时,每个像素的中心都毫无异义地分别位于四个三角形中,此时就不需要左上填充约定。下图显示了这种情况。矩形内的像素根据在Direct3D中被哪个三角形包含做了相应的标注。 如果将上例中的矩形移动,使之左上角为(1.0,1.0),右下角为(3.0,5.0),中心为(2.0,3.0),那么Direct3D使用左上角填充约定。这个矩形中大多数的像素跨越两个或更多的三角形的边界,如下图所示。 这两个矩形会影响到相同的像素。 点、线光栅化法则 点和点精灵一样,都被渲染为与屏幕边缘对齐的四边形,因此它们使用与多边形同样的渲染法则。 非抗锯齿线段的渲染法则与GDI使用的法则完全相同。 更多有关抗锯齿线段的渲染,请参阅ID3DXLine。 点精灵光栅化法则 对点精灵和patch图元的渲染,就好像先把图元tessellate成三角形,然后将得到的三角形进行光栅化。更多信息,请参阅点精灵。 矩形 贯穿Microsoft® Direct3D®和Microsoft Windows®编程,都是用术语包围矩形来讨论屏幕上的物体。由于包围矩形的边总是与屏幕的边平行,因此矩形可以用两个点描述,左上角和右下角。当在屏幕上进行位块传输(Blit = Bit block transfer)或命中检测时,大多数应用程序使用RECT结构保存包围矩形的信息。 C++中,RECT结构有如下定义。 typedef struct tagRECT { LONG left; // 这是左上角的x坐标。 LONG top; // 这是左上角的y坐标。 LONG right; // 这是右下角的x坐标。 LONG bottom; // 这是右下角的y坐标。 } RECT, PRECT, NEAR NPRECT, FAR LPRECT; 在上例中,left和top成员是包围矩形左上角的x-和y-坐标。类似地,right和bottom成员组成右下角的坐标。下图直观地显示了这些值。 为了效率、一致性及易用性, Direct3D所有的presentation函数都使用矩形。 三角形插值对象(interpolants) 在渲染时,流水线会贯穿每个三角形的表面进行顶点数据插值。有五种可能的数据类型可以进行插值。顶点数据可以是各种类型的数据,包括(但不限于):漫反射色、镜面反射色、漫反射阿尔法(三角形透明度)、镜面反射阿尔法、雾因子(固定功能流水线从镜面反射的阿尔法分量中取得,可编程顶点流水线则从雾寄存器中取得)。顶点数据通过顶点声明定义。 对一些顶点数据的插值取决于当前的着色模式,如下表所示。 着色模式 描述 平面 在平面着色模式下只对雾因子进行插值。对所有其它的插值对象,整个面都使用三角形第一个顶点的颜色。 高洛德 在所有三个顶点间进行线性插值。 根据不同的颜色模型,对漫反射色和镜面反射色的处理是不同的。在RGB颜色模型中,系统在插值时使用红、绿和蓝颜色分量。 颜色的阿尔法成员作为单独的插值对象对待,因为设备驱动程序可以以两种不同的方法实现透明:使用纹理混合或使用点画法(stippling)。 可以用D3DCAPS9结构的ShadeCaps成员确定设备驱动程序支持何种插值。 向量、顶点和四元数 贯穿Microsoft® Direct3D®,顶点用于描述位置和方向。图元中的每个顶点由指定其位置的向量、颜色、纹理坐标和指定其方向的法向量描述。 四元数给三元素向量的[ x, y, z]值增加了第四个元素。用于三维旋转的方法,除了典型的矩阵以外,四元数是另一种选择。四元数表示三维空间中的一根轴及围绕该轴的一个旋转。例如,一个四元数可能表示轴(1,1,2)和1度的旋转。四元数包含了有价值的信息,但它们真正的威力源自可对它们执行的两种操作:合成和插值。 对四元数进行插值与合成它们类似。两个四元数的合成如下表示: 将两个四元数的合成应用于几何体意味着“把几何体绕axis2轴旋转rotation2角度,然后绕axis1轴旋转rotation1角度”。在这种情况下,Q表示绕单根轴的旋转,该旋转是先后将q2和q1应用于几何体的结果。 使用四元数,应用程序可以计算出一条从一根轴和一个方向到另一根轴和另一个方向的平滑、合理的路径。因此,在q1和q2间插值提供了一个从一个方向变化到另一个方向的简单方法。 当同时使用合成与插值时,四元数提供了一个看似复杂而实际简单的操作几何体的方法。例如,设想我们希望把一个几何体旋转到某个给定方向。我们已经知道希望将它绕axis2轴旋转r2度,然后绕axis1轴旋转r1度,但是我们不知道最终的四元数。通过使用合成,我们可以在几何体上合成两个旋转并得到最终单个的四元数。然后,我们可以在原始四元数和合成的四元数间进行插值,得到两者之间的平滑转换。 Direct3D扩展(D3DX)工具库包含了帮助用户使用四元数的函数。例如,D3DXQuaternionRotationAxis函数给一个定义旋转轴的向量增加一个旋转值,并在由D3DXQUTERNION结构定义的四元数中返回结果。另外,D3DXQuaternionMultiply函数合成四元数,D3DXQuaternionSlerp函数在两个四元数间进行球面线性插值(spherical linear interpolation)。 Direct3D应用程序可以使用下列函数简化对四元数的使用。 D3DXQuaternionBaryCentric D3DXQuaternionConjugate D3DXQuaternionDot D3DXQuaternionExp D3DXQuaternionIdentity D3DXQuaternionInverse D3DXQuaternionIsIdentity D3DXQuaternionLength D3DXQuaternionLengthSq D3DXQuaternionLn D3DXQuaternionMultiply D3DXQuaternionNormalize D3DXQuaternionRotationAxis D3DXQuaternionRotationMatrix D3DXQuaternionRotationYawPitchRoll D3DXQuaternionSlerp D3DXQuaternionSquad D3DXQuaternionToAxisAngle Direct3D应用程序可以使用下列函数简化对三成员向量的使用。 D3DXVec3Add D3DXVec3BaryCentric D3DXVec3CatmullRom D3DXVec3Cross D3DXVec3Dot D3DXVec3Hermite D3DXVec3Length D3DXVec3LengthSq D3DXVec3Lerp D3DXVec3Maximize D3DXVec3Minimize D3DXVec3Normalize D3DXVec3Project D3DXVec3Scale D3DXVec3Subtract D3DXVec3Transform D3DXVec3TransformCoord D3DXVec3TransformNormal D3DXVec3Unproject D3DX工具库提供的数学函数中包含了许多辅助函数,可以简化对二成员和四成员向量的使用 http://www.gesoftfactory.com/developer/3DCS.htm 本篇文章为转载内容。原文链接:https://blog.csdn.net/okvee/article/details/3438011。 该文由互联网用户投稿提供,文中观点代表作者本人意见,并不代表本站的立场。 作为信息平台,本站仅提供文章转载服务,并不拥有其所有权,也不对文章内容的真实性、准确性和合法性承担责任。 如发现本文存在侵权、违法、违规或事实不符的情况,请及时联系我们,我们将第一时间进行核实并删除相应内容。
2023-10-24 12:49:42
271
转载
转载文章
...做其他“动态”事情的应用中。在这种情况下,你可以使用映射实例自身作为委托来实现委托属性。 例如: class User(map: Map 在上例中,委托属性会从构造函数传入的map中取值(通过字符串键——属性的名称),如果遇到声明的属性名在map 中找不到对应的key 名,或者key 对应的value 值的类型与声明的属性的类型不一致,会抛出异常。 内联函数 当一个函数被声明为inline时,它的函数体是内联的,也就是说,函数体会被直接替换到函数被调用地方 inline函数(内联函数)从概念上讲是编译器使用函数实现的真实代码来替换每一次的函数调用,带来的最直接的好处就是节省了函数调用的开销,而缺点就是增加了所生成字节码的尺寸。基于此,在代码量不是很大的情况下,我们是否有必要将所有的函数定义为内联?让我们分两种情况进行说明: 将普通函数定义为内联:众所周知,JVM内部已经实现了内联优化,它会在任何可以通过内联来提升性能的地方将函数调用内联化,并且相对于手动将普通函数定义为内联,通过JVM内联优化所生成的字节码,每个函数的实现只会出现一次,这样在保证减少运行时开销的同时,也没有增加字节码的尺寸;所以我们可以得出结论,对于普通函数,我们没有必要将其声明为内联函数,而是交给JVM自行优化。 将带有lambda参数的函数定义为内联:是的,这种情况下确实可以提高性能;但在使用的过程中,我们会发现它是有诸多限制的,让我们从下面的例子开始展开说明: inline 假如我们这样调用doSomething: fun main(args: Array<String>) { 上面的调用会被编译成: fun main(args: Array<String>) { 从上面编译的结果可以看出,无论doSomething函数还是action参数都被内联了,很棒,那让我们换一种调用方式: fun main(args: Array<String>) { 上面的调用会被编译成: fun main(args: Array<String>) { doSomething函数被内联,而action参数没有被内联,这是因为以函数型变量的形式传递给doSomething的lambda在函数的调用点是不可用的,只有等到doSomething被内联后,该lambda才可以正常使用。 通过上面的例子,我们对lambda表达式何时被内联做一下简单的总结: 当lambda表达式以参数的形式直接传递给内联函数,那么lambda表达式的代码会被直接替换到最终生成的代码中。 当lambda表达式在某个地方被保存起来,然后以变量形式传递给内联函数,那么此时的lambda表达式的代码将不会被内联。 上面对lambda的内联时机进行了讨论,消化片刻后让我们再看最后一个例子: inline 上面的例子是否有问题?是的,编译器会抛出“Illegal usage of inline-parameter”的错误,这是因为Kotlin规定内联函数中的lambda参数只能被直接调用或者传递给另外一个内联函数,除此之外不能作为他用;那我们如果确实想要将某一个lambda传递给一个非内联函数怎么办?我们只需将上述代码这样改造即可: inline 很简单,在不需要内联的lambda参数前加上noinline修饰符就可以了。 以上便是我对内联函数的全部理解,通过掌握该特性的运行机制,相信大家可以做到在正确的时机使用该特性,而非滥用或因恐惧弃而不用。 Kotlin下单例模式 饿汉式实现 //Java实现 懒汉式 //Java实现 上述代码中,我们可以发现在Kotlin实现中,我们让其主构造函数私有化并自定义了其属性访问器,其余内容大同小异。 如果有小伙伴不清楚Kotlin构造函数的使用方式。请点击 - - - 构造函数 不清楚Kotlin的属性与访问器,请点击 - - -属性和字段 线程安全的懒汉式 //Java实现 大家都知道在使用懒汉式会出现线程安全的问题,需要使用使用同步锁,在Kotlin中,如果你需要将方法声明为同步,需要添加@Synchronized注解。 双重校验锁式 //Java实现 哇!小伙伴们惊喜不,感不感动啊。我们居然几行代码就实现了多行的Java代码。其中我们运用到了Kotlin的延迟属性 Lazy。 Lazy内部实现 public 观察上述代码,因为我们传入的mode = LazyThreadSafetyMode.SYNCHRONIZED, 那么会直接走 SynchronizedLazyImpl,我们继续观察SynchronizedLazyImpl。 Lazy接口 SynchronizedLazyImpl实现了Lazy接口,Lazy具体接口如下: public 继续查看SynchronizedLazyImpl,具体实现如下: SynchronizedLazyImpl内部实现 private 通过上述代码,我们发现 SynchronizedLazyImpl 覆盖了Lazy接口的value属性,并且重新了其属性访问器。其具体逻辑与Java的双重检验是类似的。 到里这里其实大家还是肯定有疑问,我这里只是实例化了SynchronizedLazyImpl对象,并没有进行值的获取,它是怎么拿到高阶函数的返回值呢?。这里又涉及到了委托属性。 委托属性语法是:val/var : by 。在 by 后面的表达式是该 委托, 因为属性对应的 get()(和 set())会被委托给它的 getValue() 和 setValue() 方法。属性的委托不必实现任何的接口,但是需要提供一个 getValue() 函数(和 setValue()——对于 var 属性)。 而Lazy.kt文件中,声明了Lazy接口的getValue扩展函数。故在最终赋值的时候会调用该方法。 internal.InlineOnly 静态内部类式 //Java实现 静态内部类的实现方式,也没有什么好说的。Kotlin与Java实现基本雷同。 补充 在该篇文章结束后,有很多小伙伴咨询,如何在Kotlin版的Double Check,给单例添加一个属性,这里我给大家提供了一个实现的方式。(不好意思,最近才抽出时间来解决这个问题) class SingletonDemo private constructor( 其中关于?:操作符,如果 ?: 左侧表达式非空,就返回其左侧表达式,否则返回右侧表达式。请注意,当且仅当左侧为空时,才会对右侧表达式求值。 Kotlin 智能类型转换 对于子父类之间的类型转换 先看这样一段 Java 代码 public 尽管在 main 函数中,对 person 这个对象进行了类型判断,但是在使用的时候还是需要强制转换成 Student 类型,这样是不是很不智能? 同样的情况在 Kotlin 中就变得简单多了 fun main(args: Array<String>) { 在 Kotlin 中,只要对类型进行了判断,就可以直接通过父类的对象去调用子类的函数了 安全的类型转换 还是上面的那个例子,如果我们没有进行类型判断,并且直接进行强转,会怎么样呢? public static void main(String[] args) { 结果就只能是 Exception in thread "main" java.lang.ClassCastException 那么在 Kotlin 中是不是会有更好的解决方法呢? val person: Person = Person() 在转换操作符后面添加一个 ?,就不会把程序 crash 掉了,当转化失败的时候,就会返回一个 null 在空类型中的智能转换 需要提前了解 Kotlin 类型安全的相关知识(Kotlin 中的类型安全(对空指针的优化处理)) String? = aString 在定义的时候定义成了有可能为 null,按照之前的写法,我们需要这样写 String? = 但是已经进行了是否为 String 类型的判断,所以就一定 不是 空类型了,也就可以直接输出它的长度了 T.()->Unit 、 ()->Unit 在做kotlin开发中,经常看到一些系统函数里,用函数作为参数 public .()-Unit与()->Unit的区别是我们调用时,在代码块里面写this,的时候,两个this代表的含义不一样,T.()->Unit里的this代表的是自身实例,而()->Unit里,this代表的是外部类的实例。 推荐阅读 对 Kotlin 与 Java 编程语言的思考 使用 Kotlin 做开发一个月后的感想 扫一扫 关注我的公众号如果你想要跟大家分享你的文章,欢迎投稿~ 本篇文章为转载内容。原文链接:https://blog.csdn.net/weixin_39611037/article/details/109984124。 该文由互联网用户投稿提供,文中观点代表作者本人意见,并不代表本站的立场。 作为信息平台,本站仅提供文章转载服务,并不拥有其所有权,也不对文章内容的真实性、准确性和合法性承担责任。 如发现本文存在侵权、违法、违规或事实不符的情况,请及时联系我们,我们将第一时间进行核实并删除相应内容。
2023-06-23 23:56:14
470
转载
转载文章
...表达式在实际项目中的应用,可以查阅一些近期开发者博客或技术文章,了解他们在表单验证、URL解析、文本搜索替换等方面的实战案例。例如,一篇名为“利用正则表达式优化用户输入验证策略”的文章详尽探讨了如何结合现代浏览器特性,如约束验证API,配合正则表达式进行高效的数据校验。 此外,对于正则表达式的性能优化也是值得关注的话题。有研究指出,在处理大量数据时,某些复杂的正则可能导致性能瓶颈。阅读相关的性能分析报告和技术分享,可以帮助开发者掌握编写高性能正则表达式的技巧,并避免潜在的性能陷阱。 最后,关于UTC时间戳在跨时区开发中的重要性,可参考有关国际协作项目中如何妥善处理时间问题的文章,了解如何借助JavaScript Date对象正确转换和处理不同时区的时间信息,从而确保在全球范围内应用程序的正常运行。尤其在当前全球化的互联网环境下,理解和掌握这一技能愈发关键。
2023-01-24 13:01:25
529
转载
转载文章
...础原理在实际开发中的应用广泛且关键。近期,Google开源项目Abseil库就很好地体现了对构造函数和析构函数的高效利用,通过智能指针管理资源生命周期,确保了内存安全,减少了潜在的内存泄漏风险。 此外,随着C++17及后续标准的发布,类模板与友元机制也得到了进一步增强和完善。比如,在C++20中引入了模块(Modules)特性,使得类模板的编译速度大大提高,同时增强了类型安全性,对于大型项目的组织结构优化具有重要意义。友元在现代C++设计模式中仍然发挥着不可替代的作用,特别是在实现组件间深度交互时,如游戏引擎中不同系统间的紧密协作,往往借助友元关系来突破封装限制,实现高效的底层数据访问。 另外,对于对象数组、对象指针以及静态成员的讨论,实则指向了更为复杂的内存管理和对象生命周期问题。近期一篇来自ACM Queue的文章《深入剖析C++内存模型》对此做了深度解读,并探讨了在多线程环境下的同步控制和内存一致性问题,这对于理解并有效利用C++进行高性能并发编程至关重要。 总之,掌握好本文所述的基础知识是至关重要的,而与时俱进地了解最新实践和技术趋势,将有助于我们更高效、安全地运用C++进行软件开发,解决实际工程中的复杂问题。
2024-01-29 12:38:23
544
转载
转载文章
...4天 Python是应用机器学习发展最快的平台之一。 在本小课程中,您将发现如何在14天内使用Python入门,建立准确的模型以及自信地完成预测建模机器学习项目。 这是重要的职位。您可能要为其添加书签。 在我的新书中,通过16个循序渐进的教程,3个项目和完整的python代码,探索如何用熊猫准备数据,使用scikit-learn拟合和评估模型,以及更多内容。 让我们开始吧。 2016年10月更新:更新了sklearn v0.18的示例。 2018年2月更新:更新Python和库版本。 2018年3月更新:增加了备用链接以下载一些数据集,因为原始文件似乎已被删除。 2019年5月更新:修复了scikit-learn最新版本的警告消息。 Dave Young的 Python机器学习迷你课程 照片,保留一些权利。 迷你课程面向谁? 在开始之前,请确保您在正确的位置。 下面的列表提供了有关本课程针对谁的一些一般指导。 如果您没有完全匹配这些点,请不要惊慌,您可能只需要在一个或另一个区域刷牙以跟上。 知道如何编写一些代码的开发人员。这意味着,一旦您了解基本语法,就可以选择像Python这样的新编程语言,这对您来说并不重要。这并不意味着您是一名向导编码员,而是可以毫不费力地遵循基本的类似于C的语言。 懂一点机器学习的开发人员。这意味着您了解机器学习的基础知识,例如交叉验证,一些算法和偏差方差折衷。这并不意味着您是机器学习博士,而是您知道地标或知道在哪里查找。 这门迷你课程既不是Python的教科书,也不是机器学习的教科书。 从一个懂一点机器学习的开发人员到一个可以使用Python生态系统获得结果的开发人员,Python生态系统是专业机器学习的新兴平台。 在Python机器学习方面需要帮助吗? 参加我为期2周的免费电子邮件课程,发现数据准备,算法等(包括代码)。 单击立即注册,并获得该课程的免费PDF电子书版本。 立即开始免费的迷你课程! 迷你课程概述 该微型课程分为14节课。 您可以每天完成一堂课(推荐),也可以在一天内完成所有课程(核心!)。这实际上取决于您有空的时间和您的热情水平。 以下是14个课程,可帮助您入门并提高使用Python进行机器学习的效率: 第1课:下载并安装Python和SciPy生态系统。 第2课:深入了解Python,NumPy,Matplotlib和Pandas。 第3课:从CSV加载数据。 第4课:了解具有描述性统计信息的数据。 第5课:通过可视化了解数据。 第6课:通过预处理数据准备建模。 第7课:使用重采样方法进行算法评估。 第8课:算法评估指标。 第9课:现场检查算法。 第10课:模型比较和选择。 第11课:通过算法调整提高准确性。 第12课:利用集合预测提高准确性。 第13课:完成并保存模型。 第14课:Hello World端到端项目。 每节课可能需要您60秒钟或最多30分钟。花点时间按照自己的进度完成课程。提出问题,甚至在以下评论中发布结果。 这些课程希望您能开始学习并做事。我会给您提示,但每节课的重点是迫使您学习从哪里寻求有关Python平台的帮助(提示,我直接在此博客上获得了所有答案,请使用搜索特征)。 在早期课程中,我确实提供了更多帮助,因为我希望您树立一些信心和惯性。 挂在那里,不要放弃! 第1课:下载并安装Python和SciPy 您必须先访问平台才能开始使用Python进行机器学习。 今天的课程很简单,您必须在计算机上下载并安装Python 3.6平台。 访问Python主页并下载适用于您的操作系统(Linux,OS X或Windows)的Python。在计算机上安装Python。您可能需要使用特定于平台的软件包管理器,例如OS X上的macports或RedHat Linux上的yum。 您还需要安装SciPy平台和scikit-learn库。我建议使用与安装Python相同的方法。 您可以使用Anaconda一次安装所有内容(更加容易)。推荐给初学者。 通过在命令行中键入“ python”来首次启动Python。 使用以下代码检查所有您需要的版本: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 Python version import sys print('Python: {}'.format(sys.version)) scipy import scipy print('scipy: {}'.format(scipy.__version__)) numpy import numpy print('numpy: {}'.format(numpy.__version__)) matplotlib import matplotlib print('matplotlib: {}'.format(matplotlib.__version__)) pandas import pandas print('pandas: {}'.format(pandas.__version__)) scikit-learn import sklearn print('sklearn: {}'.format(sklearn.__version__)) 如果有任何错误,请停止。现在该修复它们了。 需要帮忙?请参阅本教程: 如何使用Anaconda设置用于机器学习和深度学习的Python环境 第2课:深入了解Python,NumPy,Matplotlib和Pandas。 您需要能够读写基本的Python脚本。 作为开发人员,您可以很快选择新的编程语言。Python区分大小写,使用哈希(#)进行注释,并使用空格指示代码块(空格很重要)。 今天的任务是在Python交互环境中练习Python编程语言的基本语法和重要的SciPy数据结构。 练习作业,在Python中使用列表和流程控制。 练习使用NumPy数组。 练习在Matplotlib中创建简单图。 练习使用Pandas Series和DataFrames。 例如,以下是创建Pandas DataFrame的简单示例。 1 2 3 4 5 6 7 8 dataframe import numpy import pandas myarray = numpy.array([[1, 2, 3], [4, 5, 6]]) rownames = ['a', 'b'] colnames = ['one', 'two', 'three'] mydataframe = pandas.DataFrame(myarray, index=rownames, columns=colnames) print(mydataframe) 第3课:从CSV加载数据 机器学习算法需要数据。您可以从CSV文件加载自己的数据,但是当您开始使用Python进行机器学习时,应该在标准机器学习数据集上进行练习。 今天课程的任务是让您轻松地将数据加载到Python中并查找和加载标准的机器学习数据集。 您可以在UCI机器学习存储库上下载和练习许多CSV格式的出色标准机器学习数据集。 练习使用标准库中的CSV.reader()将CSV文件加载到Python 中。 练习使用NumPy和numpy.loadtxt()函数加载CSV文件。 练习使用Pandas和pandas.read_csv()函数加载CSV文件。 为了让您入门,下面是一个片段,该片段将直接从UCI机器学习存储库中使用Pandas来加载Pima Indians糖尿病数据集。 1 2 3 4 5 6 Load CSV using Pandas from URL import pandas url = "https://raw.githubusercontent.com/jbrownlee/Datasets/master/pima-indians-diabetes.data.csv" names = ['preg', 'plas', 'pres', 'skin', 'test', 'mass', 'pedi', 'age', 'class'] data = pandas.read_csv(url, names=names) print(data.shape) 到现在为止做得很好!等一下 到目前为止有什么问题吗?在评论中提问。 第4课:使用描述性统计数据理解数据 将数据加载到Python之后,您需要能够理解它。 您越了解数据,可以构建的模型就越精确。了解数据的第一步是使用描述性统计数据。 今天,您的课程是学习如何使用描述性统计信息来理解您的数据。我建议使用Pandas DataFrame上提供的帮助程序功能。 使用head()函数了解您的数据以查看前几行。 使用shape属性查看数据的维度。 使用dtypes属性查看每个属性的数据类型。 使用describe()函数查看数据的分布。 使用corr()函数计算变量之间的成对相关性。 以下示例加载了皮马印第安人糖尿病发病数据集,并总结了每个属性的分布。 1 2 3 4 5 6 7 Statistical Summary import pandas url = "https://raw.githubusercontent.com/jbrownlee/Datasets/master/pima-indians-diabetes.data.csv" names = ['preg', 'plas', 'pres', 'skin', 'test', 'mass', 'pedi', 'age', 'class'] data = pandas.read_csv(url, names=names) description = data.describe() print(description) 试试看! 第5课:通过可视化了解数据 从昨天的课程继续,您必须花一些时间更好地了解您的数据。 增进对数据理解的第二种方法是使用数据可视化技术(例如,绘图)。 今天,您的课程是学习如何在Python中使用绘图来单独理解属性及其相互作用。再次,我建议使用Pandas DataFrame上提供的帮助程序功能。 使用hist()函数创建每个属性的直方图。 使用plot(kind ='box')函数创建每个属性的箱须图。 使用pandas.scatter_matrix()函数创建所有属性的成对散点图。 例如,下面的代码片段将加载糖尿病数据集并创建数据集的散点图矩阵。 1 2 3 4 5 6 7 8 9 Scatter Plot Matrix import matplotlib.pyplot as plt import pandas from pandas.plotting import scatter_matrix url = "https://raw.githubusercontent.com/jbrownlee/Datasets/master/pima-indians-diabetes.data.csv" names = ['preg', 'plas', 'pres', 'skin', 'test', 'mass', 'pedi', 'age', 'class'] data = pandas.read_csv(url, names=names) scatter_matrix(data) plt.show() 样本散点图矩阵 第6课:通过预处理数据准备建模 您的原始数据可能未设置为最佳建模形式。 有时您需要对数据进行预处理,以便最好地将问题的固有结构呈现给建模算法。在今天的课程中,您将使用scikit-learn提供的预处理功能。 scikit-learn库提供了两个用于转换数据的标准习语。每种变换在不同的情况下都非常有用:拟合和多重变换以及组合的拟合与变换。 您可以使用多种技术来准备数据以进行建模。例如,尝试以下一些方法 使用比例和中心选项将数值数据标准化(例如,平均值为0,标准偏差为1)。 使用范围选项将数值数据标准化(例如,范围为0-1)。 探索更高级的功能工程,例如Binarizing。 例如,下面的代码段加载了Pima Indians糖尿病发病数据集,计算了标准化数据所需的参数,然后创建了输入数据的标准化副本。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 Standardize data (0 mean, 1 stdev) from sklearn.preprocessing import StandardScaler import pandas import numpy url = "https://raw.githubusercontent.com/jbrownlee/Datasets/master/pima-indians-diabetes.data.csv" names = ['preg', 'plas', 'pres', 'skin', 'test', 'mass', 'pedi', 'age', 'class'] dataframe = pandas.read_csv(url, names=names) array = dataframe.values separate array into input and output components X = array[:,0:8] Y = array[:,8] scaler = StandardScaler().fit(X) rescaledX = scaler.transform(X) summarize transformed data numpy.set_printoptions(precision=3) print(rescaledX[0:5,:]) 第7课:使用重采样方法进行算法评估 用于训练机器学习算法的数据集称为训练数据集。用于训练算法的数据集不能用于为您提供有关新数据的模型准确性的可靠估计。这是一个大问题,因为创建模型的整个思路是对新数据进行预测。 您可以使用称为重采样方法的统计方法将训练数据集划分为子集,一些方法用于训练模型,而另一些则被保留,并用于估计看不见的数据的模型准确性。 今天课程的目标是练习使用scikit-learn中可用的不同重采样方法,例如: 将数据集分为训练集和测试集。 使用k倍交叉验证来估计算法的准确性。 使用留一法交叉验证来估计算法的准确性。 下面的代码段使用scikit-learn通过10倍交叉验证来评估Pima Indians糖尿病发作的Logistic回归算法的准确性。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 Evaluate using Cross Validation from pandas import read_csv from sklearn.model_selection import KFold from sklearn.model_selection import cross_val_score from sklearn.linear_model import LogisticRegression url = "https://raw.githubusercontent.com/jbrownlee/Datasets/master/pima-indians-diabetes.data.csv" names = ['preg', 'plas', 'pres', 'skin', 'test', 'mass', 'pedi', 'age', 'class'] dataframe = read_csv(url, names=names) array = dataframe.values X = array[:,0:8] Y = array[:,8] kfold = KFold(n_splits=10, random_state=7) model = LogisticRegression(solver='liblinear') results = cross_val_score(model, X, Y, cv=kfold) print("Accuracy: %.3f%% (%.3f%%)") % (results.mean()100.0, results.std()100.0) 您获得了什么精度?在评论中让我知道。 您是否意识到这是中间点?做得好! 第8课:算法评估指标 您可以使用许多不同的指标来评估数据集上机器学习算法的技能。 您可以通过cross_validation.cross_val_score()函数在scikit-learn中指定用于测试工具的度量,默认值可用于回归和分类问题。今天课程的目标是练习使用scikit-learn软件包中可用的不同算法性能指标。 在分类问题上练习使用“准确性”和“ LogLoss”度量。 练习生成混淆矩阵和分类报告。 在回归问题上练习使用RMSE和RSquared指标。 下面的代码段演示了根据Pima Indians糖尿病发病数据计算LogLoss指标。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 Cross Validation Classification LogLoss from pandas import read_csv from sklearn.model_selection import KFold from sklearn.model_selection import cross_val_score from sklearn.linear_model import LogisticRegression url = "https://raw.githubusercontent.com/jbrownlee/Datasets/master/pima-indians-diabetes.data.csv" names = ['preg', 'plas', 'pres', 'skin', 'test', 'mass', 'pedi', 'age', 'class'] dataframe = read_csv(url, names=names) array = dataframe.values X = array[:,0:8] Y = array[:,8] kfold = KFold(n_splits=10, random_state=7) model = LogisticRegression(solver='liblinear') scoring = 'neg_log_loss' results = cross_val_score(model, X, Y, cv=kfold, scoring=scoring) print("Logloss: %.3f (%.3f)") % (results.mean(), results.std()) 您得到了什么日志损失?在评论中让我知道。 第9课:抽查算法 您可能无法事先知道哪种算法对您的数据效果最好。 您必须使用反复试验的过程来发现它。我称之为现场检查算法。scikit-learn库提供了许多机器学习算法和工具的接口,以比较这些算法的估计准确性。 在本课程中,您必须练习抽查不同的机器学习算法。 对数据集进行抽查线性算法(例如线性回归,逻辑回归和线性判别分析)。 抽查数据集上的一些非线性算法(例如KNN,SVM和CART)。 抽查数据集上一些复杂的集成算法(例如随机森林和随机梯度增强)。 例如,下面的代码片段对Boston House Price数据集上的K最近邻居算法进行了抽查。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 KNN Regression from pandas import read_csv from sklearn.model_selection import KFold from sklearn.model_selection import cross_val_score from sklearn.neighbors import KNeighborsRegressor url = "https://raw.githubusercontent.com/jbrownlee/Datasets/master/housing.data" names = ['CRIM', 'ZN', 'INDUS', 'CHAS', 'NOX', 'RM', 'AGE', 'DIS', 'RAD', 'TAX', 'PTRATIO', 'B', 'LSTAT', 'MEDV'] dataframe = read_csv(url, delim_whitespace=True, names=names) array = dataframe.values X = array[:,0:13] Y = array[:,13] kfold = KFold(n_splits=10, random_state=7) model = KNeighborsRegressor() scoring = 'neg_mean_squared_error' results = cross_val_score(model, X, Y, cv=kfold, scoring=scoring) print(results.mean()) 您得到的平方误差是什么意思?在评论中让我知道。 第10课:模型比较和选择 既然您知道了如何在数据集中检查机器学习算法,那么您需要知道如何比较不同算法的估计性能并选择最佳模型。 在今天的课程中,您将练习比较Python和scikit-learn中的机器学习算法的准确性。 在数据集上相互比较线性算法。 在数据集上相互比较非线性算法。 相互比较同一算法的不同配置。 创建比较算法的结果图。 下面的示例在皮马印第安人发病的糖尿病数据集中将Logistic回归和线性判别分析进行了比较。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 Compare Algorithms from pandas import read_csv from sklearn.model_selection import KFold from sklearn.model_selection import cross_val_score from sklearn.linear_model import LogisticRegression from sklearn.discriminant_analysis import LinearDiscriminantAnalysis load dataset url = "https://raw.githubusercontent.com/jbrownlee/Datasets/master/pima-indians-diabetes.data.csv" names = ['preg', 'plas', 'pres', 'skin', 'test', 'mass', 'pedi', 'age', 'class'] dataframe = read_csv(url, names=names) array = dataframe.values X = array[:,0:8] Y = array[:,8] prepare models models = [] models.append(('LR', LogisticRegression(solver='liblinear'))) models.append(('LDA', LinearDiscriminantAnalysis())) evaluate each model in turn results = [] names = [] scoring = 'accuracy' for name, model in models: kfold = KFold(n_splits=10, random_state=7) cv_results = cross_val_score(model, X, Y, cv=kfold, scoring=scoring) results.append(cv_results) names.append(name) msg = "%s: %f (%f)" % (name, cv_results.mean(), cv_results.std()) print(msg) 哪种算法效果更好?你能做得更好吗?在评论中让我知道。 第11课:通过算法调整提高准确性 一旦找到一种或两种在数据集上表现良好的算法,您可能希望提高这些模型的性能。 提高算法性能的一种方法是将其参数调整为特定的数据集。 scikit-learn库提供了两种方法来搜索机器学习算法的参数组合。在今天的课程中,您的目标是练习每个。 使用您指定的网格搜索来调整算法的参数。 使用随机搜索调整算法的参数。 下面使用的代码段是一个示例,该示例使用网格搜索在Pima Indians糖尿病发病数据集上的Ridge回归算法。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 Grid Search for Algorithm Tuning from pandas import read_csv import numpy from sklearn.linear_model import Ridge from sklearn.model_selection import GridSearchCV url = "https://raw.githubusercontent.com/jbrownlee/Datasets/master/pima-indians-diabetes.data.csv" names = ['preg', 'plas', 'pres', 'skin', 'test', 'mass', 'pedi', 'age', 'class'] dataframe = read_csv(url, names=names) array = dataframe.values X = array[:,0:8] Y = array[:,8] alphas = numpy.array([1,0.1,0.01,0.001,0.0001,0]) param_grid = dict(alpha=alphas) model = Ridge() grid = GridSearchCV(estimator=model, param_grid=param_grid, cv=3) grid.fit(X, Y) print(grid.best_score_) print(grid.best_estimator_.alpha) 哪些参数取得最佳效果?你能做得更好吗?在评论中让我知道。 第12课:利用集合预测提高准确性 您可以提高模型性能的另一种方法是组合来自多个模型的预测。 一些模型提供了内置的此功能,例如用于装袋的随机森林和用于增强的随机梯度增强。可以使用另一种称为投票的合奏将来自多个不同模型的预测组合在一起。 在今天的课程中,您将练习使用合奏方法。 使用随机森林和多余树木算法练习装袋。 使用梯度增强机和AdaBoost算法练习增强合奏。 通过将来自多个模型的预测组合在一起来练习投票合奏。 下面的代码段演示了如何在Pima Indians糖尿病发病数据集上使用随机森林算法(袋装决策树集合)。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 Random Forest Classification from pandas import read_csv from sklearn.model_selection import KFold from sklearn.model_selection import cross_val_score from sklearn.ensemble import RandomForestClassifier url = "https://raw.githubusercontent.com/jbrownlee/Datasets/master/pima-indians-diabetes.data.csv" names = ['preg', 'plas', 'pres', 'skin', 'test', 'mass', 'pedi', 'age', 'class'] dataframe = read_csv(url, names=names) array = dataframe.values X = array[:,0:8] Y = array[:,8] num_trees = 100 max_features = 3 kfold = KFold(n_splits=10, random_state=7) model = RandomForestClassifier(n_estimators=num_trees, max_features=max_features) results = cross_val_score(model, X, Y, cv=kfold) print(results.mean()) 你能设计出更好的合奏吗?在评论中让我知道。 第13课:完成并保存模型 找到有关机器学习问题的良好模型后,您需要完成该模型。 在今天的课程中,您将练习与完成模型有关的任务。 练习使用模型对新数据(在训练和测试过程中看不到的数据)进行预测。 练习将经过训练的模型保存到文件中,然后再次加载。 例如,下面的代码片段显示了如何创建Logistic回归模型,将其保存到文件中,之后再加载它以及对看不见的数据进行预测。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 Save Model Using Pickle from pandas import read_csv from sklearn.model_selection import train_test_split from sklearn.linear_model import LogisticRegression import pickle url = "https://raw.githubusercontent.com/jbrownlee/Datasets/master/pima-indians-diabetes.data.csv" names = ['preg', 'plas', 'pres', 'skin', 'test', 'mass', 'pedi', 'age', 'class'] dataframe = read_csv(url, names=names) array = dataframe.values X = array[:,0:8] Y = array[:,8] test_size = 0.33 seed = 7 X_train, X_test, Y_train, Y_test = train_test_split(X, Y, test_size=test_size, random_state=seed) Fit the model on 33% model = LogisticRegression(solver='liblinear') model.fit(X_train, Y_train) save the model to disk filename = 'finalized_model.sav' pickle.dump(model, open(filename, 'wb')) some time later... load the model from disk loaded_model = pickle.load(open(filename, 'rb')) result = loaded_model.score(X_test, Y_test) print(result) 第14课:Hello World端到端项目 您现在知道如何完成预测建模机器学习问题的每个任务。 在今天的课程中,您需要练习将各个部分组合在一起,并通过端到端的标准机器学习数据集进行操作。 端到端遍历虹膜数据集(机器学习的世界) 这包括以下步骤: 使用描述性统计数据和可视化了解您的数据。 预处理数据以最好地揭示问题的结构。 使用您自己的测试工具抽查多种算法。 使用算法参数调整来改善结果。 使用集成方法改善结果。 最终确定模型以备将来使用。 慢慢进行,并记录结果。 您使用什么型号?您得到了什么结果?在评论中让我知道。 结束! (看你走了多远) 你做到了。做得好! 花一点时间,回头看看你已经走了多远。 您最初对机器学习感兴趣,并强烈希望能够使用Python练习和应用机器学习。 您可能是第一次下载,安装并启动Python,并开始熟悉该语言的语法。 在许多课程中,您逐渐地,稳定地学习了预测建模机器学习项目的标准任务如何映射到Python平台上。 基于常见机器学习任务的配方,您使用Python端到端解决了第一个机器学习问题。 使用标准模板,您所收集的食谱和经验现在可以自行解决新的和不同的预测建模机器学习问题。 不要轻描淡写,您在短时间内就取得了长足的进步。 这只是您使用Python进行机器学习的起点。继续练习和发展自己的技能。 喜欢点下关注,你的关注是我写作的最大支持 本篇文章为转载内容。原文链接:https://blog.csdn.net/m0_37337849/article/details/104016531。 该文由互联网用户投稿提供,文中观点代表作者本人意见,并不代表本站的立场。 作为信息平台,本站仅提供文章转载服务,并不拥有其所有权,也不对文章内容的真实性、准确性和合法性承担责任。 如发现本文存在侵权、违法、违规或事实不符的情况,请及时联系我们,我们将第一时间进行核实并删除相应内容。
2023-07-11 10:04:06
92
转载
站内搜索
用于搜索本网站内部文章,支持栏目切换。
知识学习
实践的时候请根据实际情况谨慎操作。
随机学习一条linux命令:
history | tail -n 10
- 查看最近十条历史记录。
推荐内容
推荐本栏目内的其它文章,看看还有哪些文章让你感兴趣。
2023-04-28
2023-08-09
2023-06-18
2023-04-14
2023-02-18
2023-04-17
2024-01-11
2023-10-03
2023-09-09
2023-06-13
2023-08-07
2023-03-11
历史内容
快速导航到对应月份的历史文章列表。
随便看看
拉到页底了吧,随便看看还有哪些文章你可能感兴趣。
时光飞逝
"流光容易把人抛,红了樱桃,绿了芭蕉。"