前端技术
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
[表面法向量计算及其对光照效果的影响 ]的搜索结果
这里是文章列表。热门标签的颜色随机变换,标签颜色没有特殊含义。
点击某个标签可搜索标签相关的文章。
点击某个标签可搜索标签相关的文章。
Nacos
...某个配置项的加载顺序影响了Nacos的读取?”我突然想到这一点。我琢磨着这事儿,干脆把所有的配置加载顺序仔仔细细捋了一遍,就为了确保Nacos的配置能在服务刚启动的时候就给安排上,别拖到后面出了幺蛾子。 同时,我还加强了异常处理逻辑,给Nacos的读取操作加上了try-catch块,以便捕获具体的异常信息: java try { String content = configService.getConfig(dataId, group, timeoutMs); System.out.println("Config loaded successfully: " + content); } catch (NacosException e) { System.err.println("Failed to load config: " + e.getMessage()); } 经过一番调整后,我再次启动服务,终于看到了一条令人振奋的消息:“Config loaded successfully”。 “太好了!”我长舒一口气,“原来问题就出在这里啊。” --- 五、总结与感悟 经过这次折腾,我对Nacos有了更深的理解。Nacos这东西确实挺牛的,是个超棒的配置管理工具,但用着用着你会发现,它也不是完美无缺的,各种小问题啊、坑啊,时不时就冒出来折腾你一下。其实吧,这些问题真不一定是Nacos自己惹的祸,八成是咱们的代码写得有点问题,或者是环境配错了,带偏了Nacos。 “其实啊,调试的过程就像侦探破案一样,需要耐心和细心。我坐在电脑前忍不住感慨:“哎,有时候觉得这问题看起来平平无奇的,可谁知道背后可能藏着啥惊天大秘密呢!”” 总之,这次经历让我明白了一个道理:遇到问题不要慌,要冷静分析,逐步排查。只有这样,才能找到问题的根本原因,解决问题。希望我的经验能对大家有所帮助,如果有类似的问题,不妨按照这个思路试试看!
2025-04-06 15:56:57
68
清风徐来
转载文章
...掌握deepin系统及其周边软件的最新发展动态,将有助于我们更好地利用这一平台进行高效开发和舒适办公。
2023-11-15 19:14:44
55
转载
Beego
近期,随着云计算和微服务架构的普及,越来越多的开发者开始关注配置管理的最佳实践。在这一背景下,Beego 框架的配置文件解析问题虽然看似基础,却依然具有重要意义。实际上,类似的问题不仅限于 Beego,而是广泛存在于各种框架和工具中。例如,Spring Boot 社区最近也发布了一篇博客,探讨了如何优化配置文件的加载机制,以应对大规模分布式系统的挑战。这表明,随着技术的发展,配置管理正变得越来越复杂,同时也更加关键。 从现实案例来看,某知名电商企业在一次系统升级过程中,由于配置文件格式错误导致服务中断长达数小时。事后调查发现,问题的根本原因并非技术难度,而是团队缺乏对配置管理的重视。这一事件引发了行业内对于配置文件规范化管理的反思。一些专家指出,现代开发团队应当建立完善的 CI/CD 流程,将配置文件的检查纳入自动化测试环节,从而最大限度地减少人为失误。 此外,近年来 DevOps 思维的兴起也为配置管理带来了新的视角。传统的配置管理往往被视为运维人员的职责,但在 DevOps 文化中,开发与运维之间的界限逐渐模糊。这意味着开发者也需要具备一定的配置管理知识,以便更好地支持持续交付流程。例如,GitHub Actions 等工具集成了丰富的配置模板,帮助开发者快速搭建自动化工作流。这种趋势不仅提升了效率,还促进了跨部门协作。 回到 Beego 框架本身,其核心开发者也在积极迭代版本,引入更多智能化特性。例如,新版 Beego 支持基于环境变量的动态配置加载,允许用户在不同环境中灵活切换设置。这一改进既体现了技术的进步,也反映了社区对用户体验的关注。未来,随着 Go 语言生态的不断完善,配置管理工具可能会进一步集成到语言标准库中,形成更加统一的解决方案。 综上所述,无论是从技术趋势还是实际应用的角度看,配置文件管理始终是软件工程中的重要一环。希望本文能够激发读者对这一领域的兴趣,并鼓励大家在日常工作中投入更多精力去优化配置流程。毕竟,正如一句古话所言:“千里之堤,溃于蚁穴”,细微之处往往决定成败。
2025-04-13 15:33:12
25
桃李春风一杯酒
Hadoop
...样能拿得到,完全不受影响。 说到这里,你可能会问:“为什么要复制这么多份?会不会浪费空间?”确实,多副本策略会占用更多的磁盘空间,但它的优点远远超过这一点。先说白了就是,它能让数据更好用、更靠谱啊!再说了,在那种超大的服务器集群里头,这样的备份机制还能帮着分散压力,不让某一个地方出问题就整个崩掉。 --- 3. 实战演示 如何使用Hadoop进行跨硬件复制? 接下来,让我们动手试试看!我会通过一些实际的例子来展示Hadoop是如何完成文件跨硬件复制的。 3.1 安装与配置Hadoop 首先,你需要确保自己的环境已经安装好了Hadoop。如果你还没有安装,可以参考官方文档一步步来配置。对新手来说,建议先试试伪分布式模式,相当于在一台电脑上“假装”有一个完整的集群,方便你熟悉环境又不用折腾多台机器。 3.2 创建一个简单的文本文件 我们先创建一个简单的文本文件,用来测试Hadoop的功能。你可以使用以下命令: bash echo "Hello, Hadoop!" > test.txt 然后,我们将这个文件上传到HDFS中: bash hadoop fs -put test.txt /user/hadoop/ 这里的/user/hadoop/是HDFS上的一个目录路径。 3.3 查看文件的副本分布 上传完成后,我们可以检查一下这个文件的副本分布情况。使用以下命令: bash hadoop fsck /user/hadoop/test.txt -files -blocks -locations 这段命令会输出类似如下的结果: /user/hadoop/test.txt 128 bytes, 1 block(s): OK 0. BP-123456789-192.168.1.1:50010 file:/path/to/local/file 1. BP-123456789-192.168.1.2:50010 file:/path/to/local/file 2. BP-123456789-192.168.1.3:50010 file:/path/to/local/file 从这里可以看到,我们的文件已经被复制到了三台不同的服务器上。 --- 4. 深度解读 Hadoop的副本策略 在前面的步骤中,我们已经看到了Hadoop是如何将文件复制到不同节点上的。但是,你知道吗?Hadoop的副本策略其实是非常灵活的。它可以根据网络拓扑结构来决定副本的位置。 例如,默认情况下,第一个副本会放在与客户端最近的节点上,第二个副本会放在另一个机架上,而第三个副本则会放在同一个机架的不同节点上。这样的策略可以最大限度地减少网络延迟,提高读取效率。 当然,如果你对默认的副本策略不满意,也可以自己定制。比如,如果你想让所有副本都放在同一个机架内,可以通过修改dfs.replication.policy参数来实现。 --- 5. 总结与展望 通过今天的讨论,我们了解了Hadoop是如何通过HDFS实现文件的跨硬件复制的。虽然这个功能看似简单,但它背后蕴含着复杂的设计理念和技术细节。正是这些设计,才使得Hadoop成为了一个强大的大数据处理工具。 最后,我想说的是,学习新技术的过程就像探险一样,充满了未知和挑战。嘿,谁还没遇到过点麻烦事儿呢?有时候一头雾水,感觉前路茫茫,但这不正是探索的开始嘛!别急着放弃,熬过去你会发现,那些让人头疼的问题其实藏着不少小惊喜,等你拨开云雾时,成就感绝对让你觉得值了!希望这篇文章能给你带来一些启发,也希望你能亲自尝试一下Hadoop的实际操作,感受一下它的魅力! 好了,今天的分享就到这里啦!如果你有任何疑问或者想法,欢迎随时留言交流。让我们一起探索更多有趣的技术吧!
2025-03-26 16:15:40
98
冬日暖阳
转载文章
...是有这么多标志位怎么计算而来的呢?它是由标志位为true的标志位值取或运算而来,比如这里我演示的class文件是一个类并且是public的,所以对应的ACC_PUBLIC和ACC_SIPER标志应该置为true,其余标志不满足则为false,那么access_flags的计算过程就是:Ox0001 | Ox0020 = Ox0021 篇幅原因,未完待续...... 参考文献:《深入理解Java虚拟机》 END 本篇文章为转载内容。原文链接:https://javar.blog.csdn.net/article/details/97532925。 该文由互联网用户投稿提供,文中观点代表作者本人意见,并不代表本站的立场。 作为信息平台,本站仅提供文章转载服务,并不拥有其所有权,也不对文章内容的真实性、准确性和合法性承担责任。 如发现本文存在侵权、违法、违规或事实不符的情况,请及时联系我们,我们将第一时间进行核实并删除相应内容。
2024-01-09 17:46:36
646
转载
Mahout
...据这事儿。它那分发式计算的能力啊,就像魔法一样,能让你的数据处理起来轻松又高效。用Mahout做分析,就像是给一堆乱糟糟的数据整了套华丽丽的整理术,让它们变得井井有条,还能从中找出各种有价值的信息和模式。这玩意儿一出手,数据处理界的难题就被它玩转得飞起,简直是个大数据时代的超级英雄呢!而Apache Spark Streaming,则是为实时数据流提供高性能处理的框架。哎呀,兄弟!把这两样技术给整到一块儿用,那效果简直不要太棒!不仅能快速消化那些源源不断的数据洪流,还能帮咱们做出超明智的决定,简直就是开挂的存在嘛!本文旨在探索Mahout与Spark Streaming如何协同工作,为实时流数据分析提供强大的解决方案。 2. Mahout概述 Mahout是一个基于Hadoop的机器学习库,旨在利用分布式计算资源来加速大规模数据集上的算法执行。哎呀,这个家伙可真厉害!它能用上各种各样的机器学习魔法,比如说分门别类的技巧(就是咱们说的分类)、把相似的东西归到一块儿的本事(聚类)还有能给咱们推荐超棒东西的神奇技能(推荐系统)。而且,它最擅长的就是对付那些海量的数据,就像大鱼吃小鱼一样,毫不费力就能搞定!通过Mahout,我们可以构建复杂的模型来挖掘数据中的模式和关系,从而驱动业务决策。 3. Spark Streaming简介 Apache Spark Streaming是Spark生态系统的一部分,专为实时数据流处理设计。哎呀,这个玩意儿简直就是程序员们的超级神器!它能让咱这些码农兄弟们轻松搞定那些超快速、高效率的实时应用,你懂的,就是那种分秒必争、数据飞速流转的那种。想象一下,一秒钟能处理几千条数据,那感觉简直不要太爽啊!就像是在玩转数据的魔法世界,每一次点击都是对速度与精准的极致追求。这不就是我们程序员的梦想吗?在数据的海洋里自由翱翔,每一刻都在创造奇迹!Spark Streaming的精髓就像个魔术师,能把连续不断的水流(数据流)变换成小段的小溪(微批次)。这小溪再通过Spark这个强大的分布式计算平台,就像是在魔法森林里跑的水车,一边转一边把水(数据)处理得干干净净。这样一来,咱们就能在实时中捕捉到信息的脉动,做出快速反应,既高效又灵活! 4. Mahout与Spark Streaming的集成 为了将Mahout的机器学习能力与Spark Streaming的实时处理能力结合起来,我们需要创建一个流水线,使得Mahout可以在实时数据流上执行分析任务。这可以通过以下步骤实现: - 数据接入:首先,我们需要将实时数据流接入Spark Streaming。这可以通过定义一个DStream(Data Stream)对象来完成,该对象代表了数据流的抽象表示。 scala import org.apache.spark.streaming._ import org.apache.spark.streaming.dstream._ val sparkConf = new SparkConf().setAppName("RealtimeMahoutAnalysis").setMaster("local[2]") val sc = new SparkContext(sparkConf) valssc = new StreamingContext(sc, Seconds(1)) // 创建StreamingContext,时间间隔为1秒 val inputStream = TextFileStream("/path/to/your/data") // 假设数据来自文件系统 val dstream = inputStream foreachRDD { rdd => rdd.map { line => val fields = line.split(",") (fields(0), fields.slice(1, fields.length)) } } - Mahout模型训练:然后,我们可以使用Mahout中的算法对数据进行预处理和建模。例如,假设我们想要进行用户行为的聚类分析,可以使用Mahout的KMeans算法。 scala import org.apache.mahout.cf.taste.hadoop.recommender.KNNRecommender import org.apache.mahout.cf.taste.impl.model.file.FileDataModel import org.apache.mahout.cf.taste.impl.neighborhood.ThresholdUserNeighborhood import org.apache.mahout.cf.taste.impl.recommender.GenericUserBasedRecommender import org.apache.mahout.cf.taste.impl.similarity.PearsonCorrelationSimilarity import org.apache.mahout.math.RandomAccessSparseVector import org.apache.hadoop.conf.Configuration val dataModel = new FileDataModel(new File("/path/to/your/data.csv")) val neighborhood = new ThresholdUserNeighborhood(0.5, dataModel, new Configuration()) val similarity = new PearsonCorrelationSimilarity(dataModel) val recommender = new GenericUserBasedRecommender(dataModel, neighborhood, similarity) val recommendations = dstream.map { (user, ratings) => val userVector = new RandomAccessSparseVector(ratings.size()) for ((itemId, rating) <- ratings) { userVector.setField(itemId.toInt, rating.toDouble) } val recommendation = recommender.recommend(user, userVector) (user, recommendation.map { (itemId, score) => (itemId, score) }) } - 结果输出:最后,我们可以将生成的推荐结果输出到合适的目标位置,如日志文件或数据库,以便后续分析和应用。 scala recommendations.foreachRDD { rdd => rdd.saveAsTextFile("/path/to/output") } 5. 总结与展望 通过将Mahout与Spark Streaming集成,我们能够构建一个强大的实时流数据分析平台,不仅能够实时处理大量数据,还能利用Mahout的高级机器学习功能进行深入分析。哎呀,这个融合啊,就像是给数据分析插上了翅膀,能即刻飞到你眼前,又准确得不得了!这样一来,咱们做决定的时候,心里那根弦就更紧了,因为有它在身后撑腰,决策那可是又稳又准,妥妥的!哎呀,随着科技车轮滚滚向前,咱们的Mahout和Spark Streaming这对好搭档,未来肯定会越来越默契,联手为我们做决策时,用上实时数据这个大宝贝,提供更牛逼哄哄的武器和方法!想象一下,就像你用一把锋利的剑,能更快更准地砍下胜利的果实,这俩家伙在数据战场上,就是那把超级厉害的宝剑,让你的决策快人一步,精准无比! --- 以上内容是基于实际的编程实践和理论知识的融合,旨在提供一个从概念到实现的全面指南。哎呀,当真要将这个系统或者项目实际铺展开来的时候,咱们得根据手头的实际情况,比如数据的个性、业务的流程和咱们的技术底子,来灵活地调整策略,让一切都能无缝对接,发挥出最大的效用。就像是做菜,得看食材的新鲜度,再搭配合适的调料,才能做出让人满意的美味佳肴一样。所以,别死板地照搬方案,得因地制宜,因材施教,这样才能确保我们的工作既高效又有效。
2024-09-06 16:26:39
60
月影清风
转载文章
...诉 Libnids要计算校验和 / define NIDS_DONT_CHKSUM 1 / 表示告诉 Libnids不要计算校验和 / struct tuple4 / 描述一个地址端口对 , 它表示发送发IP 和端口以及接收方 IP 和端口 , 适用 TCP,UDP/ { u_short source; / 源 IP 地址的端口号/ u_short dest; / 目的 IP 地址的端口号/ u_int saddr; / 源 IP 地址 / u_int daddr; / 目的 IP 地址 / }; struct half_stream / 描述在 TCP 连接中一端的所有信息, 可以是客户端 , 也可以是服务端 / { char state; / 表示套接字的状态 , 也就是TCP 的状态 / char collect; / 可以表示有数据到达 , 此数据存放在data 成员中 , 也可以表示不存储此数据到 data中 , 此数据忽略 . 如果大于0 就存储 , 否则就忽略 / char collect_urg; / 可以表示有紧急数据到达 , 此数据就存放在urgdata 中 , 也可以表示不存储此数据到 urgdata中 , 此速数据忽略 . 如果大于0 就存储 , 否则就忽略 / char data; / 用户存储正常接受到的数据 / int offset; / 表示存储在 data 中数据的第一个字节的偏移量/ int count; / 表示从 TCP 连接开始已经存储到data 中的数据的字节数 / int count_new; / 有多少新的数据存储到 data 中, 如果为 0, 则表示没有新的数据到达 / int bufsize; int rmem_alloc; int urg_count; / 用来存储紧急数据 / u_int acked; u_int seq; u_int ack_seq; u_int first_data_seq; u_char urgdata; //存储紧急数据 u_char count_new_urg; / 表示有新的紧急数据到达 , 如果为0 表示没有新的紧急数据 / u_char urg_seen; //新的urg数据,不是以前重复的数据 u_int urg_ptr;/指向urg在流中的位置/ u_short window; u_char ts_on; u_char wscale_on; u_int curr_ts; u_int wscale; struct skbuff list; struct skbuff listtail; }; struct tcp_stream / 描述一个 TCP 连接的所有信息/ { struct tuple4 addr; char nids_state; struct lurker_node listeners; struct half_stream client; / 表示客户端信息 / struct half_stream server; / 表示服务端信息 / struct tcp_stream next_node; struct tcp_stream prev_node; int hash_index; struct tcp_stream next_time; struct tcp_stream prev_time; int read; struct tcp_stream next_free; }; struct nids_prm / 描述了 Libnids 的一些全局参数信息/ { int n_tcp_streams; / 表示哈西表大小 , 此哈西表用来存放tcp_stream 数据结构 , 默认值 1040.在同一时刻 Libnids 捕获的 TCP 数据包的最大个数必须是此参数值的3/4/ int n_hosts; / 表示哈西表的大小 , 此哈西表用来存储IP 碎片信息的 , 默认值为 256/ char device; / 表示网络接口 ,Libnids 将在此网络接口上捕获数据, 默认值为 NULL. 这样 Libnids将使用 pcap_lookupdev来查找可以用的网络接口 . 如果其值为 all, 表示捕获所有网络接口的数据/ char filename; / 表示用来存储网络数据的捕获文件 , 此文件的类型必须与 Libpcap 类型一致 , 如果设置了文件, 与此同时就应该设置 device 为 NULL,默认值为 NULL/ int sk_buff_size; / 表示的是数据接口 sk_buff 的大小 .sk_buff 是Linux 内核中一个重要的数据结构, 是用来进行数据包排队操作的 , 默认值为 168/ int dev_addon; / 表示在数据结构 sk_buff 中用于网络接口上信息的字节数. 如果是 -1( 默认值 ),那么 Libnids 会根据不同的网络接口进行修正 / void (syslog) (); / 是一个函数指针 , 默认值为nids_syslog() 函数 . 在 syslog函数中可以检测入侵攻击 , 如网络扫描攻击 , 也可以检测一些异常情况, 如无效 TCP 标记 / int syslog_level; / 表示日志等级 , 默认值是LOG_ALERT/ int scan_num_hosts; / 表示一个哈西表的大小 ,( 此哈西表用来存储端口扫描信息) 表示 Libnids 将要检测的同时扫描的端口数据 . 如果其值为 0,Libnids将不提供端口扫描功能 . 默认值 256/ int scan_delay; / 表示在扫描检测中 , 俩端口扫描的间隔时间, 以毫秒来计算 , 缺省值为 3000/ int scan_num_ports; / 表示相同源地址必须扫描的 TCP 端口数目 , 默认值为10/ void (no_mem) (char ); / 是一个函数指针 , 当Libnids 发生内存溢出时被调用/ int (ip_filter) (); / 是一个函数指针 , 此函数可以用来分析IP 数据包 , 当有 IP 数据包到达时 , 此函数就被调用. 如果此函数返回非零值 , 此数据包就被处理 ;如果返回零 , 此 IP 数据包就被丢弃. 默认值为 nids_ip_filter 函数 , 总是返回 1./ char pcap_filter; / 表示过滤规则 , 即Libpcap 的过滤规则 , 默认值为 NULL,表示捕获所有数据包 . 可以在此设置过滤规则 , 只捕获感兴趣的开发包/ int promisc; / 表示网卡模式 , 如果是非零, 就把此网卡设置为混杂模式 ; 否则 , 设为非混杂模式 . 默认值为1/ int one_loop_less; / 初始值为 0/ int pcap_timeout; / 表示捕获数据返回的时间 , 以毫秒计算. 实际上它表示的就是 Libpcap 函数中的 pcap_open_live函数的 timeout 参数 , 默认值 1024/ }; / 返回值 : 调用成功返回 1,失败返回 0 参 数 : 无 功 能 : 对 Libnids 初始化, 这是所有设计基于 Libnids 的程序最开始调用的函数 . 它的主要内容包括打开网络接口 , 打开文件 , 编译过滤规则 , 判断网络链路层类型, 进行必要的初始化工作 / int nids_init (void); / 返回值 : 无 参 数 : 回调函数名字 功 能 : 注册一个能够检测所有 IP 数据包的回调函数, 包括 IP 碎片 .e.g nids_register_ip_frag(ip_frag_function); void ip_frag_function(struct ip a_packet,int len) a_packet 表示接收的IP 数据包 len 表示接收的数据包长度 此回调函数可以检测所有的IP 数据包 , 包括 IP 碎片 / void nids_register_ip_frag (void ()); // / 返回值 : 无 参 数 : 回调函数名字 功 能 : 注册一个回调函数 , 此回调函数可以接收正常的IP 数据包 .e.g nids_register_ip_frag(ip_frag_function); void ip_frag_function(struct ip a_packet) a_packet 表示接收的IP 数据包 此回调函数可以接收正常的IP 数据包 , 并在此函数中对捕获数到的 IP数据包进行分析 . / void nids_register_ip (void ()); // / 返回值 : 无 参 数 : 回调函数 功 能 : 注册一个 TCP 连接的回调函数. 回调函数的类型定义如下 : void tcp_callback(struct tcp_stream ns,void param) ns 表示一个TCP 连接的所有信息 , param 表示要传递的参数信息 , 可以指向一个 TCP连接的私有数据 此回调函数接收的TCP 数据存放在 half_stream 的缓存中 , 应该马上取出来 ,一旦此回调函数返回 , 此数据缓存中存储的数据就不存在 了 .half_stream 成员 offset描述了被丢弃的数据字节数 . 如果不想马上取出来 , 而是等到存储一定数量的数据之后再取出来, 那么可 以使用函数nids_discard(struct tcp_stream ns, int num_bytes)来处理 . 这样回调函数返回时 ,Libnids 将丢弃缓存数据之前 的 num_bytes 字节的数据 .如果不调用 nids_discard()函数 , 那么缓存数据的字节应该为 count_new 字节 . 一般情况下, 缓存中的数据 应该是count-offset 字节 / void nids_register_tcp (void ()); / 返回值 : 无 参 数 : 回调函数 功 能 : 注册一个分析 UDP 协议的回调函数, 回调函数的类型定义如下 : void udp_callback(struct tuple4 addr,char buf,int len,struct ip iph) addr 表示地址端口信息buf 表示 UDP 协议负载的数据内容 len表是 UDP 负载数据的长度 iph 表示一个IP 数据包 , 包括 IP 首部 ,UDP 首部以及UDP 负载内容 / void nids_register_udp (void ()); / 返回值 : 无 参 数 : 表示一个 TCP 连接 功 能 : 终止 TCP 连接 . 它实际上是调用 Libnet的函数进行构造数据包 , 然后发送出去 / void nids_killtcp (struct tcp_stream ); / 返回值 : 无 参 数 : 参数 1 一个 TCP 连接 参数 2 个数 功 能 : 丢弃参数 2 字节 TCP 数据 , 用于存储更多的数据 / void nids_discard (struct tcp_stream , int); / 返回值 : 无 参 数 : 无 功 能 : 运行 Libnids, 进入循环捕获数据包状态. 它实际上是调用 Libpcap 函数 pcap_loop()来循环捕获数据包 / void nids_run (void); / 返回值 : 调用成功返回文件描述符 ,失败返回 -1 参 数 : 无 功 能 : 获得文件描述符号 / int nids_getfd (void); / 返回值 : 调用成功返回个数 ,失败返回负数 参 数 : 表示捕获数据包的个数 功 能 : 调用 Libpcap 中的捕获数据包函数pcap_dispatch() / int nids_dispatch (int); / 返回值 : 调用成功返回 1,失败返回 0 参 数 : 无 功 能 : 调用 Libpcap 中的捕获数据包函数pcap_next() / int nids_next (void); extern struct nids_prm nids_params; /libnids.c定以了一个全部变量 , 其定义和初始值在 nids_params/ extern char nids_warnings[]; extern char nids_errbuf[]; extern struct pcap_pkthdr nids_last_pcap_header; struct nids_chksum_ctl { / 描述的是计算校验和 , 用于决定是否计算校验和/ u_int netaddr; / 表示地址 / u_int mask; / 表示掩码 / u_int action; / 表示动作 , 如果是NIDS_DO_CHKSUM, 表示计算校验和; 如果是 NIDS_DONT_CHKSUM, 表示不计算校验和 / u_int reserved; / 保留未用 / }; / 返回值 : 无 参 数 : 参数 1 表示 nids_chksum_ctl 列表 参数 2 表示列表中的个数 功 能 : 决定是否计算校验和 . 它是根据数据结构nids_chksum_ctl 中的action 进行决定的 , 如果所要计算的对象不在列表中 , 则必须都要计算校验和 / extern void nids_register_chksum_ctl(struct nids_chksum_ctl , int); endif / _NIDS_NIDS_H / 本篇文章为转载内容。原文链接:https://blog.csdn.net/xieqb/article/details/7681968。 该文由互联网用户投稿提供,文中观点代表作者本人意见,并不代表本站的立场。 作为信息平台,本站仅提供文章转载服务,并不拥有其所有权,也不对文章内容的真实性、准确性和合法性承担责任。 如发现本文存在侵权、违法、违规或事实不符的情况,请及时联系我们,我们将第一时间进行核实并删除相应内容。
2023-02-08 17:36:31
307
转载
Docker
...,可以让你的应用程序及其依赖项打包成一个独立的“容器”,然后轻松地运行在任何支持Docker的环境中。 举个例子吧,假如你想在一个全新的服务器上安装WordPress,传统方法可能是手动下载PHP、MySQL、Nginx等一堆软件,再逐一配置。而如果你用Docker,只需要一条命令就能搞定: bash docker run --name wordpress -d -p 80:80 \ -v /path/to/wordpress:/var/www/html \ -e WORDPRESS_DB_HOST=db \ -e WORDPRESS_DB_USER=root \ -e WORDPRESS_DB_PASSWORD=yourpassword \ wordpress 这段代码的意思是:启动一个名为wordpress的容器,并将本地目录/path/to/wordpress挂载到容器内的/var/www/html路径下,同时设置数据库连接信息。是不是比传统的安装方式简洁多了? 不过,单独使用Docker虽然强大,但对于不熟悉命令行的人来说还是有点门槛。这时候就需要一些辅助工具来帮助我们更好地管理和调度容器了。 --- 3. Portainer 可视化管理Docker的好帮手 Portainer绝对是我最近发现的一颗“宝藏”。它的界面非常直观,几乎不需要学习成本。不管是想看看现有的容器啥情况,还是想启动新的容器,甚至连网络和卷的管理,都只需要动动鼠标拖一拖、点一点就行啦! 比如,如果你想快速创建一个新的MySQL容器,只需要打开Portainer的Web界面,点击“Add Container”,然后填写几个基本信息即可: yaml image: mysql:5.7 name: my-mysql ports: - "3306:3306" volumes: - /data/mysql:/var/lib/mysql environment: MYSQL_ROOT_PASSWORD: rootpassword 这段YAML配置文件描述了一个MySQL容器的基本参数。Portainer会自动帮你解析并生成对应的Docker命令。是不是超方便? 另外,Portainer还有一个特别棒的功能——实时监控。你打开页面就能看到每个“小房子”(就是容器)里用掉的CPU和内存情况,而且还能像穿越空间一样,去访问别的机器上跑着的那些“小房子”(Docker实例)。这种功能对于运维人员来说简直是福音! --- 4. Rancher 企业级的容器编排利器 如果你是一个团队协作的开发者,或者正在运营一个大规模的服务集群,那么Rancher可能是你的最佳选择。它不仅仅是一个Docker管理工具,更是一个完整的容器编排平台。 Rancher的核心优势在于它的“多集群管理”能力。想象一下,你的公司有好几台服务器,分别放在地球上的不同角落,有的在美国,有的在欧洲,还有的在中国。每台服务器上都跑着各种各样的服务,比如网站、数据库啥的。这时候,Rancher就派上用场了!它就像一个超级贴心的小管家,让你不用到处切换界面,在一个地方就能轻松搞定所有服务器和服务的管理工作,省时又省力! 举个例子,如果你想在Rancher中添加一个新的节点,只需要几步操作即可完成: 1. 登录Rancher控制台。 2. 点击“Add Cluster”按钮。 3. 输入目标节点的信息(IP地址、SSH密钥等)。 4. 等待几分钟,Rancher会自动为你安装必要的组件。 一旦节点加入成功,你就可以直接在这个界面上部署应用了。比如,用Kubernetes部署一个Redis集群: bash kubectl create deployment redis --image=redis:alpine kubectl expose deployment redis --type=LoadBalancer --port=6379 虽然这条命令看起来很简单,但它背后实际上涉及到了复杂的调度逻辑和网络配置。而Rancher把这些复杂的事情封装得很好,让我们可以专注于业务本身。 --- 5. Traefik 反向代理与负载均衡的最佳拍档 最后要介绍的是Traefik,这是一个轻量级的反向代理工具,专门用来处理HTTP请求的转发和负载均衡。它最厉害的地方啊,就是能跟Docker完美地融为一体,还能根据容器上的标签,自动调整路由规则呢! 比如说,你有两个服务分别监听在8080和8081端口,现在想通过一个域名访问它们。只需要给这两个容器加上相应的标签: yaml labels: - "traefik.enable=true" - "traefik.http.routers.service1.rule=Host(service1.example.com)" - "traefik.http.services.service1.loadbalancer.server.port=8080" - "traefik.http.routers.service2.rule=Host(service2.example.com)" - "traefik.http.services.service2.loadbalancer.server.port=8081" 这样一来,当用户访问service1.example.com时,Traefik会自动将请求转发到监听8080端口的容器;而访问service2.example.com则会指向8081端口。这种方式不仅高效,还极大地减少了配置的工作量。 --- 6. 总结 找到最适合自己的工具 好了,到这里咱们已经聊了不少关于服务器管理工具的话题。从Docker到Portainer,再到Rancher和Traefik,每一种工具都有其独特的优势和适用场景。 我的建议是,先根据自己的需求确定重点。要是你只想弄个小玩意儿,图个省事儿快点搞起来,那用Docker配个Portainer就完全够用了。但要是你们团队一起干活儿,或者要做大范围的部署,那Rancher这种专业的“老司机工具”就得安排上啦! 当然啦,技术的世界永远没有绝对的答案。其实啊,很多时候你会发现,最适合你的工具不一定是最火的那个,而是那个最合你心意、用起来最顺手的。就像穿鞋一样,别人觉得好看的根本不合脚,而那双不起眼的小众款却让你走得又稳又舒服!所以啊,在用这些工具的时候,别光顾着看,得多动手试试,边用边记下自己的感受和想法,这样你才能真的搞懂它们到底有啥门道! 好了,今天的分享就到这里啦!如果你还有什么问题或者想法,欢迎随时留言交流哦~咱们下次再见啦!
2025-04-16 16:05:13
98
月影清风_
Hadoop
近年来,随着云计算和大数据技术的快速发展,数据安全与隐私保护成为全球关注的焦点。特别是在跨境数据流动日益频繁的背景下,如何确保数据在不同系统间的高效迁移同时兼顾安全性,已经成为企业和政府必须面对的重大课题。就在上周,欧盟委员会发布了一份关于加强数据跨境传输监管的新提案,旨在强化GDPR(《通用数据保护条例》)的执行力度,尤其是针对云服务提供商的跨境数据处理活动提出了更为严格的审查标准。这一举措无疑将对依赖Hadoop等分布式系统的企业带来深远影响,尤其是在涉及跨国业务的数据处理环节中,如何平衡技术创新与法律合规将成为新的挑战。 与此同时,国内也在加速推进数据安全立法进程。近日,中国信通院发布了《中国数字经济发展白皮书》,其中特别提到,在数字经济快速发展的背景下,数据要素市场化配置改革亟需解决的关键问题之一便是如何构建统一的数据流通体系。报告建议,应加快制定和完善数据分级分类管理制度,鼓励采用先进的技术手段如区块链、联邦学习等,以提升数据流动的安全性和透明度。这表明,无论是在国际还是国内层面,围绕数据安全的技术创新与政策规范都呈现出同步加强的趋势。 值得注意的是,尽管Hadoop因其强大的分布式计算能力在全球范围内得到了广泛应用,但其在实际部署过程中仍面临诸多挑战,例如如何在满足业务需求的同时避免因权限配置不当而导致的数据泄露风险。对此,专家指出,企业应当加强对员工的数据安全意识培训,同时积极引入第三方审计机制,定期评估系统内的访问控制策略是否符合最新的行业标准。此外,随着量子计算等新兴技术的发展,未来的数据加密方案也需要重新审视,以应对潜在的安全威胁。 综上所述,无论是国际法规的变化还是国内政策的调整,都在推动数据安全领域发生深刻变革。对于那些希望借助Hadoop等工具实现高效数据迁移的企业而言,只有紧跟时代步伐,不断优化自身的数据管理体系,才能在未来竞争中立于不败之地。
2025-04-29 15:54:59
80
风轻云淡
ZooKeeper
近期,随着云计算和微服务架构的普及,越来越多的企业开始依赖ZooKeeper这类分布式协调工具来保障系统的稳定性和一致性。然而,正如文章所提到的,CommitQueueFullException仍然是许多开发者头疼的问题。最近,阿里云发布的开源项目“SOFARegistry”引起了广泛关注,这是一个基于ZooKeeper的高性能注册中心,旨在解决大规模分布式系统中的服务发现和配置管理问题。SOFARegistry通过对ZooKeeper的深度优化,大幅提升了请求处理能力,降低了CommitQueueFullException的发生概率。例如,在某电商平台的双11活动中,使用SOFARegistry后,服务调用成功率提升了近30%,同时降低了约40%的系统资源消耗。此外,腾讯云也推出了类似的解决方案,其推出的TSeer组件同样基于ZooKeeper,专注于提供低延迟的服务发现和负载均衡能力。这些新技术的出现,不仅为企业提供了更多选择,也为ZooKeeper的未来发展注入了新活力。值得注意的是,尽管这些优化方案效果显著,但在实际应用中仍需结合自身业务特点进行定制化调整。例如,某些企业可能需要进一步增强SOFARegistry的容错能力,而另一些企业则可能需要TSeer提供的更细粒度的流量控制功能。总之,随着分布式系统规模的不断扩大,如何高效利用现有工具并持续创新将成为未来发展的关键。希望这些前沿技术和最佳实践能为读者带来启发,助力企业在数字化转型中抢占先机。
2025-03-16 15:37:44
11
林中小径
转载文章
...毕后再执行JS代码 效果 第二阶段:鼠标选中后,闪烁 只有JavaScript需要修改 var table; //游戏桌面var squareWidth = 50; //方块宽高var boardWidth = 10; //行列数var squareSet = []; //方块信息集合(二维数组)每个元素保存该方块的全部信息var baseScore = 5; //第一块的分数var stepScore = 10; //每多一块的累加分数var totalScore = 0; //当前总分var targetScore = 1500; //目标分var choose = []; //选中的连通小方块var timer = null; //闪烁定时器var flag = true; //锁,防止点击事件中响应其他点击或移入时间var tempSquare = null; //临时方块function refresh(){for (var i = 0; i < squareSet.length; i++) {for (var j = 0; j < squareSet[i].length; j++) {squareSet[i][j].style.background="url(pic/"+squareSet[i][j].num+".png)"squareSet[i][j].style.left=squareSet[i][j].colsquareWidth+"px";squareSet[i][j].style.bottom=squareSet[i][j].rowsquareWidth+"px";} }}function createSquare(value,row,col){ //创建小方块,传入参数为颜色、行、列,初始化时使用。var temp = document.createElement('div'); //创建div dom对象temp.style.height = squareWidth + "px";temp.style.width = squareWidth + "px";temp.style.position = "absolute"; //相对于背景绝对定位temp.num = value;temp.col = col;temp.row = row;return temp; //返回这个创建出来的对象}function goBack(){ //还原样式if(timer != null){ //清空计时器clearInterval(timer);}for(var i = 0 ; i < squareSet.length ; i ++){for(var j = 0 ; j < squareSet[i].length ; j ++){squareSet[i][j].style.border = "0px solid white";squareSet[i][j].style.transform = "scale(0.95)";} }}function checkLinked(square , arr){ // 递归连通图算法arr.push(square); // 将当前方块放入选中数组中// check leftif( square.col > 0 && //未到边界squareSet[square.row][square.col - 1].num == square.num && //颜色相同arr.indexOf(squareSet[square.row][square.col - 1]) == -1) { //不在choose中,避免循环判断checkLinked(squareSet[square.row][square.col - 1] , arr);}// check rightif( square.col < boardWidth - 1 &&squareSet[square.row][square.col + 1].num == square.num &&arr.indexOf(squareSet[square.row][square.col + 1]) == -1) {checkLinked(squareSet[square.row][square.col + 1] , arr);}// check upif( square.row < boardWidth - 1 &&squareSet[square.row + 1][square.col].num == square.num &&arr.indexOf(squareSet[square.row + 1][square.col]) == -1) {checkLinked(squareSet[square.row + 1][square.col] , arr);}// check downif( square.row > 0 &&squareSet[square.row - 1][square.col].num == square.num &&arr.indexOf(squareSet[square.row - 1][square.col]) == -1) {checkLinked(squareSet[square.row - 1][square.col] , arr);} }function flicker(arr){ // 选中连通的小方块可以闪烁var num = 0;timer = setInterval(function(){for(var i = 0 ; i < arr.length ; i ++){arr[i].style.border = "3px solid BFEFFF";//有个框arr[i].style.transform = "scale(" + (0.9 + (0.05 Math.pow(-1 , num))) + ")";//一闪一闪}num ++; // 注意这里所采用的数学技巧,仍然使用transform:scale(val)来进行缩放。},300);//闪烁的时间}function mouseOver(obj){ //鼠标移入区域响应// 还原所有样式goBack();// 检查相邻choose = [];checkLinked(obj , choose);// 闪烁flicker(choose);// 显示分数selectScore();}function init(){ // JS调用入口table = document.getElementById('pop_star'); // 获取到最外层的父元素作为桌面document.getElementById('targetScore').innerHTML = "Target Score : " + targetScore; //显示目标分数用innerHTML// 循环初始化星星区域for(var i = 0 ; i < boardWidth ; i ++){squareSet[i] = new Array(); //二维数组的创建,对每一个元素new Array()创建新数组for(var j = 0 ; j < boardWidth ; j ++){var square = createSquare(Math.floor(Math.random() 5) , i , j);// 鼠标移入事件square.onmouseover = function(){mouseOver(this);}squareSet[i][j] = square; //必须将新创建的方块放回到数组中table.appendChild(square); //需要将创建的新元素添加到桌面上} }refresh(); //每次页面内容发生变化需要重绘页面}window.onload = function(){init();} // window.onload 保证了在页面全部加载完毕后再执行JS代码 效果2.1 加入这段代码,便会计算闪烁方块得分 function selectScore(){ //可以显示当前选中小方块的得分var score = 0;for(var i = 0 ; i < choose.length ; i ++){score += (baseScore + i stepScore);}document.getElementById('selectScore').innerHTML = choose.length + " blocks " + score + " points";document.getElementById('selectScore').style.opacity = 1;// 设置时间间隔1秒后显示消失的过渡动画setTimeout(function(){document.getElementById('selectScore').style.opacity = 0;document.getElementById('selectScore').style.transition = "opacity 1s";},1000);} 完整代码为: var table; //游戏桌面var squareWidth = 50; //方块宽高var boardWidth = 10; //行列数var squareSet = []; //方块信息集合(二维数组)每个元素保存该方块的全部信息var baseScore = 5; //第一块的分数var stepScore = 10; //每多一块的累加分数var totalScore = 0; //当前总分var targetScore = 1500; //目标分var choose = []; //选中的连通小方块var timer = null; //闪烁定时器var flag = true; //锁,防止点击事件中响应其他点击或移入时间var tempSquare = null; //临时方块function refresh(){for (var i = 0; i < squareSet.length; i++) {for (var j = 0; j < squareSet[i].length; j++) {squareSet[i][j].style.background="url(pic/"+squareSet[i][j].num+".png)"squareSet[i][j].style.left=squareSet[i][j].colsquareWidth+"px";squareSet[i][j].style.bottom=squareSet[i][j].rowsquareWidth+"px";} }}function createSquare(value,row,col){ //创建小方块,传入参数为颜色、行、列,初始化时使用。var temp = document.createElement('div'); //创建div dom对象temp.style.height = squareWidth + "px";temp.style.width = squareWidth + "px";temp.style.position = "absolute"; //相对于背景绝对定位temp.num = value;temp.col = col;temp.row = row;return temp; //返回这个创建出来的对象}function goBack(){ //还原样式if(timer != null){ //清空计时器clearInterval(timer);}for(var i = 0 ; i < squareSet.length ; i ++){for(var j = 0 ; j < squareSet[i].length ; j ++){squareSet[i][j].style.border = "0px solid white";squareSet[i][j].style.transform = "scale(0.95)";} }}function checkLinked(square , arr){ // 递归连通图算法arr.push(square); // 将当前方块放入选中数组中// check leftif( square.col > 0 && //未到边界squareSet[square.row][square.col - 1].num == square.num && //颜色相同arr.indexOf(squareSet[square.row][square.col - 1]) == -1) { //不在choose中,避免循环判断checkLinked(squareSet[square.row][square.col - 1] , arr);}// check rightif( square.col < boardWidth - 1 &&squareSet[square.row][square.col + 1].num == square.num &&arr.indexOf(squareSet[square.row][square.col + 1]) == -1) {checkLinked(squareSet[square.row][square.col + 1] , arr);}// check upif( square.row < boardWidth - 1 &&squareSet[square.row + 1][square.col].num == square.num &&arr.indexOf(squareSet[square.row + 1][square.col]) == -1) {checkLinked(squareSet[square.row + 1][square.col] , arr);}// check downif( square.row > 0 &&squareSet[square.row - 1][square.col].num == square.num &&arr.indexOf(squareSet[square.row - 1][square.col]) == -1) {checkLinked(squareSet[square.row - 1][square.col] , arr);} }function flicker(arr){ // 选中连通的小方块可以闪烁var num = 0;timer = setInterval(function(){for(var i = 0 ; i < arr.length ; i ++){arr[i].style.border = "3px solid BFEFFF";//有个框arr[i].style.transform = "scale(" + (0.9 + (0.05 Math.pow(-1 , num))) + ")";//一闪一闪}num ++; // 注意这里所采用的数学技巧,仍然使用transform:scale(val)来进行缩放。},300);//闪烁的时间}function selectScore(){ //可以显示当前选中小方块的得分var score = 0;for(var i = 0 ; i < choose.length ; i ++){score += (baseScore + i stepScore);}document.getElementById('selectScore').innerHTML = choose.length + " blocks " + score + " points";document.getElementById('selectScore').style.opacity = 1;// 设置时间间隔1秒后显示消失的过渡动画setTimeout(function(){document.getElementById('selectScore').style.opacity = 0;document.getElementById('selectScore').style.transition = "opacity 1s";},1000);}function mouseOver(obj){ //鼠标移入区域响应// 还原所有样式goBack();// 检查相邻choose = [];checkLinked(obj , choose);// 闪烁flicker(choose);// 显示分数selectScore();}function init(){ // JS调用入口table = document.getElementById('pop_star'); // 获取到最外层的父元素作为桌面document.getElementById('targetScore').innerHTML = "Target Score : " + targetScore; //显示目标分数用innerHTML// 循环初始化星星区域for(var i = 0 ; i < boardWidth ; i ++){squareSet[i] = new Array(); //二维数组的创建,对每一个元素new Array()创建新数组for(var j = 0 ; j < boardWidth ; j ++){var square = createSquare(Math.floor(Math.random() 5) , i , j);// 鼠标移入事件square.onmouseover = function(){mouseOver(this);}squareSet[i][j] = square; //必须将新创建的方块放回到数组中table.appendChild(square); //需要将创建的新元素添加到桌面上} }refresh(); //每次页面内容发生变化需要重绘页面}window.onload = function(){init();} // window.onload 保证了在页面全部加载完毕后再执行JS代码 效果2.2 第三阶段:消灭星星(只消灭一次) 只消除选中的星星,但是不会掉下来。 在function init(){}里面添加以下代码: // 鼠标点击事件square.onclick = function(){//为移除增加一个延迟动画,为了防止闭包,这里采用立即执行函数for(var i = 0 ; i < choose.length ; i ++){(function(i){setTimeout(function(){squareSet[choose[i].row][choose[i].col] = null; //为状态数组置空table.removeChild(choose[i]); //将其从桌面上移除} , i 100);})(i);} } 效果 使得星星移动(原作者这里出现错误) function move(){//纵向下落,采用快慢指针算法for(var i = 0 ; i < boardWidth ; i ++){var pointer = 0; //慢指针for(var j = 0 ; j < boardWidth ; j ++){if(squareSet[j][i] != null){ //按行遍历if(pointer != j){ //快慢指针不同步说明中间有空元素squareSet[pointer][i] = squareSet[j][i]; //慢指针设成快指针元素squareSet[j][i].row = pointer;squareSet[j][i] = null; //快指针处置空}pointer ++; //该行非空时慢指针增加} }} 完整代码如下: var table; //游戏桌面var squareWidth = 50; //方块宽高var boardWidth = 10; //行列数var squareSet = []; //方块信息集合(二维数组)每个元素保存该方块的全部信息var baseScore = 5; //第一块的分数var stepScore = 10; //每多一块的累加分数var totalScore = 0; //当前总分var targetScore = 1500; //目标分var choose = []; //选中的连通小方块var timer = null; //闪烁定时器var flag = true; //锁,防止点击事件中响应其他点击或移入时间var tempSquare = null; //临时方块function refresh(){for (var i = 0; i < squareSet.length; i++) {for (var j = 0; j < squareSet[i].length; j++) {squareSet[i][j].style.background="url(pic/"+squareSet[i][j].num+".png)"squareSet[i][j].style.left=squareSet[i][j].colsquareWidth+"px";squareSet[i][j].style.bottom=squareSet[i][j].rowsquareWidth+"px";} }}function createSquare(value,row,col){ //创建小方块,传入参数为颜色、行、列,初始化时使用。var temp = document.createElement('div'); //创建div dom对象temp.style.height = squareWidth + "px";temp.style.width = squareWidth + "px";temp.style.position = "absolute"; //相对于背景绝对定位temp.num = value;temp.col = col;temp.row = row;return temp; //返回这个创建出来的对象}function goBack(){ //还原样式if(timer != null){ //清空计时器clearInterval(timer);}for(var i = 0 ; i < squareSet.length ; i ++){for(var j = 0 ; j < squareSet[i].length ; j ++){squareSet[i][j].style.border = "0px solid white";squareSet[i][j].style.transform = "scale(0.95)";} }}function checkLinked(square , arr){ // 递归连通图算法arr.push(square); // 将当前方块放入选中数组中// check leftif( square.col > 0 && //未到边界squareSet[square.row][square.col - 1].num == square.num && //颜色相同arr.indexOf(squareSet[square.row][square.col - 1]) == -1) { //不在choose中,避免循环判断checkLinked(squareSet[square.row][square.col - 1] , arr);}// check rightif( square.col < boardWidth - 1 &&squareSet[square.row][square.col + 1].num == square.num &&arr.indexOf(squareSet[square.row][square.col + 1]) == -1) {checkLinked(squareSet[square.row][square.col + 1] , arr);}// check upif( square.row < boardWidth - 1 &&squareSet[square.row + 1][square.col].num == square.num &&arr.indexOf(squareSet[square.row + 1][square.col]) == -1) {checkLinked(squareSet[square.row + 1][square.col] , arr);}// check downif( square.row > 0 &&squareSet[square.row - 1][square.col].num == square.num &&arr.indexOf(squareSet[square.row - 1][square.col]) == -1) {checkLinked(squareSet[square.row - 1][square.col] , arr);} }function flicker(arr){ // 选中连通的小方块可以闪烁var num = 0;timer = setInterval(function(){for(var i = 0 ; i < arr.length ; i ++){arr[i].style.border = "3px solid BFEFFF";//有个框arr[i].style.transform = "scale(" + (0.9 + (0.05 Math.pow(-1 , num))) + ")";//一闪一闪}num ++; // 注意这里所采用的数学技巧,仍然使用transform:scale(val)来进行缩放。},300);//闪烁的时间}function selectScore(){ //可以显示当前选中小方块的得分var score = 0;for(var i = 0 ; i < choose.length ; i ++){score += (baseScore + i stepScore);}document.getElementById('selectScore').innerHTML = choose.length + " blocks " + score + " points";document.getElementById('selectScore').style.opacity = 1;// 设置时间间隔1秒后显示消失的过渡动画setTimeout(function(){document.getElementById('selectScore').style.opacity = 0;document.getElementById('selectScore').style.transition = "opacity 1s";},1000);}function mouseOver(obj){ //鼠标移入区域响应// 还原所有样式goBack();// 检查相邻choose = [];checkLinked(obj , choose);// 闪烁flicker(choose);// 显示分数selectScore();}function move(){//纵向下落,采用快慢指针算法for(var i = 0 ; i < boardWidth ; i ++){var pointer = 0; //慢指针for(var j = 0 ; j < boardWidth ; j ++){if(squareSet[j][i] != null){ //按行遍历if(pointer != j){ //快慢指针不同步说明中间有空元素squareSet[pointer][i] = squareSet[j][i]; //慢指针设成快指针元素squareSet[j][i].row = pointer;squareSet[j][i] = null; //快指针处置空}pointer ++; //该行非空时慢指针增加} }}// 横向移动(当出现一列为空时)for(var i = 0 ; i < squareSet[0].length ;){ //必须注意循环结束条件的判断if(squareSet[0][i] == null){ //逻辑:只需判断最低层为空,该行则全为空for(var j = 0 ; j < boardWidth ; j ++){squareSet[j].splice(i , 1); //splice删除数组squareSet[j]中从i开始的1个元素}continue;//注意移动后i不应改变了}i ++;}refresh();}function init(){ // JS调用入口table = document.getElementById('pop_star'); // 获取到最外层的父元素作为桌面document.getElementById('targetScore').innerHTML = "Target Score : " + targetScore; //显示目标分数用innerHTML// 循环初始化星星区域for(var i = 0 ; i < boardWidth ; i ++){squareSet[i] = new Array(); //二维数组的创建,对每一个元素new Array()创建新数组for(var j = 0 ; j < boardWidth ; j ++){var square = createSquare(Math.floor(Math.random() 5) , i , j);// 鼠标移入事件square.onmouseover = function(){mouseOver(this);}// 鼠标点击事件square.onclick = function(){//对锁进行控制if(!flag || choose.length == null){return;}flag = false;tempSquare = null;//更新分数var score = 0;for(var i = 0 ; i < choose.length ; i ++){score += (baseScore + i stepScore);}totalScore += score;document.getElementById('nowScore').innerHTML = "Current Score : " + totalScore;//为移除增加一个延迟动画,为了防止闭包,这里采用立即执行函数for(var i = 0 ; i < choose.length ; i ++){(function(i){setTimeout(function(){squareSet[choose[i].row][choose[i].col] = null; //为状态数组置空table.removeChild(choose[i]); //将其从桌面上移除} , i 100);})(i);}//需要等星星消除完毕后再移动,故需增加一个延迟setTimeout(function(){move(); //调用移动函数},choose.length 100);}squareSet[i][j] = square; //必须将新创建的方块放回到数组中table.appendChild(square); //需要将创建的新元素添加到桌面上} }refresh(); //每次页面内容发生变化需要重绘页面}window.onload = function(){init();} // window.onload 保证了在页面全部加载完毕后再执行JS代码 效果(下降成功,但是有点小bug只有部分下降了) 解决方案:只需要在function refresh(){}的双循环里面增加以下代码: if(squareSet[i][j] == null) continue; 完整代码如下: var table; //游戏桌面var squareWidth = 50; //方块宽高var boardWidth = 10; //行列数var squareSet = []; //方块信息集合(二维数组)每个元素保存该方块的全部信息var baseScore = 5; //第一块的分数var stepScore = 10; //每多一块的累加分数var totalScore = 0; //当前总分var targetScore = 1500; //目标分var choose = []; //选中的连通小方块var timer = null; //闪烁定时器var flag = true; //锁,防止点击事件中响应其他点击或移入时间var tempSquare = null; //临时方块function refresh(){for (var i = 0; i < squareSet.length; i++) {for (var j = 0; j < squareSet[i].length; j++) {if(squareSet[i][j] == null) continue; // 点击后数组中可能有空值需要跳过squareSet[i][j].style.background="url(pic/"+squareSet[i][j].num+".png)"squareSet[i][j].style.left=squareSet[i][j].colsquareWidth+"px";squareSet[i][j].style.bottom=squareSet[i][j].rowsquareWidth+"px";} }}function createSquare(value,row,col){ //创建小方块,传入参数为颜色、行、列,初始化时使用。var temp = document.createElement('div'); //创建div dom对象temp.style.height = squareWidth + "px";temp.style.width = squareWidth + "px";temp.style.position = "absolute"; //相对于背景绝对定位temp.num = value;temp.col = col;temp.row = row;return temp; //返回这个创建出来的对象}function goBack(){ //还原样式if(timer != null){ //清空计时器clearInterval(timer);}for(var i = 0 ; i < squareSet.length ; i ++){for(var j = 0 ; j < squareSet[i].length ; j ++){squareSet[i][j].style.border = "0px solid white";squareSet[i][j].style.transform = "scale(0.95)";} }}function checkLinked(square , arr){ // 递归连通图算法arr.push(square); // 将当前方块放入选中数组中// check leftif( square.col > 0 && //未到边界squareSet[square.row][square.col - 1].num == square.num && //颜色相同arr.indexOf(squareSet[square.row][square.col - 1]) == -1) { //不在choose中,避免循环判断checkLinked(squareSet[square.row][square.col - 1] , arr);}// check rightif( square.col < boardWidth - 1 &&squareSet[square.row][square.col + 1].num == square.num &&arr.indexOf(squareSet[square.row][square.col + 1]) == -1) {checkLinked(squareSet[square.row][square.col + 1] , arr);}// check upif( square.row < boardWidth - 1 &&squareSet[square.row + 1][square.col].num == square.num &&arr.indexOf(squareSet[square.row + 1][square.col]) == -1) {checkLinked(squareSet[square.row + 1][square.col] , arr);}// check downif( square.row > 0 &&squareSet[square.row - 1][square.col].num == square.num &&arr.indexOf(squareSet[square.row - 1][square.col]) == -1) {checkLinked(squareSet[square.row - 1][square.col] , arr);} }function flicker(arr){ // 选中连通的小方块可以闪烁var num = 0;timer = setInterval(function(){for(var i = 0 ; i < arr.length ; i ++){arr[i].style.border = "3px solid BFEFFF";//有个框arr[i].style.transform = "scale(" + (0.9 + (0.05 Math.pow(-1 , num))) + ")";//一闪一闪}num ++; // 注意这里所采用的数学技巧,仍然使用transform:scale(val)来进行缩放。},300);//闪烁的时间}function selectScore(){ //可以显示当前选中小方块的得分var score = 0;for(var i = 0 ; i < choose.length ; i ++){score += (baseScore + i stepScore);}document.getElementById('selectScore').innerHTML = choose.length + " blocks " + score + " points";document.getElementById('selectScore').style.opacity = 1;// 设置时间间隔1秒后显示消失的过渡动画setTimeout(function(){document.getElementById('selectScore').style.opacity = 0;document.getElementById('selectScore').style.transition = "opacity 1s";},1000);}function mouseOver(obj){ //鼠标移入区域响应// 还原所有样式goBack();// 检查相邻choose = [];checkLinked(obj , choose);// 闪烁flicker(choose);// 显示分数selectScore();}function move(){//纵向下落,采用快慢指针算法for(var i = 0 ; i < boardWidth ; i ++){var pointer = 0; //慢指针for(var j = 0 ; j < boardWidth ; j ++){if(squareSet[j][i] != null){ //按行遍历if(pointer != j){ //快慢指针不同步说明中间有空元素squareSet[pointer][i] = squareSet[j][i]; //慢指针设成快指针元素squareSet[j][i].row = pointer;squareSet[j][i] = null; //快指针处置空}pointer ++; //该行非空时慢指针增加} }}// 横向移动(当出现一列为空时)for(var i = 0 ; i < squareSet[0].length ;){ //必须注意循环结束条件的判断if(squareSet[0][i] == null){ //逻辑:只需判断最低层为空,该行则全为空for(var j = 0 ; j < boardWidth ; j ++){squareSet[j].splice(i , 1); //splice删除数组squareSet[j]中从i开始的1个元素}continue;//注意移动后i不应改变了}i ++;}refresh();}function init(){ // JS调用入口table = document.getElementById('pop_star'); // 获取到最外层的父元素作为桌面document.getElementById('targetScore').innerHTML = "Target Score : " + targetScore; //显示目标分数用innerHTML// 循环初始化星星区域for(var i = 0 ; i < boardWidth ; i ++){squareSet[i] = new Array(); //二维数组的创建,对每一个元素new Array()创建新数组for(var j = 0 ; j < boardWidth ; j ++){var square = createSquare(Math.floor(Math.random() 5) , i , j);// 鼠标移入事件square.onmouseover = function(){mouseOver(this);}// 鼠标点击事件square.onclick = function(){//对锁进行控制if(!flag || choose.length == null){return;}flag = false;tempSquare = null;//更新分数var score = 0;for(var i = 0 ; i < choose.length ; i ++){score += (baseScore + i stepScore);}totalScore += score;document.getElementById('nowScore').innerHTML = "Current Score : " + totalScore;//为移除增加一个延迟动画,为了防止闭包,这里采用立即执行函数for(var i = 0 ; i < choose.length ; i ++){(function(i){setTimeout(function(){squareSet[choose[i].row][choose[i].col] = null; //为状态数组置空table.removeChild(choose[i]); //将其从桌面上移除} , i 100);})(i);}//需要等星星消除完毕后再移动,故需增加一个延迟setTimeout(function(){move(); //调用移动函数},choose.length 100);}squareSet[i][j] = square; //必须将新创建的方块放回到数组中table.appendChild(square); //需要将创建的新元素添加到桌面上} }refresh(); //每次页面内容发生变化需要重绘页面}window.onload = function(){init();} // window.onload 保证了在页面全部加载完毕后再执行JS代码 第四阶段:消灭全部星星,返回结果 最终完整版代码如下: var table; //游戏桌面var squareWidth = 50; //方块宽高var boardWidth = 10; //行列数var squareSet = []; //方块信息集合(二维数组)每个元素保存该方块的全部信息var baseScore = 5; //第一块的分数var stepScore = 10; //每多一块的累加分数var totalScore = 0; //当前总分var targetScore = 1500; //目标分var choose = []; //选中的连通小方块var timer = null; //闪烁定时器var flag = true; //锁,防止点击事件中响应其他点击或移入时间var tempSquare = null; //临时方块function refresh(){ //重绘画板,每次鼠标点击后刷新for(var i = 0 ; i < squareSet.length ; i ++){for(var j = 0 ; j < squareSet[i].length ; j ++){if(squareSet[i][j] == null) continue; // 点击后数组中可能有空值需要跳过squareSet[i][j].row = i; //更新当前的行列数squareSet[i][j].col = j;squareSet[i][j].style.backgroundImage = "url(./pic/" + squareSet[i][j].num + ".png)"squareSet[i][j].style.backgroundSize = "cover"; //占满范围squareSet[i][j].style.transform = "scale(0.95)"; //美观效果让不同星星之间留出空隙(缩小至0.95倍大小)squareSet[i][j].style.left = squareSet[i][j].col squareWidth + "px"; // 别忘了加"px"squareSet[i][j].style.bottom = squareSet[i][j].row squareWidth + "px";squareSet[i][j].style.transition = "left 0.3s, bottom 0.3s";} }}function createSquare(value,row,col){ //创建小方块,传入参数为颜色、行、列,初始化时使用。var temp = document.createElement('div'); //创建div dom对象temp.style.height = squareWidth + "px";temp.style.width = squareWidth + "px";temp.style.display = "inline-block"; //需要让对象元素能排列一排temp.style.position = "absolute"; //相对于背景绝对定位temp.style.boxSizing = "border-box"; //重要:不会使增加的边框溢出覆盖到旁边的元素temp.style.borderRadius = "12px";temp.num = value;temp.col = col;temp.row = row;return temp; //返回这个创建出来的对象}function goBack(){ //还原样式if(timer != null){ //清空计时器clearInterval(timer);}for(var i = 0 ; i < squareSet.length ; i ++){for(var j = 0 ; j < squareSet[i].length ; j ++){if(squareSet[i][j] == null) continue;squareSet[i][j].style.border = "0px solid white";squareSet[i][j].style.transform = "scale(0.95)";} }}function checkLinked(square , arr){ // 递归连通图算法if(square == null) return; // 递归边界arr.push(square); // 将当前方块放入选中数组中// check leftif( square.col > 0 && //未到边界squareSet[square.row][square.col - 1] && //左侧有块squareSet[square.row][square.col - 1].num == square.num && //颜色相同arr.indexOf(squareSet[square.row][square.col - 1]) == -1) { //不在choose中,避免循环判断checkLinked(squareSet[square.row][square.col - 1] , arr);}// check rightif( square.col < boardWidth - 1 &&squareSet[square.row][square.col + 1] &&squareSet[square.row][square.col + 1].num == square.num &&arr.indexOf(squareSet[square.row][square.col + 1]) == -1) {checkLinked(squareSet[square.row][square.col + 1] , arr);}// check upif( square.row < boardWidth - 1 &&squareSet[square.row + 1][square.col] &&squareSet[square.row + 1][square.col].num == square.num &&arr.indexOf(squareSet[square.row + 1][square.col]) == -1) {checkLinked(squareSet[square.row + 1][square.col] , arr);}// check downif( square.row > 0 &&squareSet[square.row - 1][square.col] &&squareSet[square.row - 1][square.col].num == square.num &&arr.indexOf(squareSet[square.row - 1][square.col]) == -1) {checkLinked(squareSet[square.row - 1][square.col] , arr);} }function flicker(arr){ // 选中连通的小方块可以闪烁var num = 0;timer = setInterval(function(){for(var i = 0 ; i < arr.length ; i ++){arr[i].style.border = "3px solid BFEFFF";arr[i].style.transform = "scale(" + (0.9 + (0.05 Math.pow(-1 , num))) + ")";}num ++; // 注意这里所采用的数学技巧,仍然使用transform:scale(val)来进行缩放。},300);}function selectScore(){ //可以显示当前选中小方块的得分var score = 0;for(var i = 0 ; i < choose.length ; i ++){score += (baseScore + i stepScore);}if(score == 0) return;document.getElementById('selectScore').innerHTML = choose.length + " blocks " + score + " points";document.getElementById('selectScore').style.opacity = 1;document.getElementById('selectScore').style.transition = null;// 设置时间间隔1秒后显示消失的过渡动画setTimeout(function(){document.getElementById('selectScore').style.opacity = 0;document.getElementById('selectScore').style.transition = "opacity 1s";},1000);}function mouseOver(obj){ //鼠标移入区域响应// 加锁,点击事件过程中不允许其他点击事件与移入事件if(!flag){tempSquare = obj;return;}// 还原所有样式goBack();// 检查相邻choose = [];checkLinked(obj , choose);if(choose.length <= 1){choose = [];return;}// 闪烁flicker(choose);// 显示分数selectScore();}function move(){ //下落移动控制//纵向下落,采用快慢指针算法for(var i = 0 ; i < boardWidth ; i ++){var pointer = 0; //慢指针for(var j = 0 ; j < boardWidth ; j ++){if(squareSet[j][i] != null){ //按行遍历if(pointer != j){ //快慢指针不同步说明中间有空元素squareSet[pointer][i] = squareSet[j][i]; //慢指针设成快指针元素squareSet[j][i].row = pointer;squareSet[j][i] = null; //快指针处置空}pointer ++; //该行非空时慢指针增加} }}// 横向移动(当出现一列为空时)for(var i = 0 ; i < squareSet[0].length ;){ // 注意循环终止条件的判断!!!因为数组长度会更新if(squareSet[0][i] == null){ //逻辑:只需判断最低层为空,该行则全为空for(var j = 0 ; j < boardWidth ; j ++){squareSet[j].splice(i , 1); //splice删除数组squareSet[j]中从i开始的1个元素}continue;//注意移动后i不应改变了}i ++;}refresh();}function isFinish(){ //判断游戏结束flag = true; //重要:需要先解锁,保证后续鼠标事件可以被响应for(var i = 0 ; i < squareSet.length ; i ++){for(var j = 0 ; j < squareSet[i].length ; j ++){if(squareSet[i][j] == null) continue; //遍历每一元素判断连通var temp = [];checkLinked(squareSet[i][j] , temp);if(temp.length > 1) return false; //若有某一元素仍有多块连通,则游戏未结束} }return flag;}function init(){ // JS调用入口table = document.getElementById('pop_star'); // 获取到最外层的父元素作为桌面document.getElementById('targetScore').innerHTML = "Target Score : " + targetScore; //显示目标分数用innerHTML// 循环初始化星星区域for(var i = 0 ; i < boardWidth ; i ++){squareSet[i] = new Array(); //二维数组的创建,对每一个元素new Array()创建新数组for(var j = 0 ; j < boardWidth ; j ++){var square = createSquare(Math.floor(Math.random() 5) , i , j);// 鼠标移入事件square.onmouseover = function(){mouseOver(this);}// 鼠标点击事件square.onclick = function(){//对锁进行控制if(!flag || choose.length == null){return;}flag = false;tempSquare = null;//更新分数var score = 0;for(var i = 0 ; i < choose.length ; i ++){score += (baseScore + i stepScore);}totalScore += score;document.getElementById('nowScore').innerHTML = "Current Score : " + totalScore;//为移除增加一个延迟动画,为了防止闭包,这里采用立即执行函数for(var i = 0 ; i < choose.length ; i ++){(function(i){setTimeout(function(){squareSet[choose[i].row][choose[i].col] = null; //为状态数组置空table.removeChild(choose[i]); //将其从桌面上移除} , i 50);})(i);}//需要等星星消除完毕后再移动,故需增加一个延迟setTimeout(function(){move(); //调用移动函数setTimeout(function(){var judge = isFinish();if(judge){ //游戏达到结束条件if(totalScore > targetScore){alert('Congratulations! You win!');}else{alert('Mission Failed!');} }else{flag = true;choose = [];mouseOver(tempSquare); //处理可能存在的冲突} },300 + choose.length 75); //需要一个判断延迟},choose.length 50);}squareSet[i][j] = square; //必须将新创建的方块放回到数组中table.appendChild(square); //需要将创建的新元素添加到桌面上} }refresh(); //每次页面内容发生变化需要重绘页面}window.onload = function(){init();} // window.onload 保证了在页面全部加载完毕后再执行JS代码 效果 本篇文章为转载内容。原文链接:https://blog.csdn.net/weixin_56471396/article/details/128681321。 该文由互联网用户投稿提供,文中观点代表作者本人意见,并不代表本站的立场。 作为信息平台,本站仅提供文章转载服务,并不拥有其所有权,也不对文章内容的真实性、准确性和合法性承担责任。 如发现本文存在侵权、违法、违规或事实不符的情况,请及时联系我们,我们将第一时间进行核实并删除相应内容。
2023-06-08 15:26:34
517
转载
转载文章
...able表,可以查看影响子段(含义比较清晰)。 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
140
转载
转载文章
...修改了形参的地址并不影响原来的参数,故即使你修改了值也不会同步到原变量中,故操作的变量都显式或者隐式的定义为final JSON fastjson parseArray(String text, Class<T> clazz) 解析List parseObject(String text, Class<T> clazz) 解析Object JSON对于null、空白字符串、“null”会返回nullif (text == null) {return null;} else {DefaultJSONParser parser = new DefaultJSONParser(text, ParserConfig.getGlobalInstance());JSONLexer lexer = parser.lexer;int token = lexer.token();ArrayList list;if (token == 8) {lexer.nextToken(); // nextToken() => ...if ("null".equalsIgnoreCase(ident)) this.token = 8;list = null;} } String toJSONString(Object object) 将对象转为String toJSONBytes(Object object, SerializerFeature... features) 将对象转为byte[] @JSONField() 可以忽略字段serialize ,别名映射name,日期格式化format等 jackson @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") 设置Date到前台的格式 @JsonIgnore SpringMVC不会向前台传递该字段 ObjectMapper mapper = new ObjectMapper();String str = mapper.writeValueAsString(admin); // 对象转JSON字符串mapper.readValue(s,Admin.class ); // JSON字符串转对象 EasyExcel 官方API https://www.yuque.com/easyexcel/doc 使用类注解@ExcelIgnoreUnannotated配合@ExcelProperty操作 @ExcelProperty可以指定表头列名,列顺序和表头的合并 @ColumnWidth(10)可以指定列宽,其长度约为(中文length3+英文length1) @DateTimeFormat(value="yyyy-MM-dd HH:mm:ss")可以指定日期格式 自定义策略实现SheetWriteHandler工作表回调接口,在afterSheetCreate()工作表创建之后方法可以 设置列宽 自定义表头 新建单元格 自定义策略实现RowWriteHandler行回调接口,在afterRowDispose()行操作完之后方法可以 设置行高 设置行样式 自定义策略实现CustomerCellHandler单元格回调接口,在afterCellDispose()单元格操作完之后方法可以 根据行号,列宽甚至是单元格的值来设置单元格样式 可以对单元格的值获取和修改 样式通常包括内容格式、批注、背景色、自动换行、平和垂直居中、边框大小和颜色、字体实例(格式,颜色,大小,加粗等)等 自定义策略继承AbstractMergeStrategy单元格合并抽象类,在merge()方法中可以通过CellRangeAddress合并单元格 过于复杂的表格可以使用模板,配合写出write和填充fill一起使用 Mybatis 在mapper方法的@select中也是可以直接书写动态SQL的,但要使用<script></script>包裹,这样就不用在java文件和xml文件切换了,将@select中包裹的代码直接放到浏览器的控制台输出后会自动转义\n,\t,+,"等 动态sql中“<” 和 “>” 号要用转义字符 “<” 和 ”>“ (分号要带) 动态sql中test中表达式通常使用 test=“id != null and id != ‘’”,要注意的是字符串不能直接识别单引号,有两种方法使用id==“1001"或者id==‘1001’.toString(),另外参数如果是boolean,可以直接使用test=”!flag",如果判定集合的话可以使用 test=“list != null and list.size>0” 返回数据类型为Map只能接收一条记录,字段为键名,字段值为值,但通常是用实体类接收,或是使用注解@MapKey来进行每条记录的映射,效果等同于List用Stream流转Map foreach遍历list collection=“list” item=“vo” separator="," open="(" close=")"> {vo.id} foreach遍历map collection=“map” index=“key” item=“value”,{key}获取建,{value}获取值,$亦可 collection=“map.entrySet()” index=“key” item=“value”,同上 collection=“map.keys” item=“key”,{key}为键 不要使用where 1=1,使用动态where拼接,会自动剔除where后多余的and和or 单个参数时无论基本和引用并且未使用在动态SQL可以不加参数注解@Param,但一旦参数大于一个或者参数在动态SQL中使用就必须加@Param 并不是直接把参数加引号,而是变成?的形式交给prepareStatement处理,$直接使用值,当ORDER BY诸如此类不需要加引号的参数时,使用$代替,但为避免sql注入,该参数不能交由用户控制 Plus 官方API https://baomidou.com/guide/ @TableName 表名 @TableField(strategy = FieldStrategy.IGNORED) 更新不会忽略NULL值 @TableField(exist = false)表明该字段非数据字段,否则新增更新会报错 MybatisPlus对于单表的操作还是非常优秀的,在对单表进行新增或者更新的时候经常使用,但对于单表的查询业务上很少出现仅仅查询一张表的情况,但也会有,如果条件不大于3个还是可以使用的,多了倒没有直接写SQL来的方便了 MybatisPlus的批量插入也是通过for循环插入的,还是建议使用Mybatis的动态foreach进行批量插入 MybatisPlus的分页器会对方法中的参数判断,如果存在分页对象就先查询总数看是否大于0,然后拼接当前的数据库limit语句,所以如果我们分页对象为null,就可以实现不分页查询 Object paramObj = boundSql.getParameterObject();IPage page = null;if (paramObj instanceof IPage) { ……public static String getOriginalCountSql(String originalSql) {return String.format("SELECT COUNT(1) FROM ( %s ) TOTAL", originalSql);} ……originalSql = DialectFactory.buildPaginationSql(page, buildSql, dbType, this.dialectClazz); ……public String buildPaginationSql(String originalSql, long offset, long limit) {StringBuilder sql = new StringBuilder(originalSql);sql.append(" LIMIT ").append(offset).append(",").append(limit);return sql.toString();} IDEA 插件 Lombok : 快速生成getter、setter等 Alibaba Java Coding Guidelines :阿里规约扫描 Rainbow Brackets :彩色括号 HighlightBracketPair :高亮提示 MyBatisX :mabatisPlus提供的xml和mapper转换的插件,小鸟图标 CamelCase :大小写、驼峰、下划线、中划线转换插件 使用shift+Alt+u进行转换(很方便) 可以在Editor中设置CamelCase的转换,一般只保留下划线和驼峰两种 String Manipulation :字符串工具(未使用) RestfulToolkit http :Restful请求工具 打开idea,在右侧边栏会有一个标签(RestServices),打开可以看到里面是url路径 ctrl+\或者ctrl+alt+n会检索路径 Ctrl + Enter格式化json 没有记忆功能,也不能加token,只是查找请求路径使用 easycode :代码生成工具(个人觉得很好用,常用于生成实体类) 支持自定义模板 支持添加自定义列,不影响数据库 支持多表同时生成 支持自定义类型映射 支持配置导入导出 支持动态调试 支持自定义属性 Power Mode 11 :打字特效(纯属装逼) Nyan Progress Bar :漂亮的进度条(纯属装逼) Other Vo:数据持久化模型 Query:数据查询模型 Dto:数据传输模型 本篇文章为转载内容。原文链接:https://blog.csdn.net/qq_40910781/article/details/111416185。 该文由互联网用户投稿提供,文中观点代表作者本人意见,并不代表本站的立场。 作为信息平台,本站仅提供文章转载服务,并不拥有其所有权,也不对文章内容的真实性、准确性和合法性承担责任。 如发现本文存在侵权、违法、违规或事实不符的情况,请及时联系我们,我们将第一时间进行核实并删除相应内容。
2023-05-26 23:30:52
269
转载
转载文章
...ce; } } } 效果展示: 详细配置信息可以参考这篇文章:http://blog.ncmem.com/wordpress/2019/08/12/plupload%e4%b8%8a%e4%bc%a0%e6%95%b4%e4%b8%aa%e6%96%87%e4%bb%b6%e5%a4%b9-2/ 本篇文章为转载内容。原文链接:https://blog.csdn.net/weixin_45525177/article/details/100654639。 该文由互联网用户投稿提供,文中观点代表作者本人意见,并不代表本站的立场。 作为信息平台,本站仅提供文章转载服务,并不拥有其所有权,也不对文章内容的真实性、准确性和合法性承担责任。 如发现本文存在侵权、违法、违规或事实不符的情况,请及时联系我们,我们将第一时间进行核实并删除相应内容。
2023-12-19 09:43:46
128
转载
转载文章
...解光学原理,并与数学计算相结合,提升他们解决实际问题的能力。 此外,艺术家和设计师也在利用颜色叠加的原理进行创新实践。例如,荷兰艺术家埃舍尔借助颜色叠加创作出视错觉艺术作品,展示出二维空间内不同颜色相互作用产生的神奇效果。而在时尚界,设计师们通过面料上的颜色叠加与透明度变化,营造出丰富多变且极具层次感的视觉体验。 总的来说,颜色叠加这一基本原理不仅在科普实验中有生动体现,更在科技、教育、艺术等多个领域发挥着重要作用,不断推动着人类对色彩世界的深入理解和广泛利用。
2024-01-20 16:20:26
469
转载
Ruby
...再次升温,尤其是在云计算和人工智能领域,多线程处理的需求愈发旺盛。例如,亚马逊AWS最近推出了一项名为“Firecracker”的微虚拟化技术,旨在为无服务器计算提供更高的性能和安全性。这项技术利用轻量级虚拟化容器来运行多个任务,极大地提高了资源利用率。然而,这种高度并发的环境也带来了新的挑战,比如如何确保不同任务之间的数据隔离性和一致性。 在国内,阿里巴巴集团也在积极布局并发编程相关的技术研究。阿里云推出了基于Go语言的高性能微服务框架“MOSN”,该框架支持大规模分布式系统的构建,特别适合处理高并发场景下的请求分发和负载均衡。MOSN的设计理念强调模块化和可扩展性,使得开发者能够轻松应对复杂的业务逻辑。不过,随着越来越多的企业采用类似的架构,如何有效管理线程池大小、避免死锁等问题成为了新的关注焦点。 此外,近期一篇发表在《ACM Transactions on Programming Languages and Systems》上的论文引起了广泛关注。这篇论文探讨了现代编程语言在并发模型设计上的差异,并提出了一种新型的“乐观并发控制”算法。该算法通过预测线程间的冲突概率,动态调整同步策略,从而在一定程度上减少了锁的使用频率。这一方法不仅提升了程序的执行效率,还降低了开发者的维护成本。 从哲学角度来看,无论是技术层面还是理论层面,人类对于并发编程的追求始终未曾停歇。正如古希腊哲学家赫拉克利特所言:“人不能两次踏进同一条河流。”同样,在并发编程的世界里,每一次尝试都是一次全新的探索,而每一次成功都离不开对失败教训的深刻反思。未来,随着量子计算等前沿科技的发展,我们或许将迎来一场关于并发编程范式的革命,而这无疑将为软件工程领域带来前所未有的机遇与挑战。
2025-04-25 16:14:17
33
凌波微步
转载文章
....1.1 SSM语言及其特点 5 2.1.2 Java及Java Servlets概述 6 2.1.3 JavaBean简介 6 2.2 服务器配置 7 2.2.1 Tomcat安装及配置 8 2.2.2 数据库配置 8 3系统分析 11 3.1 可行性分析 11 3.1.1 技术可行性 11 3.1.2 操作可行性 11 3.1.3 经济可行性 11 3.1.4 法律可行性 11 3.2 腕表交易系统功能需求分析 11 3.3 数据库需求分析 12 4系统设计 13 4.1 系统功能模块设计 13 4.2系统流程设计 13 4.2.1 系统开发流程 13 4.2.2 用户登录流程 14 4.2.3 系统操作流程 15 4.2.4 添加信息流程 15 4.2.5 修改信息流程 16 4.2.6 删除信息流程 16 4.3系统用例分析 17 4.3.1 管理员用例图 17 4.3.2 用户用例图 18 4.4 数据库设计 19 4.4.1 tb_Ware(商品信息表) 19 4.4.2 tb_manager(管理员信息表) 19 4.4.3 tb_sub(订单生成表) 19 4.4.4 tb_Link(超级链接表) 20 4.4.5 tb_Affiche(公告信息表) 20 4.3 用SSM连接数据库 20 5系统实现 22 5.1 前台部分 22 5.1.1 前台总体框架 22 5.1.2 商城首页 22 5.1.3 产品详情页 23 5.1.4 评价 23 5.2 后台部分 24 5.2.1 后台主页 24 5.2.2 后台评价管理 25 5.2.3 商品管理 25 5.2.4 商品修改 26 5.2.5 分类管理 26 5.2.6 订单管理 27 5.2.7 腕表购物车管理 27 6系统测试 28 6.1系统测试的意义 28 6.2性能测试 29 6.3测试分析 29 总 结 30 致 谢 31 参考文献 31 3系统分析 3.1 可行性分析 腕表交易系统主要目标是实现网上展示腕表交易系统信息,购买腕表产品。在确定了目标后,我们从以下四方面对能否实现本系统目标进行可行性分析。 3.1.1 技术可行性 腕表交易系统主要采用Java技术,基于B/S结构,MYSQL数据库,主要包括前端应用程序的开发以及后台数据库的建立和维护两个方面。对于应用程序的开发要求具备功能要完备、使用应简单等特点,而对于数据库的建立和维护则要求建立一个数据完整性强、数据安全性好、数据稳定性高的库。腕表交易系统的开发技术具有很高可行性,且开发人员掌握了一定的开发技术,所以系统的开发具有可行性。 3.1.2 操作可行性 腕表交易系统的登录界面简单易于操作,采用常见的界面窗口来登录界面,通过电脑进行访问操作,会员只要平时使用过电脑都能进行访问操作。此系统的开发采用PHP语言开发,基于B/S结构,这些开发环境使系统更加完善。本系统具有易操作、易管理、交互性好的特点,在操作上是非常简单的。因此本系统可以进行开发。 3.1.3 经济可行性 腕表交易系统是基于B/S模式,采用MYSQL数据库储存数据,所要求的硬件和软件环境,市场上都很容易购买,程序开发主要是管理系统的开发和维护。所以程序在开发人力、财力上要求不高,而且此系统不是很复杂,开发周期短,在经济方面具有较高的可行性。 3.1.4 法律可行性 此腕表交易系统是自己设计的管理系统,具有很大的实际意义。开发环境软件和使用的数据库都是开源代码,因此对这个系统进行开发与普通的系统软件设计存在很大不同,没有侵权等问题,在法律上完全具有可行性。 综上所述,腕表交易系统在技术、经济、操作和法律上都具有很高的可行性,开发此程序是很必要的。 3.2 腕表交易系统功能需求分析 此基于SSM的腕表交易系统分前台功能和后台功能: 1)前台部分由用户使用,主要包括用户注册,腕表购物车管理,订单管理,个人资料管理,留言板管理 2)后台部分由管理员使用,主要包括管理员身份验证,商品管理,处理订单,用户信息管理,连接信息管理 3.3 数据库需求分析 数据库的设计通常是以一个已经存在的数据库管理系统为基础的,常用的数据库管理系统有MYSQL,SQL,Oracle等。我采用了Mysql数据库管理系统,建立的数据库名为db_business。 整个系统功能需要以下数据项: 用户:用户id、用户名称、登录密码、用户真实姓名、性别、邮箱地址、联系地址、联系电话、密码问题、答案、注册时间。 留言:主题id、作者姓名、Email、主题名称、留言内容、发布时间。 商品:商品id、名称、价格、图片路径、类型、简要介绍、存储地址、上传人姓名、发布时间、是否推荐。 订单:订单号、用户名、真实姓名、订购日期、Email、地址、邮编、付款方式、联系方式、运送方式、订单核对、其他。 管理员:管理员id、管理员名称、管理员密码。 公告:公告内容、公告时间。 4系统设计 4.1 系统功能模块设计 功能结构图如下: 图9 功能模块设计图 从图中可以看出,网上腕表交易系统可以分为前台和后台两个部分,前台部分由用户使用,主要包括用户注册,生成订单,腕表购物车管理,查看腕表购物车,查看留言,订购产品,订单查询和发布留言7个模块;本文转载自http://www.biyezuopin.vip/onews.asp?id=11975后台部分由管理员使用,主要包括管理员身份验证,商品管理,处理订单,用户信息管理,连接信息管理5个模块。 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html><head><base href="<%=basePath%>"/><title>腕表商城</title><meta http-equiv="pragma" content="no-cache"><meta http-equiv="cache-control" content="no-cache"><meta http-equiv="expires" content="0"> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"><meta http-equiv="description" content="This is my page"><meta name="viewport" content="width=device-width, initial-scale=1"><!-- Favicon --><link rel="shortcut icon" type="image/x-icon" href="img/favicon.png"><link rel="stylesheet" type="text/css" href="<%=basePath%>home/css/font-awesome.min.css" /><link rel="stylesheet" type="text/css" href="<%=basePath%>home/css/bootstrap.css" /><link rel="stylesheet" type="text/css" href="<%=basePath%>home/css/style.css"><link rel="stylesheet" type="text/css" href="<%=basePath%>home/css/magnific-popup.css"><link rel="stylesheet" type="text/css" href="<%=basePath%>home/css/owl.carousel.css"><script type="text/javascript">function getprofenlei(){ var html = ""; $.ajax({url: "leixing.action?list&page=0&rows=30",type: "POST",async: false, contentType: "application/x-www-form-urlencoded;charset=UTF-8",success: function (data) { $.each(data.rows, function (i, val) { html += ' <li ><a href="home/search.jsp?fenlei='+val.id+'" >'+val.a1+' </a></li>';})} }); $("fenlei").html(html);}function gettop1(){var html = "";$.ajax({url: "leixing.action?list&page=0&rows=10",type: "POST",async: false,success: function (data) {var total='';//<div class="tab-pane active" id="nArrivals">// <div class="nArrivals owl-carousel" id="top1">$.each(data.rows, function (i, valmm) { html+='<div class="nArrivals owl-carousel" id="'+valmm.id+'">';$.ajax({url: "shangpin.action?list&page=0&rows=10",type: "POST",async: false,data: { fenlei:valmm.id },success: function (data) { $.each(data.rows, function (i, val) { html+='<div class="product-grid">'+'<div class="item">'+' <div class="product-thumb">'+' <div class="image product-imageblock"> <a href="home/details.jsp?ids='+val.id+'"> <img data-name="product_image" style="width:223px;height:285px;" src="<%=basePath%>'+val.tupian1+'" alt="iPod Classic" title="iPod Classic" class="img-responsive"> <img style="width:223px;height:285px;" src="<%=basePath%>'+val.tupian1+'" alt="iPod Classic" title="iPod Classic" class="img-responsive"> </a> </div>'+' <div class="caption product-detail text-left">'+' <h6 data-name="product_name" class="product-name mt_20"><a href="home/details.jsp?ids='+val.id+'" title="Casual Shirt With Ruffle Hem">'+val.biaoti+'</a></h6>'+' <div class="rating"> <span class="fa fa-stack"><i class="fa fa-star-o fa-stack-1x"></i><i class="fa fa-star fa-stack-1x"></i></span> <span class="fa fa-stack"><i class="fa fa-star-o fa-stack-1x"></i><i class="fa fa-star fa-stack-1x"></i></span> <span class="fa fa-stack"><i class="fa fa-star-o fa-stack-1x"></i><i class="fa fa-star fa-stack-1x"></i></span> <span class="fa fa-stack"><i class="fa fa-star-o fa-stack-1x"></i><i class="fa fa-star fa-stack-1x"></i></span> <span class="fa fa-stack"><i class="fa fa-star-o fa-stack-1x"></i><i class="fa fa-star fa-stack-x"></i></span> </div>'+'<span class="price"><span class="amount"><span class="currencySymbol">$</span>'+val.jiage+'</span>'+'</span>'+'<div class="button-group text-center">'+' <div class="wishlist"><a href="home/details.jsp?ids='+val.id+'"><span>wishlist</span></a></div>'+'<div class="quickview"><a href="home/details.jsp?ids='+val.id+'"><span>Quick View</span></a></div>'+'<div class="compare"><a href="home/details.jsp?ids='+val.id+'"><span>Compare</span></a></div>'+'<div class="add-to-cart"><a href="home/details.jsp?ids='+val.id+'"><span>Add to cart</span></a></div>'+'</div>'+'</div>'+'</div>'+'</div>'+' </div>'; })html+='</div>'; } })}) $("nArrivals").html(html); } }); 本篇文章为转载内容。原文链接:https://blog.csdn.net/newlw/article/details/127608579。 该文由互联网用户投稿提供,文中观点代表作者本人意见,并不代表本站的立场。 作为信息平台,本站仅提供文章转载服务,并不拥有其所有权,也不对文章内容的真实性、准确性和合法性承担责任。 如发现本文存在侵权、违法、违规或事实不符的情况,请及时联系我们,我们将第一时间进行核实并删除相应内容。
2023-03-21 18:24:50
67
转载
转载文章
...用容器技术将应用程序及其依赖项打包在一起,形成可移植的、自包含的运行环境。在本文中,Docker 用于创建和管理 MySQL 数据库服务的容器实例,通过提供预配置的 MySQL 镜像,使得用户能够快速启动并配置 MySQL 服务器。 MySQL 镜像 , MySQL 镜像是 Docker 中的一个预构建软件包,其中包含了运行 MySQL 数据库服务器所需的所有文件和配置。在 Docker 环境中,通过拉取并运行特定版本(如 8.0 或 5.7)的 MySQL 镜像,可以轻松创建一个新的 MySQL 容器实例,并根据需要通过环境变量等方式进行配置。 数据卷(Data Volume) , 在 Docker 中,数据卷是一个可供多个容器之间共享和持久化存储数据的区域,即使容器停止或删除,数据也能得到保留。在文中提到,可以通过 -v 参数将主机上的目录挂载为容器内的 MySQL 数据目录(例如 /var/lib/mysql),这样 MySQL 的数据库文件就能持久存储在主机系统上,而不仅仅存在于容器内部,从而实现数据持久化。 环境变量(Environment Variables) , 环境变量是在操作系统进程中维护的一系列命名值,它们提供了影响进程行为的方法。在 Docker 和 MySQL 的结合使用中,环境变量被用来传递配置信息给 MySQL 容器,比如设置根用户的密码 (MYSQL_ROOT_PASSWORD)、创建新用户和数据库 (MYSQL_USER 和 MYSQL_DATABASE) 等。这些变量在容器启动时被读取,并用于初始化和配置 MySQL 实例。 docker-entrypoint-initdb.d 目录 , 这是在官方 MySQL Docker 镜像中的一个特殊目录,当首次启动 MySQL 容器且需要初始化新数据库实例时,Docker 会自动执行该目录下所有扩展名为 .sh、.sql 和 .sql.gz 的文件。这个机制允许用户在容器启动过程中自定义数据库初始化脚本,用以填充数据或执行其他数据库初始化任务。
2023-05-29 17:31:06
102
转载
转载文章
...不同尺寸屏幕下的展示效果。Grid布局通过定义二维网格系统,轻松实现复杂且灵活的布局需求;而Flexbox则专注于一维空间内的对齐和方向调整,尤其适用于导航栏、侧边栏等组件的布局。这两种现代布局方式不仅在兼容性上有所提升,而且大大简化了以往使用浮动、定位或表格布局时繁琐的计算过程。 同时,针对物理像素精确绘制的需求,CSS单位如“vw”、“vh”以及“calc()”函数的应用也日趋广泛。这些单位基于视口宽度和高度百分比,能更好地配合各种屏幕密度进行布局,并解决了1px边框在高DPR设备上的显示问题。 此外,最新的浏览器已经开始支持CSS环境变量(CSS Variables),这使得跨组件甚至跨页面的样式统一管理变得更加容易,进一步提升了移动端页面自适应设计的效率和灵活性。 综上所述,在移动端页面自适应方案的探索道路上,从早期的rem布局到如今CSS Grid、Flexbox等现代布局技术的广泛应用,开发者们正不断追求更高效、更便捷、更具前瞻性的解决方案,以应对日新月异的移动互联网时代挑战。而对于那些仍在使用或想要了解rem布局方案的开发者而言,适时关注并学习这些新的布局技术和策略,无疑将有助于其在未来的项目中打造出更为优质且适应力更强的移动端用户体验。
2023-03-23 12:01:53
134
转载
转载文章
...可能更为紧凑。 北航计算机学硕 , 北航指的是北京航空航天大学,是我国著名的“双一流”建设高校之一;计算机学硕则代表计算机科学与技术学术型硕士研究生,区别于专硕(专业型硕士),更侧重于理论研究和学术探索。 知名高校 , 在文中,知名高校主要指具有较高学术声誉和社会影响力的高等学校,如文中提及的末流985高校以及上海科技大学、北京理工大学、北京航空航天大学等,在我国高等教育体系中占据重要地位,对于学生来说,进入这些学校深造意味着更高的平台和更多的机会。
2023-05-02 23:03:36
121
转载
转载文章
...全性的通讯标准,在云计算、边缘计算以及各类工业场景中的应用日益广泛。诸如微软Azure IoT Edge等云服务已实现对OPC UA的原生支持,使得工厂设备能够无缝对接云端,实现远程监控与智能决策。 此外,德国联邦经济事务和能源部正积极推动“工业4.0组件”的标准化进程,其中OPC UA扮演着核心角色,为实现生产设备间互操作性提供关键支撑。最新的OPC UA规范也在不断迭代更新,以满足未来工厂智能化、网络化的需求,如适应时间敏感网络(TSN)、增强信息安全机制等。 综上所述,深入研究OPC UA的实际应用场景及其在国内外工业领域内的政策导向和技术革新,对于理解和掌握现代工业通信技术的发展具有重要指导意义。紧跟行业动态,了解OPC UA如何赋能制造业数字化转型,将有助于我们更好地应对未来挑战并抓住机遇。
2023-05-10 18:43:00
270
转载
转载文章
...时候,在出了问题会有影响的模块,进行处理,建立自动恢复性 4.3 实现弹性 在设计上,不要假定模块是正常的、始终不变的 – 可以配合AutoScaling、EIP和可用区AZ来满足 允许模块的失败重启 – 无状态设计比有状态设计好 – 使用ELB、云监控去检测“实例”运行状态 有引导参数的实例(实现自动配置) – 例如:加入user data在启动的时候,告知它应该做的事情 在关闭实例的时候,保存其配置和个性化 – 例如用DynamoDB保存session信息 弹性后就不会为了超配资源而浪费钱了 4.4 安全是整体的事,需要在每个层面综合考虑 基础架构层 计算/网络架构层 数据层 应用层 4.5 最小授权原则 只付于操作者完成工作的必要权限 所有用户的操作必须授权 三种类型的权限能操作AWS – 主账户 – IAM用户 – 授权服务(主要是开发的app) 5 设计:高可用、高效率、可容错、可扩展的系统 本部分的目标是设计出高可用、高效率低成本、可容错、可扩展的系统架构 - 高可用 – 了解AWS服务自身的高可靠性(例如弹性负载均衡)—-因为ELB是可以多AZ部署的 – 用好这些服务可以减少可用性的后顾之忧 - 高效率(低成本) – 了解自己的容量需求,避免超额分配 – 利用不同的价格策略,例如:使用预留实例 – 尽量使用AWS的托管服务(如SNS、SQS) - 可容错 – 了解HA和容错的区别 – 如果说HA是结果,那么容错则是保障HA的一个重要策略 – HA强调系统不要出问题,而容错是在系统出了问题后尽量不要影响业务 - 可扩展性 – 需要了解AWS哪些服务自身就可以扩展,例如SQS、ELB – 了解自动伸缩组(AS) 运用好 AWS 7大架构设计原则的:松耦合、实现弹性 6 实施和部署设计 本部分的在设计的基础上找到合适的工具来实现 对比第一部分“设计”,第一章主要针对用什么,而第二章则讨论怎么用 主要考核AWS云的核心的服务目录和核心服务,包括: 计算机和网络 – EC2、VPC 存储和内容分发 – S3、Glacier 数据库相关分类 – RDS 部署和管理服务 – CloudFormation、CloudWatch、IAM 应用服务 – SQS、SNS 7 数据安全 数据安全的基础,是AWS责任共担的安全模型模型,必须要读懂 数据安全包括4个层面:基础设施层、计算/网络层、数据层、应用层 - 基础设施层 1. 基础硬件安全 2. 授权访问、流程等 - 计算/网络层 1. 主要靠VPC保障网络(防护、路由、网络隔离、易管理) 2. 认识安全组和NACLs以及他们的差别 安全组比ACL多一点,安全组可以针对其他安全组,ACL只能针对IP 安全组只允许统一,ACL可以设置拒绝 安全组有状态!很重要(只要一条入站规则通过,那么出站也可以自动通过),ACL没有状态(必须分别指定出站、入站规则) 安全组的工作的对象是网卡(实例)、ACL工作的对象是子网 认识4种网关,以及他们的差别 共有4种网关,支撑流量进出VPC internet gatway:互联网的访问 virtual private gateway:负责VPN的访问 direct connect:负责企业直连网络的访问 vpc peering:负责VPC的peering的访问 数据层 数据传输安全 – 进入和出AWS的安全 – AWS内部传输安全 通过https访问API 链路的安全 – 通过SSL访问web – 通过IP加密访问VPN – 使用直连 – 使用OFFLINE的导入导出 数据的持久化保存 – 使用EBS – 使用S3访问 访问 – 使用IAM策略 – 使用bucket策略 – 访问控制列表 临时授权 – 使用签名的URL 加密 – 服务器端加密 – 客户端加密 应用层 主要强调的是共担风险模型 多种类型的认证鉴权 给用户在应用层的保障建议 – 选择一种认证鉴权机制(而不要不鉴权) – 用安全的密码和强安全策略 – 保护你的OS(如打开防火墙) – 用强壮的角色来控制权限(RBAC) 判断AWS和用户分担的安全中的标志是,哪些是AWS可以控制的,那些不能,能的就是AWS负责,否则就是用户(举个例子:安全组的功能由AWS负责—是否生效,但是如何使用是用户负责—自己开放所有端口跟AWS无关) AWS可以保障的 用户需要保障的 工具与服务 操作系统 物理内部流程安全 应用程序 物理基础设施 安全组 网络设施 虚拟化设施 OS防火墙 网络规则 管理账号 8 故障排除 问题经常包括的类型: - EC2实例的连接性问题 - 恢复EC2实例或EBS卷上的数据 - 服务使用限制问题 8.1 EC2实例的连接性问题 经常会有多个原因造成无法连接 外部VPC到内部VPC的实例 – 网关(IGW–internet网关、VPG–虚拟私有网关)的添加问题 – 公司网络到VPC的路由规则设置问题 – VPC各个子网间的路由表问题 – 弹性IP和公有IP的问题 – NACLs(网络访问规则) – 安全组 – OS层面的防火墙 8.2 恢复EC2实例或EBS卷上的数据 注意EBS或EC2没有任何强绑定关系 – EBS是可以从旧实例上分离的 – 如有必要尽快做 将EBS卷挂载到新的、健康的实例上 执行流程可以针对恢复没有工作的启动卷(boot volume) – 将root卷分离出来 – 像数据一样挂载到其他实例 – 修复文件 – 重新挂载到原来的实例中重新启动 8.3 服务使用限制问题 AWS有很多软性限制 – 例如AWS初始化的时候,每个类型的EBS实例最多启动20个 还有一些硬性限制例如 – 每个账号最多拥有100个S3的bucket – …… 别的服务限制了当前服务 – 例如无法启动新EC2实例,原因可能是EBS卷达到上限 – Trusted Advisor这个工具可以根据服务水平的不同给出你一些限制的参考(从免费试用,到商业试用,和企业试用的建议) 常见的软性限制 公共的限制 – 每个用户最多创建20个实例,或更少的实例类型 – 每个区域最多5个弹性ip – 每个vpc最多100个安全组 – 最多20个负载均衡 – 最多20个自动伸缩组 – 5000个EBS卷、10000个快照,4w的IOPS和总共20TB的磁盘 – …更多则需要申请了 你不需要记住限制 – 知道限制,并保持数值敏感度就好 – 日后遇到问题时可以排除掉软限制的相关的问题 9. 总结 9.1 认证的主要目标是: 确认架构师能否搜集需求,并且使用最佳实践,在AWS中构建出这个系统 是否能为应用的整个生命周期给出指导意见 9.2 希望架构师(助理或专家级)考试前的准备: 深度掌握至少1门高级别语言(c,c++,java等) 掌握AWS的三份白皮书 – aws概览 – aws安全流程 – aws风险和应对 – 云中的存储选项 – aws的架构最佳实践 按照客户需求,使用AWS组件来部署混合系统的经验 使用AWS架构中心网站了解更多信息 9.3 经验方面的建议 助理架构师 – 至少6个月的实际操作经验、在AWS中管理生产系统的经验 – 学习过AWS的基本课程 专家架构师 – 至少2年的实际操作经验、在AWS中管理多种不同种类的复杂生产系统的经验(多种服务、动态伸缩、高可用、重构或容错) – 在AWS中执行构建的能力,架构的高级概念能力 9.4 相关资源 认证学习的资源地址 - 可以自己练习,模拟考试需要付费的 接下来就去网上报名参加考试 本篇文章为转载内容。原文链接:https://blog.csdn.net/QXK2001/article/details/51292402。 该文由互联网用户投稿提供,文中观点代表作者本人意见,并不代表本站的立场。 作为信息平台,本站仅提供文章转载服务,并不拥有其所有权,也不对文章内容的真实性、准确性和合法性承担责任。 如发现本文存在侵权、违法、违规或事实不符的情况,请及时联系我们,我们将第一时间进行核实并删除相应内容。
2023-11-29 22:08:40
271
转载
站内搜索
用于搜索本网站内部文章,支持栏目切换。
知识学习
实践的时候请根据实际情况谨慎操作。
随机学习一条linux命令:
yum check-update && yum upgrade (适用于基于RPM的系统如CentOS)
- 同上,用于RPM包管理器。
推荐内容
推荐本栏目内的其它文章,看看还有哪些文章让你感兴趣。
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
历史内容
快速导航到对应月份的历史文章列表。
随便看看
拉到页底了吧,随便看看还有哪些文章你可能感兴趣。
时光飞逝
"流光容易把人抛,红了樱桃,绿了芭蕉。"