- Windows图形开发库Kernel32,OpenGL32,Glu32,Gdi32与User32
CoderIsArt
C#windows
publicconststringKernel32="kernel32.dll";publicconststringOpenGL32="opengl32.dll";publicconststringGlu32="Glu32.dll";publicconststringGdi32="gdi32.dll";publicconststringUser32="user32.dll";这段代码定义了一些常量
- Java基础回顾 Day1
小斌的Debug日记
Java基础回顾java开发语言
常用工具类相关1.自动装箱和自动拆箱基本数据类型和包装类转换2.String、StringBuffer、StringBuilder区别与联系。string不可变,线程安全stringbuffer可变,线程安全stringbuilder可变,线程不安全,效率高3.Stringstr=”ccjr”;和Stringstr=newString(“ccjr”);的区别前者在常量池寻找,若”ccjr”已存在,
- SpringBoot整合AI:5行代码接入大模型API实战
weixin_74887700
springboot人工智能后端
一、SpringAI快速入门指南1.1三步接入OpenAI//build.gradledependencies{implementation'org.springframework.ai:spring-ai-openai-spring-boot-starter:0.8.0'}//核心调用代码@RestControllerpublicclassAIController{@Autowiredpriva
- 【Qt学习】| 如何使用QVariant存储自定义类型
歌笑爱学习
qt学习数据库
QVariant是Qt框架中的一个通用数据类型,可以存储多种类型的数据,主要作用是提供一种类型安全的方式来存储和传递不同类型的数据,而不需要显示地指定数据类型。QVariant提供了诸多构造函数可以非常方便地对基础数据类型(如:intdoubleboolQStringQTimeQSize)进行转换,具体可在帮助文档中查阅。那么,如何对自定义类型的数据进行转换呢?方法1:voidsetValue(c
- LeetCode热题100刷题12
Liwan95
LeetCodeleetcode算法职场和发展
23.合并K个升序链表给你一个链表数组,每个链表都已经按升序排列。请你将所有链表合并到一个升序链表中,返回合并后的链表。与合并两个有序链表类似,但是需要在k个链表节点中找到最小的。考虑使用优先队列。classSolution{classStatusimplementsComparable{intval;ListNodenode;publicStatus(intval,ListNodenode){t
- 2025 Swift 最新面试题及答案
九变形战士
移动开发swift开发语言ios
2024Swift最新面试题及答案基础部分Swift访问控制Swift`Any`、`AnyObject`和`Generics`区别Swift`final`关键字⽤过没主要⽤来⼲嘛Swift的`static`和`class`区别Swift的`extension`⽤过没,都能⼲嘛Swift中的Optional是什么?如何安全解包?Swift有什么⽅案能监听属性值的变化,不使用ObjC的KVO进阶部分说
- python-leetcode-二叉树的中序遍历
Joyner2018
leetcode算法职场和发展
94.二叉树的中序遍历-力扣(LeetCode)方法1:递归实现#Definitionforabinarytreenode.#classTreeNode:#def__init__(self,val=0,left=None,right=None):#self.val=val#self.left=left#self.right=rightclassSolution:definorderTraversa
- hive运维
花泽啸
Hivehive
hive锁相关showlocks;查看锁unlocktable表名;释放锁发现释放不了锁,执行下面sethive.support.concurrency=false;sethive.txn.manager=org.apache.hadoop.hive.ql.lockmgr.DummyTxnManager;然后在unlock还是不行的的话:select*fromHIVE_LOCKS;关闭hivese
- Redis学习笔记——(17)Redis面试题及答案
码农小高
Redisredis学习数据库
Redis面试题1.什么是redis?Redis是一个key-value存储系统,它支持存储的value类型相对更多,包括string、list、set、zset(sortedset--有序集合)和hash。这些数据结构都支持push/pop、add/remove及取交集并集和差集及更丰富的操作,而且这些操作都是原子性的。在此基础上,Redis支持各种不同方式的排序。为了保证效率,数据都是缓存在内
- Kotlin 2.1.0 入门教程(二十三)泛型、泛型约束、协变、逆变、不变
xvch
Kotlinkotlinandroid
out(协变)out关键字用于实现泛型的协变。协变意味着如果B是A的子类型,那么Producer可以被视为Producer的子类型。这里的Producer是一个使用泛型类型参数的类或接口,并且该泛型类型参数被标记为out。interfaceProducer{funproduce():T}openclassAnimalclassCat:Animal()funmain(){valcatProducer
- Redis数据库面试——数据结构类型知识
Good Note
补档数据库redis面试服务端后端数据结构缓存
大家好,这里是GoodNote,关注公主号:Goodnote,专栏文章私信限时Free。本文详细介绍Redis提供的5种基本数据结构类型和4种特殊类型,除此之外,还有8种底层数据结构,每种结构类型有其特点和适用场景。文章目录基本数据类型1.String(字符串)使用场景缓存计数器ID生成器分布式锁2.Hash(哈希)3.List(链表/列表)4.Set(集合)5.SortedSet(有序集合)特殊
- 【5. C++ 数据抽象:理解与实践】
涛ing
C++面向对象c++开发语言linuxubuntuc语言vscode人工智能
本章目录:前言什么是数据抽象?C++中的数据抽象类与对象示例:简单的加法器类输出:数据抽象的好处访问控制与封装示例:封装与访问控制输出:设计策略总结前言数据抽象是面向对象编程中的一个重要概念,它指的是通过只暴露关键信息来隐藏数据的实现细节。通过数据抽象,程序员能够专注于接口而不是内部实现,减少了代码复杂度,同时也提升了代码的可维护性和可扩展性。C++语言通过类(class)为数据抽象提供了强大的支
- 上位机和MYSQL连接_C#上位机与数据库连接初步学习经验分享一!
weixin_39961369
上位机和MYSQL连接
太一、定义连接字符串,用来链接SQLServerstringstr_con="server=.(服务器名称一般为.);database=WordBook(数据库名称);uid=sa(服务器登录名);pwd=123(服务器密码)";二、有了链接字符串之后,开始数据库操作1、数据库查询定义了一个查询方法,用来调用:publicDataSetqueryDatabase(stringsql)//sql是查
- C vs C++:从面向过程到面向对象的本质差异
金外飞176
信息分享c语言c++
CvsC++:从面向过程到面向对象的本质差异引言作为编程语言界的"双生子",C和C++自1972年和1985年诞生以来,始终占据系统级开发的核心地位。尽管语法相似度高达70%,但两者在设计哲学、抽象层次和适用场景上存在本质差异。本文通过10大核心对比维度,揭示两种语言的独特魅力。一、语言特性根本差异1.1面向对象支持//C++类定义classRectangle{public:intwidth;in
- git clone - fatal:鉴权失败
执 白
git
Usernamefor‘https://github.com’:(输入账号)Passwordfor‘https://***@github.com’:(输入personalaccesstoken,而不是账号对应的密码)personalaccesstoken获取过程如下(有两种token,这篇文章仅展示Creatingapersonalaccesstoken(classic)如何获取):github官
- Yarn 依赖解析机制深度解析:确定性安装与版本冲突的工程哲学
引言:包管理工具的"圣杯问题"在现代前端工程中,依赖管理已成为构建稳定性的核心挑战。根据2023年JavaScript生态调查报告显示,平均每个前端项目依赖1,200+个第三方包,嵌套依赖层级超过15层。在这样的复杂度下,如何实现确定性安装(DeterministicInstallation)和版本冲突智能解决,成为Yarn这类包管理工具的核心战场。本文将深入探讨Yarn(特别是Classicv1
- Ubuntu 下 nginx-1.24.0 源码分析 - ngx_atoi 函数
若云止水
nginx运维
ngx_atoi声明在src/core/ngx_string.hngx_int_tngx_atoi(u_char*line,size_tn);定义在src/core/ngx_string.cngx_int_tngx_atoi(u_char*line,size_tn){ngx_int_tvalue,cutoff,cutlim;if(n==0){returnNGX_ERROR;}cutoff=NGX_
- 蓝桥杯R格式--高精度算法模拟
泛舟起晶浪
算法蓝桥杯程序人生
#includeusingnamespacestd;intpos,p1;intib[1566];intan[1567];intn;stringa,b;intmain(){cin>>n>>a;for(inti=a.size()-1;i>=0;i--){if(a[i]!='.'){pos++;b.insert(b.end(),a[i]);///string插char用insert/push_back}
- 2025蓝桥杯JAVA编程题练习Day5
起床悠悠
蓝桥杯Java算法学习算法数据结构java蓝桥杯
1.最少步数【省模拟赛】问题描述小蓝要上一个楼梯,楼梯共有n级台阶(即小蓝总共要走nn级)。小蓝每一步可以走1级、2级或3级台阶。请问小蓝至少要多少步才能上到楼梯顶端?输入格式输入一行包含一个整数n。输出格式输出一行包含一个整数,表示答案。样例输入19样例输出13样例输入210样例输出24AC代码importjava.util.*;publicclassexercise1{staticScanne
- python实现文件下载-python实现文件上传下载
weixin_37988176
创建自己的ftp类myftp.py废话不多说,前方上代码!!!#!/usr/bin/python#coding:utf-8#author:zhj#info:数据传输平台importftplib,socket,os,sysclassMyFtp(object):def__init__(self,host,port,name,passwd):self.host=hostself.port=portsel
- 实时性保障方案
m0_55576290
工作一二三balance
1.实时性保障方案双缓冲数据管道设计:classDataPipeline{QVectorbufferA,bufferB;QMutexmutex;public:voidwriteData(constQVector&data){QMutexLockerlocker(&mutex);bufferA.append(data);}QVectorreadData(){QMutexLockerlocker(&m
- PLC中位、字、双字的关系
技术花境
单片机人工智能
在1200PLC(可编程逻辑控制器)中,数据的存储单位有几个基本概念,包括位(bit)、字节(byte)和字(word)。它们之间的关系如下:1.位(bit)定义:位是信息的基本构成单位,是计算机数据存储中最小的信息单位。特点:它只能取两个值,0或1。这使得位能够表示各种状态,如开和关(例如,开关状态、传感器状态等)。在PLC中的应用:位通常用于表示单个输入或输出状态,例如操作开关、传感器的状态,
- 数字雨-贪吃蛇
aids1990
游戏c/c++
数字雨#include"windows.h"#include"stdlib.h"#include"stdio.h"#include"time.h"#include"string.h"#defineID_TIMER1#defineSTRMAXLEN25#defineSTRMINLEN8LRESULTCALLBACKWndProc(HWND,UINT,WPARAM,LPARAM);typedefstr
- Redis 常用的五种数据类型
HinINAX
redischrome数据库
Redis常用的五种数据类型一、字符串(String)简介字符串是Redis中最基本的数据类型,可以存储任何类型的数据(如文本、数字、二进制数据等)。每个字符串的最大长度可以达到512MB。常用命令SETkeyvalue用途:设置键key的值为value。语法:SETkeyvalue示例:SETusername"john_doe"GETkey用途:获取键key的值。语法:GETkey示例:GETu
- java后端开发day19--学生管理系统升级
元亓亓亓
java后端开发java开发语言
(以下内容全部来自上述课程)1.要求及思路1.总体框架2.注册3.登录4.忘记密码2.代码1.javabeanpublicclassUser1{privateStringusername;privateStringpassword;privateStringpersonID;privateStringphoneNumber;publicUser1(){}publicUser1(Stringuser
- 041集——选取若干点生成三角网(CAD—C#二次开发入门)
山水CAD筑梦人
CADC#二次开发c#数据库java
随机生成2000个三维点并生成三角网,效果如下:随机生成20个点,效果如下:附部分代码如下:publicclassNTS三角网{publicstaticintnumPoints=20;[CommandMethod("xx")]publicvoid在NTSdemo(){//获取当前文档和编辑器Documentdoc=Application.DocumentManager.MdiActiveDocum
- Leetcode Day6 (图论I, dfs, bfs)
比起村村长
leetcode深度优先leetcode图论
创建一个visited的模版#mxn大小的矩阵m=len(matrix)n=len(matrix[0])visited=[[Falsefor_inrange(n)]for_inrange(m)]foriinrange(m):forjinrange(n):blablabla#DFS模版```python200岛屿数量classSolution:defnumIslands(self,grid:List
- java开发——为什么要使用动态代理?
river66
进阶篇java
举个例子:假如有一个杀手专杀男的,不杀女的。代码如下:publicinterfaceKiller{voidkill(Stringname,Stringsex);voidwatch(Stringname);}publicclassManKillerimplementsKiller{@Overridepublicvoidkill(Stringname,Stringsex){if(sex.equals(
- QChart Class Reference
七贤岭双花红棍
QtCharts小课堂qt
QChart是Qt框架中用于绘制图表的类,属于QtCharts模块。它提供了一种简单而强大的方式来创建各种类型的图表,如折线图、柱状图、饼图、散点图等。QChart可以与QChartView结合使用,将图表嵌入到应用程序的GUI中。QChart的核心功能多种图表类型:支持折线图、柱状图、饼图、散点图、面积图等多种图表类型。数据管理:通过QAbstractSeries的子类(如QLineSeries
- 【Day25 LeetCode】贪心Ⅲ
银河梦想家
leetcode算法
一、贪心Ⅲ1、加油站134这道题直接想法是采用二重循环暴力搜索,简单粗暴但是会超时,是因为以每个点为起点最坏的情况可能都要遍历完全部的序列,有大量重复的操作,那有没有优化的地方呢?有一个结论:如果以iii位置出发最远可达jjj位置,那么在在这段区间里的任意一点出发都不可能达到比jjj位置更远的地方。反证法可以得出。可以通过这个结论避免大量重复搜索,每个位置只会经过一次。代码如下:classSolu
- 312个免费高速HTTP代理IP(能隐藏自己真实IP地址)
yangshangchuan
高速免费superwordHTTP代理
124.88.67.20:843
190.36.223.93:8080
117.147.221.38:8123
122.228.92.103:3128
183.247.211.159:8123
124.88.67.35:81
112.18.51.167:8123
218.28.96.39:3128
49.94.160.198:3128
183.20
- pull解析和json编码
百合不是茶
androidpull解析json
n.json文件:
[{name:java,lan:c++,age:17},{name:android,lan:java,age:8}]
pull.xml文件
<?xml version="1.0" encoding="utf-8"?>
<stu>
<name>java
- [能源与矿产]石油与地球生态系统
comsci
能源
按照苏联的科学界的说法,石油并非是远古的生物残骸的演变产物,而是一种可以由某些特殊地质结构和物理条件生产出来的东西,也就是说,石油是可以自增长的....
那么我们做一个猜想: 石油好像是地球的体液,我们地球具有自动产生石油的某种机制,只要我们不过量开采石油,并保护好
- 类与对象浅谈
沐刃青蛟
java基础
类,字面理解,便是同一种事物的总称,比如人类,是对世界上所有人的一个总称。而对象,便是类的具体化,实例化,是一个具体事物,比如张飞这个人,就是人类的一个对象。但要注意的是:张飞这个人是对象,而不是张飞,张飞只是他这个人的名字,是他的属性而已。而一个类中包含了属性和方法这两兄弟,他们分别用来描述对象的行为和性质(感觉应该是
- 新站开始被收录后,我们应该做什么?
IT独行者
PHPseo
新站开始被收录后,我们应该做什么?
百度终于开始收录自己的网站了,作为站长,你是不是觉得那一刻很有成就感呢,同时,你是不是又很茫然,不知道下一步该做什么了?至少我当初就是这样,在这里和大家一份分享一下新站收录后,我们要做哪些工作。
至于如何让百度快速收录自己的网站,可以参考我之前的帖子《新站让百
- oracle 连接碰到的问题
文强chu
oracle
Unable to find a java Virtual Machine--安装64位版Oracle11gR2后无法启动SQLDeveloper的解决方案
作者:草根IT网 来源:未知 人气:813标签:
导读:安装64位版Oracle11gR2后发现启动SQLDeveloper时弹出配置java.exe的路径,找到Oracle自带java.exe后产生的路径“C:\app\用户名\prod
- Swing中按ctrl键同时移动鼠标拖动组件(类中多借口共享同一数据)
小桔子
java继承swing接口监听
都知道java中类只能单继承,但可以实现多个接口,但我发现实现多个接口之后,多个接口却不能共享同一个数据,应用开发中想实现:当用户按着ctrl键时,可以用鼠标点击拖动组件,比如说文本框。
编写一个监听实现KeyListener,NouseListener,MouseMotionListener三个接口,重写方法。定义一个全局变量boolea
- linux常用的命令
aichenglong
linux常用命令
1 startx切换到图形化界面
2 man命令:查看帮助信息
man 需要查看的命令,man命令提供了大量的帮助信息,一般可以分成4个部分
name:对命令的简单说明
synopsis:命令的使用格式说明
description:命令的详细说明信息
options:命令的各项说明
3 date:显示时间
语法:date [OPTION]... [+FORMAT]
- eclipse内存优化
AILIKES
javaeclipsejvmjdk
一 基本说明 在JVM中,总体上分2块内存区,默认空余堆内存小于 40%时,JVM就会增大堆直到-Xmx的最大限制;空余堆内存大于70%时,JVM会减少堆直到-Xms的最小限制。 1)堆内存(Heap memory):堆是运行时数据区域,所有类实例和数组的内存均从此处分配,是Java代码可及的内存,是留给开发人
- 关键字的使用探讨
百合不是茶
关键字
//关键字的使用探讨/*访问关键词private 只能在本类中访问public 只能在本工程中访问protected 只能在包中和子类中访问默认的 只能在包中访问*//*final 类 方法 变量 final 类 不能被继承 final 方法 不能被子类覆盖,但可以继承 final 变量 只能有一次赋值,赋值后不能改变 final 不能用来修饰构造方法*///this()
- JS中定义对象的几种方式
bijian1013
js
1. 基于已有对象扩充其对象和方法(只适合于临时的生成一个对象):
<html>
<head>
<title>基于已有对象扩充其对象和方法(只适合于临时的生成一个对象)</title>
</head>
<script>
var obj = new Object();
- 表驱动法实例
bijian1013
java表驱动法TDD
获得月的天数是典型的直接访问驱动表方式的实例,下面我们来展示一下:
MonthDaysTest.java
package com.study.test;
import org.junit.Assert;
import org.junit.Test;
import com.study.MonthDays;
public class MonthDaysTest {
@T
- LInux启停重启常用服务器的脚本
bit1129
linux
启动,停止和重启常用服务器的Bash脚本,对于每个服务器,需要根据实际的安装路径做相应的修改
#! /bin/bash
Servers=(Apache2, Nginx, Resin, Tomcat, Couchbase, SVN, ActiveMQ, Mongo);
Ops=(Start, Stop, Restart);
currentDir=$(pwd);
echo
- 【HBase六】REST操作HBase
bit1129
hbase
HBase提供了REST风格的服务方便查看HBase集群的信息,以及执行增删改查操作
1. 启动和停止HBase REST 服务 1.1 启动REST服务
前台启动(默认端口号8080)
[hadoop@hadoop bin]$ ./hbase rest start
后台启动
hbase-daemon.sh start rest
启动时指定
- 大话zabbix 3.0设计假设
ronin47
What’s new in Zabbix 2.0?
去年开始使用Zabbix的时候,是1.8.X的版本,今年Zabbix已经跨入了2.0的时代。看了2.0的release notes,和performance相关的有下面几个:
:: Performance improvements::Trigger related da
- http错误码大全
byalias
http协议javaweb
响应码由三位十进制数字组成,它们出现在由HTTP服务器发送的响应的第一行。
响应码分五种类型,由它们的第一位数字表示:
1)1xx:信息,请求收到,继续处理
2)2xx:成功,行为被成功地接受、理解和采纳
3)3xx:重定向,为了完成请求,必须进一步执行的动作
4)4xx:客户端错误,请求包含语法错误或者请求无法实现
5)5xx:服务器错误,服务器不能实现一种明显无效的请求
- J2EE设计模式-Intercepting Filter
bylijinnan
java设计模式数据结构
Intercepting Filter类似于职责链模式
有两种实现
其中一种是Filter之间没有联系,全部Filter都存放在FilterChain中,由FilterChain来有序或无序地把把所有Filter调用一遍。没有用到链表这种数据结构。示例如下:
package com.ljn.filter.custom;
import java.util.ArrayList;
- 修改jboss端口
chicony
jboss
修改jboss端口
%JBOSS_HOME%\server\{服务实例名}\conf\bindingservice.beans\META-INF\bindings-jboss-beans.xml
中找到
<!-- The ports-default bindings are obtained by taking the base bindin
- c++ 用类模版实现数组类
CrazyMizzz
C++
最近c++学到数组类,写了代码将他实现,基本具有vector类的功能
#include<iostream>
#include<string>
#include<cassert>
using namespace std;
template<class T>
class Array
{
public:
//构造函数
- hadoop dfs.datanode.du.reserved 预留空间配置方法
daizj
hadoop预留空间
对于datanode配置预留空间的方法 为:在hdfs-site.xml添加如下配置
<property>
<name>dfs.datanode.du.reserved</name>
<value>10737418240</value>
- mysql远程访问的设置
dcj3sjt126com
mysql防火墙
第一步: 激活网络设置 你需要编辑mysql配置文件my.cnf. 通常状况,my.cnf放置于在以下目录: /etc/mysql/my.cnf (Debian linux) /etc/my.cnf (Red Hat Linux/Fedora Linux) /var/db/mysql/my.cnf (FreeBSD) 然后用vi编辑my.cnf,修改内容从以下行: [mysqld] 你所需要: 1
- ios 使用特定的popToViewController返回到相应的Controller
dcj3sjt126com
controller
1、取navigationCtroller中的Controllers
NSArray * ctrlArray = self.navigationController.viewControllers;
2、取出后,执行,
[self.navigationController popToViewController:[ctrlArray objectAtIndex:0] animated:YES
- Linux正则表达式和通配符的区别
eksliang
正则表达式通配符和正则表达式的区别通配符
转载请出自出处:http://eksliang.iteye.com/blog/1976579
首先得明白二者是截然不同的
通配符只能用在shell命令中,用来处理字符串的的匹配。
判断一个命令是否为bash shell(linux 默认的shell)的内置命令
type -t commad
返回结果含义
file 表示为外部命令
alias 表示该
- Ubuntu Mysql Install and CONF
gengzg
Install
http://www.navicat.com.cn/download/navicat-for-mysql
Step1: 下载Navicat ,网址:http://www.navicat.com/en/download/download.html
Step2:进入下载目录,解压压缩包:tar -zxvf navicat11_mysql_en.tar.gz
- 批处理,删除文件bat
huqiji
windowsdos
@echo off
::演示:删除指定路径下指定天数之前(以文件名中包含的日期字符串为准)的文件。
::如果演示结果无误,把del前面的echo去掉,即可实现真正删除。
::本例假设文件名中包含的日期字符串(比如:bak-2009-12-25.log)
rem 指定待删除文件的存放路径
set SrcDir=C:/Test/BatHome
rem 指定天数
set DaysAgo=1
- 跨浏览器兼容的HTML5视频音频播放器
天梯梦
html5
HTML5的video和audio标签是用来在网页中加入视频和音频的标签,在支持html5的浏览器中不需要预先加载Adobe Flash浏览器插件就能轻松快速的播放视频和音频文件。而html5media.js可以在不支持html5的浏览器上使video和audio标签生效。 How to enable <video> and <audio> tags in
- Bundle自定义数据传递
hm4123660
androidSerializable自定义数据传递BundleParcelable
我们都知道Bundle可能过put****()方法添加各种基本类型的数据,Intent也可以通过putExtras(Bundle)将数据添加进去,然后通过startActivity()跳到下一下Activity的时候就把数据也传到下一个Activity了。如传递一个字符串到下一个Activity
把数据放到Intent
- C#:异步编程和线程的使用(.NET 4.5 )
powertoolsteam
.net线程C#异步编程
异步编程和线程处理是并发或并行编程非常重要的功能特征。为了实现异步编程,可使用线程也可以不用。将异步与线程同时讲,将有助于我们更好的理解它们的特征。
本文中涉及关键知识点
1. 异步编程
2. 线程的使用
3. 基于任务的异步模式
4. 并行编程
5. 总结
异步编程
什么是异步操作?异步操作是指某些操作能够独立运行,不依赖主流程或主其他处理流程。通常情况下,C#程序
- spark 查看 job history 日志
Stark_Summer
日志sparkhistoryjob
SPARK_HOME/conf 下:
spark-defaults.conf 增加如下内容
spark.eventLog.enabled true spark.eventLog.dir hdfs://master:8020/var/log/spark spark.eventLog.compress true
spark-env.sh 增加如下内容
export SP
- SSH框架搭建
wangxiukai2015eye
springHibernatestruts
MyEclipse搭建SSH框架 Struts Spring Hibernate
1、new一个web project。
2、右键项目,为项目添加Struts支持。
选择Struts2 Core Libraries -<MyEclipes-Library>
点击Finish。src目录下多了struts