自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+

FREEDOM

hello world

  • 博客(806)
  • 资源 (29)
  • 收藏
  • 关注

原创 安卓android自动化测试-uiautomator/uiautomator2

很早以前,我用uiautomator+java实践过Android APP自动化测试,不过今天要提的不是uiautomator,而是uiautomator2。听起来uiautomator2像是uiautomator的升级版,但是这两款框架仅仅是名字上比较相似,实际上没有任何关联。先有的谷歌uiautomator,但是只支持java;后来一个名为hexiaocong的开发者基于uiautomator封装了python版本,支持python代码运行;

2025-10-14 12:03:03 562

原创 带管理界面的app操作、自动化测试平台-sonic

sonic是一个云真机平台,可以在浏览器界面操作手机,手机app,做相关操作。如截图,抓包,调试等等,并能编写自动化测试流程,实现自动化测试。底层使用adb,uiautomator2,ios-bridge等和手机端进行交互。涉及以下三个项目。

2025-10-14 12:02:13 748

原创 Cython编译去掉符号表

通常,这是通过编译器和链接器的选项来实现的。在链接阶段,你可以使用链接器的选项来去除所有符号信息。然而,这通常会去除所有符号,包括那些可能需要的导出符号。在实施这些措施之前,请确保你了解它们对性能和兼容性的影响,并进行充分的测试。除了去除符号信息外,你还可以考虑使用代码混淆工具来进一步保护你的Cython代码。在Cython编译生成的C代码之后,你可以使用编译器的选项来减少或去除生成的二进制文件中的符号信息。可能会去除所有符号,包括必要的导出符号,因此更常见的做法是先编译和链接,然后使用。

2025-10-14 11:59:52 228

原创 java的线程池 ThreadPoolExecutor 源码解析-sm

程序BUG导致动态生成了很多新类,使得 Metaspace 不断被占用,先引发FGC,最后导致OOM. 代码中显式调用了gc方法,包括自己的代码甚至框架中的代码。如果YoungGC频率远低于这个值,例如20秒1次,30秒1次,甚至60秒1次。这种情况下,JVM相当空闲,处于基本上无事可做的状态。如果YoungGC频率远低于这个值,例如1秒/次,甚至1秒/好多次。检查Young区,Young区在整个堆占比在25%~40%比较合理,如果Young区太小,建议扩大Xmn。FGC:1天1次以内。

2025-10-14 11:59:08 638

原创 Sentinel限流正则匹配,以及不同版本的问题sm

此版本基于sentinel1.8.8 ,支持资源正则,但是只是client支持正则,dashboard管理界面并没有提供,可以自己更改内存配置或者redis中存储的规则,增加regex=true即可。

2025-09-19 09:35:56 37

原创 docker和pip两种方式安装superset,安装apsw报错‘for’ loop initial declarations are only allowed in C99 mode-sm

在 C89 标准中,变量必须在代码块的开头声明,而 C99 允许在。循环内部声明变量(如。

2025-07-21 18:21:59 75

原创 springboot jar暴露prometheus指标的两种方式,以及opentelemetry-javaagent.jar能做什么(无侵入prometheus指标、以及链路追踪)-sm

是 OpenTelemetry 项目提供的,可以自动收集 Java 应用的和,并将这些数据发送到指定的监控后端(如 Prometheus、Jaeger、Grafana 等)。这是最简便的方法,无需额外编写代码。

2025-07-17 15:51:35 686

原创 springboot2.6+(SpringMVC 5.3+) 及之前版本的路径匹配策略 ,ANT_PATH_MATCHER和PATH_PATTERN_PARSER,Swagger扫描不到接口解决-sm

特性匹配语法Ant 风格表达式类似 Ant,但更严格性能中等更高(内存占用更低)Spring Boot 默认版本2.5 及之前2.6+Swagger 2.x 兼容性✅ 兼容❌ 需手动配置❌ 不支持✅ 仅支持此策略如果你的项目使用 Spring Boot 2.6+ 且依赖 Swagger 2.x,建议配置以确保兼容性。

2025-05-22 11:29:21 1308

原创 pyarmor的问题-sm

经测试不编译为pyd是没问题的,若要pyd需再pyarmor gen命令时所在的目录下,添加一个restrict_module=0的文件。再目录下执行pyarmor cfg restrict_module=0会自动生成。

2025-04-27 17:08:41 232

原创 pyarmor9的使用,py文件加密混淆打包-sm

官网文档:https://pyarmor.readthedocs.io/en/latest/

2025-04-27 11:55:32 305

原创 redisson,分布式锁(可重入锁、公平锁、联锁、红锁)集合(列表、集合、映射、有序集合)同步工具、对象,分布式服务(远程服务调用、执行器、调度器)分布式消息(发布订阅队列)限流-sm

Redisson 的分布式对象允许在分布式系统的多个节点间共享和操作数据,就像操作本地对象一样。

2025-03-25 15:24:06 1183

原创 sharding-jdbc总结、水平、垂直分库分表、动态扩容,读写分分离,分布式事务,加解密-sm

sharding-jdbc 是一个客户端框架,客户端实现分片。sharding-proxy是一个代理,代理服务中实现分片。

2025-03-09 15:17:36 778

原创 sse协议 前后端流式消息,如文心一言 等返答案是一个字一个词现实的。以及自定义的http返回流式消息。sm

也是基于http,get,post等都可以,把数据分为一块一块的,类似chunk格式。只用在返回的时候,一个字符或几个字符流返回就行, 且规定每块之间的分割符(主要为了获取无完整的字符,防止乱码),前端当得到一个分割符时,前面的数据流就可以转成字符展示了,然后继续判断下一个分割符。。。以下演示从ai获取答案后中专返回前端的例子。/*** 聊天-流式,\n\n 分割* @param question 问题* @param resMsg 返回答案* @return*/try {

2024-06-19 17:32:23 666

原创 selenium 无头模式 以及防止被检测sm

一般情况下,我们使用Selenium打开一个网页时,会有一个提示:Chrome正受到自动测试软件的控制。以淘宝为首,众多网站都针对 Selenium的js监测机制,就是上面的方法实现的。在启动Chromedriver之前,为Chrome开启实验性功能参数。运行上面的代码,就没有Chrome正受到自动测试软件的控制的提示了。发现已经是undefined了,这样才是一个正常的浏览器了。只需要设置Chromedriver的启动参数即可解决问题。然后打开调试工具,点击consile,输入代码。

2024-05-17 17:56:13 326

原创 selenium 等待页面渲染完成,获取选然后html代码-sm

在Selenium中,可以使用几种方法来等待页面渲染完成。

2024-05-17 16:05:46 213

原创 python setup.py 打包安装到site-packages, distutils 和 setuptools 两种方式sm

是Python distutils增强版的集合(distutils),它可以帮助我们更简单的创建和分发Python包,尤其是拥有依赖关系的。建议使用setuptools两种引入方式如下是Python,负责建立Python扩展模块的安装器用的。而setuptools是, 相比而言拥有更多的优点。

2024-03-21 12:05:35 789

原创 跨平台app测试框架-Appium。支持安卓android或ios的sdk

Appium是一个移动端的自动化框架,可用于测试原生应用,移动网页应用和混合型应用,且是跨平台的。可用于IOS和Android以及firefox的操作系统。原生的应用是指用android或ios的sdk编写的应用,移动网页应用是指网页应用,类似于ios中safari应用或者Chrome应用或者类浏览器的应用。混合应用是指一种包裹webview的应用,原生应用于网页内容交互性的应用。重要的是Appium是跨平台的,何为跨平台,意思就是可以针对不同的平台用一套api来编写测试用例。

2024-01-09 15:43:08 1346

原创 Node 版本管理——NVM

nvm(Node Version Manager)是Node.js的版本管理器,可以让我们轻松地在不同的Node.js版本之间进行切换。中文网nvm文档手册 - nvm是一个nodejs版本管理工具 - nvm中文网​nvm.uihtm.com/​编辑。

2023-10-13 12:03:30 1803

原创 nginx 日志,格式化,存储,按日切割

server {使用log_format指令定义了一个main的格式,并在access_log指令中引用了它。Win64;我们看到最终的日志记录中都对应了一个,这是因为这几个变量为空。Nginx中通过access_log和error_log指令配置访问日志和错误日志,通过log_format我们可以自定义日志格式。如果日志文件路径中使用了变量,我们可以通过指令来设置缓存,提升性能。其他的根据自己的使用场景定义。

2023-03-28 17:09:27 3994

原创 pip/conda/mamba

众所周知,在使用Python语言时有时会需要导入第三方库,而在导入第三库之前需要先安装该库,而安装方式有两种,分别是通过pip install 和 conda install 的方式,那么这两种方式有什么区别呢?Mamba 底层依赖于conda,conda是单线程,Mamba做了优化可多线程下载,Mamba兼容conda的命令。最重要的是​​Mamba可与conda完美兼容​​ (将conda执行命令中的conda换做mamba即可)。Mamba的核心部分是通过C++实现,以获得最大执行效率;

2023-03-25 19:11:43 1894

原创 elasticsearch es doc_values和fielddata 、ignore_above

搜索需要用到倒排索引,而排序和聚合则需要使用 “正排索引”。doc_values和fielddata就是用来给文档建立正排索引的。他俩一个很显著的区别是,前者的工作地盘主要在磁盘,而后者的工作地盘在内存。不过对于text字段,doc_values是不支持的,有一种替代方案就是使用fielddata,这是一种把文本字段放到内存中来处理的方式,先直接从磁盘读取每个段的反向索引,然后通过反向索引,反转索引与文档的关系,最后将结果放到JVM堆内存中来处理。

2023-02-03 15:19:29 678

原创 k8s 知识总结2

但是有时候例如Java程序内存泄漏了,程序无法正常工作,但是JVM进程却是一直运行的,对于这种应用本身业务出了问题的情况,Kubernetes提供了Liveness Probe机制,通过检测容器响应是否正常来决定是否重启,这是一种很好的健康检查机制。意思就是deployment是一个pod的配置管理,pod是具体的运行实例(一组容器的运行实例,一个pod下的多个容器互不影响,pod只是一组相同标签属性的容器的统称)用来管理有状态应用,可以保证部署和扩缩的顺序,详细参考 StatefulSet。

2023-01-06 11:56:23 559

原创 es elasticsearch 新增更新索引,新增更新文档

局部更新是:若更新数据为{"a":111},则get整个文档变为{"a":111,"b":2}全量更新是:若更新数据为{"a":111},则get整个文档变为{"a":111}创建一个全新的索引,映射包含调整后的字段或类型。将新的索引的别名设置为原来索引相同名称。若原文档为{"a":1,"b":2}将原有索引的数据迁移到新的索引。只能增加原有不存在的字段。

2022-12-19 10:04:12 1697

原创 爬虫,selenium问题汇总,driver.close,driver.quit(),新的tab

selenium中webdriver关闭浏览器有两个方法,一个是close,一个是quit,为了测试二者的区别,通过代码注释观察了一下区别观察了一下当webdriver.Chrome()时会产生以下进程当python调用chrome程序关闭后,chrome相关的进程也会关闭。使用driver.close()关闭时,若浏览器只打开一个tab,所以会关闭浏览器,chromedriver这个服务进程还存在,可以通过ps -ef|grep chrome查看到。

2022-11-24 18:03:35 481

原创 elasticsearch es的全文检索,排序,范围查询原理。深度分页慢的原因,正排索引,倒排索引,为何不像mysql用B+树做排序索引-sm

111

2022-09-23 10:41:42 24

原创 mongodb 总结

mongo的索引是B树,非聚簇索引,即所有的索引都关联一个recordId(非_id字段,_id索引也要关联recordId),通过recordId再查找数据。

2022-08-11 15:19:12 1703

原创 elasticsearch es 搭建 操作 优化总结,索引模板 别名滚动索引 切割索引 时间索引 冷热数据 生命周期 索引隔离 读写分离-sm

索引与分片主分片,一旦设置数量,就无法更改,因为路由策略的原因,修改会导致根据id查找不到数据。shard_num= hash(_routing) % num_primary_shardses创建索引时若不指定主分片数量,则默认是5个。分片副本的数量可以随时增加,副本主要是为了数据备份,因此副本根据数据重要性来定吧。单分片磁盘占用最好在20-50g。 因为es的一个分片就是lucene的一个index。一个ES shard(lucene index)最多可以索引2,147,483,5.

2022-05-28 17:31:51 30

原创 kafka 配置、问题、生产消费 可靠性、等幂、事务、性能优化总结(一)-sm

kafka 支持事务,即生产者开启事务写入多条,一条出错全回滚,消费者 通过配置 只能读取 已提交事务数据。 而对于未提交不可见。kafka支持可配置生产者等幂enable.idempotence,即会对生产者发送的每个消息加一个seq自增序号。首先,它只能保证单分区上的幂等性,即一个幂等性 Producer 能够保证某个主题的一个分区上不出现重复消息,它无法实现多个分区的幂等性。其次,它只能实现单会话上的幂等性,不能实现跨会话的幂等性。这里的会话,你可以理解为Producer 进程的一...

2022-05-25 17:41:20 30

原创 spring 事务传播REQUIRED 与 NESTED的区别

NESTED 似乎与REQUIRED 是一样的,但是他们是不同的。若关于spring事务传播机制的解释播行为 意义 PROPAGATION_REQUIRES 表示当前方法必须在一个事务中运行。如果一个现有事务正在进行中,该方法将在那个事务中运行,否则就要开始一个新事务。 PROPAGATION_SUPPORTS 表示当前方法不需要事务性上下文,但是如果有一个事务已经在运行的话,它也可以在这个事务里运行。 PROPAGATION_MANDATORY ...

2022-05-12 20:28:00 5487 1

原创 字符编号ASCII 和Unicode,与字符编码,utf8,gbk

总结字符编号ASCII 和Unicode类似。仅仅是给某个字一个唯一的编号,并没有规定怎么对字符编码。ASCII 只用一个字节,因为发明比较早,只能标识256个字符,00000000-11111111,里面只给英文字母,和一些特殊字符如空格 进行了编号。Unicode 是为了解决全世界的字符(unicode 同时兼容ASCII 的编号),给每个字符都有一个唯一的编号,比如,汉字“严”的unicode是十六进制数4E25,转换成二进制数足足有15位。字符编码UTF-8是Unicode.

2022-04-02 11:22:26 1499

原创 java/spring 等相关框架 漏洞原理汇总

JNDI 中的 rmi或ldap 所造成漏洞rmi 客户端与服务端之间 传输的是序列化后的类实例对象,然后在客户端在反序列化生成对象,并初始化调用构造方法。ldap 协议也会造成本地执行远程class文件的问题,不同与rmi,ldap 会加载远程class类文件到本进行实例化构造方法!!!参考:https://liuhuiyao.blog.csdn.net/article/details/121877227log4j的 jndi漏洞log4j-2.x 版本jndi漏洞(使用ldap协议.

2022-03-31 12:34:27 1634

原创 java 加载运行网络jar包

java.net.URLClassLoader中有一个加载网络jar或者class的addUrl方法,不过是protected的,不能通过对象直接调用,可以通过反射调用。代码如下:编写UserService类,用于业务逻辑。package test2;public class UserService { public static void sayHello(String name) { System.out.println("I am "+name);; }..

2022-03-31 10:07:12 1652

原创 AmazonS3 、大文件、分段上传、分段下载,上传下载超时,java.net.SocketTimeoutException问题

关于分段下载客户端请求时:在请求头上增加range属性:bytes=fromByte-toByte。 如 值为bytes=100-200服务端响应时:指定响应status=206,Content-Length=本次传输的byte大小,Content-Range=bytes from-to/文件总大小,Accept-Ranges=bytes可以用迅雷下载,迅雷会先请求一个不带range的,获得总长度然后开多个线程进行range请求。若分段请求完成则 断开不带range的完整请求。...

2022-03-29 15:55:26 4083

原创 关于springmvc 文件下载,nginx 转发去掉了content-length ,浏览器前端下载没有进度,无法显示文件总大小的问题。

若要前端、浏览器显示下载进度,就必须直到问价总大小,要直到文件总大小就必须后端在响应头中加上content-length 即文件总大小。Content-Length:byte大小若响应有content-length时,浏览器会显示文件大小,如:若响应没有content-length时,浏览器只会显示下载多少:java下载代码/** * 下载/导出本地文件 * * @author: * @param request * @param respo...

2022-03-25 18:51:18 4911

转载 分布式id生成策略

一线大厂的分布式 ID 生成方案是什么样的? - 简书1 前言分布式系统中我们会对遇到数据量较大的业务表进行拆分,如:订单表、用户表,但是有时又需要保证id需要在整个系统保证唯一,这个时候就需要使用到分布式id。2 分布式id需要满足什么条件才是符合要求的分布式id生成方案需要保证满足一下条件才算是合理的方案整个系统唯一 id是数字类型,并且在一定范围是趋于增长趋势 id简短,查询效率快3 分布式id的几种方案3.1 UUID优点:代码简单 本机生成,没有性能问题

2022-02-18 16:04:24 660

原创 pdf分页分片预览,pdf截取,pdf转图片

分页预览主要解决两个问题(1)前端下载整个pdf比较慢。(2) 前端可以下载整个文件流,不安全。若要分页预览,也有两种方案:(1)把pdf 转成一张一张的图片。(2)把pdf 再次截取from-to页,然后生成一个新的pdf文件。pdf 分页截取截取生成新的pdf,转图片 代码 <dependency> <groupId>org.apache.pdfbox</groupId> <artifactId>pdf...

2022-02-09 13:01:35 2805 1

原创 netty 总结

重要类说明线程模型及原理代码实现tcp连接udp连接websocket连接单线程多线程主从多线程 EventLoopGroup bossGroup=new NioEventLoopGroup(2);//accept线程池 EventLoopGroup workerGroup=new NioEventLoopGroup(2);//具体负责读写及业务处理的工作线程池 ServerBootstrap b = new Server...

2022-01-17 12:39:19 1019

原创 在线文件/文档预览/分页分片预览 之开源kkfileview(word转pdf,pdf截取,pdf转图片,Aspose jobConverter , OpenOffice ,libreoffice )

官网文档kkFileView - 在线文件预览git代码地址kkFileView: 使用spring boot打造文件文档在线预览项目解决方案,支持doc、docx、ppt、pptx、xls、xlsx、zip、rar、mp4、mp3以及众多类文本如txt、html、xml、java、properties、sql、js、md、json、conf、ini、vue、php、py、bat、gitignore等文件在线预览 - Gitee.com开源协议apache。可免费商用安装部署..

2022-01-11 14:53:56 7153 4

转载 从浏览器多进程到JS单线程,JS运行机制最全面的一次梳理

前言见解有限,如有描述不当之处,请帮忙及时指出,如有错误,会及时修正。----------超长文+多图预警,需要花费不少时间。----------如果看完本文后,还对进程线程傻傻分不清,不清楚浏览器多进程、浏览器内核多线程、JS单线程、JS运行机制的区别。那么请回复我,一定是我写的还不够清晰,我来改。。。----------正文开始----------最近发现有不少介绍JS单线程运行机制的文章,但是发现很多都仅仅是介绍某一部分的知识,而且各个地方的说法还不统一,容易造成困惑。因此准备梳

2022-01-10 23:00:05 814

原创 mysql 事务与connection,锁,慢sql,如何解决,杀死执行的线程

前提说明navicat中每打开一个窗口就是打开一个connection,关掉窗口就是关掉connection事务与connection测试事务不提交的情况(步骤1)先打开一个窗口,开启一个事务T1插入一条数据,这里不进行提交。由于在一个事务中,所以select 能立刻查出insert的但还没提交的数据。查询是否开启 事务超时,回滚策略。SHOW GLOBAL VARIABLES LIKE 'innodb_rollback_on_timeout';若...

2022-01-06 12:45:59 2535

phpmyadmin修改密码

phpmyadmin修改密码,自己总结的,很好用

2014-03-31

S3 java sdk 文档-使用手册.pdf

AmazonS3 sdk中文文档

2021-11-03

nltk python 中文版 pdf

nltk python 中文版 pdf

2017-02-17

opencv 人脸识别 代码

opencv 人脸识别

2016-10-18

nlp工具 word2vec nltk textblob crf++ 机器人 中文翻译 繁体转简体 关键词 主题 命名体识别 分词 聚类 词性标注 词向量

本资源属于代码类,是一些nlp工具的使用 nlp 工具 word2vec nltk textblob crf++ (1)机器人 (2)中文翻译,及繁体转简体 (3)关键词提取,主题提取,摘要提取 (4)命名体识别 (5)分词 (6)情感分析,正负类分析 (7)近义词,同义词,句子相似性 (8)聚类,监督,无监督 (9)词性标注 (10)词向量提取

2018-07-20

CRF++ 训练中文分词

CRF++ 训练中文分词,文件后缀有3标示3列的语料,文件后缀有2,表示2列的语料训练

2017-02-08

图像标注-labelImg_windows_v1.7

图像标注-labelImg_windows_v1.7 图像标注-labelImg_windows_v1.7 图像标注-labelImg_windows_v1.7

2020-10-25

Qt 子窗口父窗口切换,窗口间传值

Qt 子窗口父窗口切换,窗口间传值

2016-09-04

xgboost.pmml

sklearn 鸢尾花训练后的pmml模型文件 ,sklearn 鸢尾花训练后的pmml模型文件

2020-10-23

网页,html5,canvas,js 动态绘制柱形图

网页,html5,canvas,js 动态绘制柱形图

2015-05-31

pcm 静默分析

pcm 静默分析pcm 静默分析pcm 静默分析pcm 静默分析pcm 静默分析pcm 静默分析pcm 静默分析

2017-12-27

iris.csv

iris.csv

2020-10-23

CRF++ 0.58.tar.gz源文件for linux和.zip for windows

CRF++ 目前最新版,包括CRF++ 0.58.tar.gz源文件for linux和.zip for windows 另外,包括一个介绍使用的下载网页文件。

2017-01-18

微信网站模板

微信网站模板

2015-03-04

jstl包

jstl包

2015-09-10

mina2 cs 客户端服务器通信 已经实现完整通信代码

mina2 cs 客户端服务器通信 已经实现完整通信代码

2015-05-31

python2.7.6+python for eclipse

python2.7.6+python for eclipse

2016-01-03

centos win7双系统安装,在win7已经安装的基础上

centos win7双系统安装,在win7已经安装的基础上。

2018-07-20

MyBatis Generator.

MyBatis Generator

2015-12-20

qt 页面切换 与传值

qt 页面切换 与传值

2016-09-05

汉语 词频 标注 语料

汉语 词频 标注 语料 汉语 词频 标注 语料 汉语 词频 标注 语料

2018-07-20

hibernate3-log4j-slf4j所有包

hibernate3 日志配置所需的三个包 log4j-slf4j

2015-10-07

java二维码制作源码

二维码二维码二维码erweima

2015-03-04

angular 路由,传值,http

angular 路由,传值,http

2016-11-03

springboot

springboot-mybatis demo

2017-01-23

jasperReports spring mvc 整合代码

2016-09-02

俄罗斯方块

import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import javax.swing.*; import javax.swing.Timer; public class Tetris extends JFrame { public Tetris() { Tetrisblok a = new Tetrisblok(); addKeyListener(a); add(a); } public static void main(String[] args) { Tetris frame = new Tetris(); JMenuBar menu = new JMenuBar(); frame.setJMenuBar(menu); JMenu game = new JMenu("游戏"); JMenuItem newgame = game.add("新游戏"); JMenuItem pause = game.add("暂停"); JMenuItem goon = game.add("继续"); JMenuItem exit = game.add("退出"); JMenu help = new JMenu("帮助"); JMenuItem about = help.add("关于"); menu.add(game); menu.add(help); frame.setLocationRelativeTo(null); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setSize(220, 275); frame.setTitle("Tetris内测版"); // frame.setUndecorated(true); frame.setVisible(true); frame.setResizable(false); } } // 创建一个俄罗斯方块类 class Tetrisblok extends JPanel implements KeyListener { // blockType 代表方块类型 // turnState代表方块状态 private int blockType; private int score = 0; private int turnState; private int x; private int y; private int i = 0; int j = 0; int flag = 0; // 定义已经放下的方块x=0-11,y=0-21; int[][] map = new int[13][23]; // 方块的形状 第一组代表方块类型有S、Z、L、J、I、O、T 7种 第二组 代表旋转几次 第三四组为 方块矩阵 private final int shapes[][][] = new int[][][] { // i { { 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0 }, { 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0 } }, // s { { 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, { 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 } }, // z { { 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 }, { 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 } }, // j { { 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0 }, { 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 }, { 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, // o { { 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, // l { { 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0 }, { 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, { 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 } }, // t { { 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }, { 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, { 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0 } } }; // 生成新方块的方法 public void newblock() { blockType = (int) (Math.random() * 1000) % 7; turnState = (int) (Math.random() * 1000) % 4; x = 4; y = 0; if (gameover(x, y) == 1) { newmap(); drawwall(); score = 0; JOptionPane.showMessageDialog(null, "GAME OVER"); } } // 画围墙 public void drawwall() { for (i = 0; i < 12; i++) { map[i][21] = 2; } for (j = 0; j < 22; j++) { map[11][j] = 2; map[0][j] = 2; } } // 初始化地图 public void newmap() { for (i = 0; i < 12; i++) { for (j = 0; j < 22; j++) { map[i][j] = 0; } } } // 初始化构造方法 Tetrisblok() { newblock(); newmap(); drawwall(); Timer timer = new Timer(1000, new TimerListener()); timer.start(); } // 旋转的方法 public void turn() { int tempturnState = turnState; turnState = (turnState + 1) % 4; if (blow(x, y, blockType, turnState) == 1) { } if (blow(x, y, blockType, turnState) == 0) { turnState = tempturnState; } repaint(); } // 左移的方法 public void left() { if (blow(x - 1, y, blockType, turnState) == 1) { x = x - 1; } ; repaint(); } // 右移的方法 public void right() { if (blow(x + 1, y, blockType, turnState) == 1) { x = x + 1; } ; repaint(); } // 下落的方法 public void down() { if (blow(x, y + 1, blockType, turnState) == 1) { y = y + 1; delline(); } ; if (blow(x, y + 1, blockType, turnState) == 0) { add(x, y, blockType, turnState); newblock(); delline(); } ; repaint(); } // 是否合法的方法 public int blow(int x, int y, int blockType, int turnState) { for (int a = 0; a < 4; a++) { for (int b = 0; b < 4; b++) { if (((shapes[blockType][turnState][a * 4 + b] == 1) && (map[x + b + 1][y + a] == 1)) || ((shapes[blockType][turnState][a * 4 + b] == 1) && (map[x + b + 1][y + a] == 2))) { return 0; } } } return 1; } // 消行的方法 public void delline() { int c = 0; for (int b = 0; b < 22; b++) { for (int a = 0; a < 12; a++) { if (map[a][b] == 1) { c = c + 1; if (c == 10) { score += 10; for (int d = b; d > 0; d--) { for (int e = 0; e < 11; e++) { map[e][d] = map[e][d - 1]; } } } } } c = 0; } } // 判断你挂的方法 public int gameover(int x, int y) { if (blow(x, y, blockType, turnState) == 0) { return 1; } return 0; } // 把当前添加map public void add(int x, int y, int blockType, int turnState) { int j = 0; for (int a = 0; a < 4; a++) { for (int b = 0; b < 4; b++) { if (map[x + b + 1][y + a] == 0) { map[x + b + 1][y + a] = shapes[blockType][turnState][j]; } ; j++; } } } // 画方块的的方法 public void paintComponent(Graphics g) { super.paintComponent(g); // 画当前方块 for (j = 0; j < 16; j++) { if (shapes[blockType][turnState][j] == 1) { g.fillRect((j % 4 + x + 1) * 10, (j / 4 + y) * 10, 10, 10); } } // 画已经固定的方块 for (j = 0; j < 22; j++) { for (i = 0; i < 12; i++) { if (map[i][j] == 1) { g.fillRect(i * 10, j * 10, 10, 10); } if (map[i][j] == 2) { g.drawRect(i * 10, j * 10, 10, 10); } } } g.drawString("score=" + score, 125, 10); g.drawString("抵制不良游戏,", 125, 50); g.drawString("拒绝盗版游戏。", 125, 70); g.drawString("注意自我保护,", 125, 90); g.drawString("谨防受骗上当。", 125, 110); g.drawString("适度游戏益脑,", 125, 130); g.drawString("沉迷游戏伤身。", 125, 150); g.drawString("合理安排时间,", 125, 170); g.drawString("享受健康生活。", 125, 190); } // 键盘监听 public void keyPressed(KeyEvent e) { switch (e.getKeyCode()) { case KeyEvent.VK_DOWN: down(); break; case KeyEvent.VK_UP: turn(); break; case KeyEvent.VK_RIGHT: right(); break; case KeyEvent.VK_LEFT: left(); break; } } // 无用 public void keyReleased(KeyEvent e) { } // 无用 public void keyTyped(KeyEvent e) { } // 定时器监听 class TimerListener implements ActionListener { public void actionPerformed(ActionEvent e) { repaint(); if (blow(x, y + 1, blockType, turnState) == 1) { y = y + 1; delline(); } ; if (blow(x, y + 1, blockType, turnState) == 0) { if (flag == 1) { add(x, y, blockType, turnState); delline(); newblock(); flag = 0; } flag = 1; } ; } } }

2014-01-04

spring-mvc-jasperReports

spring-mvc-jasperReports

2016-09-03

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除