1、spring相关配置如下:
<bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig"> <property name="maxIdle" value="${redis.pool.maxIdle}" /> <!-- 最大能够保持idel状态的对象数 --> <property name="maxTotal" value="${redis.pool.maxTotal}" /> <!-- 最大分配的对象数 --> <property name="testOnBorrow" value="${redis.pool.testOnBorrow}" /> <!-- 当调用borrow Object方法时,是否进行有效性检查 --> </bean> <!-- sprin_data_redis 单机配置 --> <bean id="jedisConnFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory" > <property name="hostName" value="${redis.host}" /> <property name="port" value="${redis.port}" /> <property name="timeout" value="${redis.timeout}" /> <property name="password" value="${redis.password}" /> <property name="poolConfig" ref="jedisPoolConfig" /> </bean> <!-- key序列化 --> <bean id="stringRedisSerializer" class="org.springframework.data.redis.serializer.StringRedisSerializer" /> <bean id="stringRedisTemplate" class="org.springframework.data.redis.core.StringRedisTemplate" p:connectionFactory-ref="jedisConnFactory" /> <bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate" p:connectionFactory-ref="jedisConnFactory" p:keySerializer-ref="stringRedisSerializer" p:hashKeySerializer-ref="stringRedisSerializer" /> <!-- spring自己的缓存管理器 --> <bean id="cacheManager" class="org.springframework.cache.support.SimpleCacheManager"> <property name="caches"> <set> <bean class="com.rd.ifaes.common.jedis.RdRedisCache" p:redis-template-ref="redisTemplate" p:name="sysCache"/> </set> </property> </bean> <!-- 启用缓存注解功能,这个是必须的,否则注解不会生效,另外,该注解一定要声明在spring主配置文件中才会生效 --> <cache:annotation-driven cache-manager="cacheManager" proxy-target-class="true" />
2、缓存工具类CacheUtils
package com.lh.core.core.util; import java.util.Map; import java.util.Set; import java.util.concurrent.TimeUnit; import org.springframework.data.redis.core.BoundHashOperations; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.util.CollectionUtils; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.rd.ifaes.common.dict.ExpireTime; import com.lh.common.util.JsonMapper; import com.rd.ifaes.common.util.SpringContextHolder; import com.rd.ifaes.common.util.StringUtils; /** * 通用缓存工具类 * @author lh * @version 3.0 * @since 2016-6-22 * */ public class CacheUtils { private static StringRedisTemplate stringRedisTemplate = SpringContextHolder.getBean("stringRedisTemplate"); private static RedisTemplate<String, Object> redisTemplate = SpringContextHolder.getBean("redisTemplate"); /** * 删除缓存<br> * 根据key精确匹配删除 * @param key */ @SuppressWarnings("unchecked") public static void del(String... key){ if(key!=null && key.length > 0){ if(key.length == 1){ redisTemplate.delete(key[0]); }else{ redisTemplate.delete(CollectionUtils.arrayToList(key)); } } } /** * 批量删除<br> * (该操作会执行模糊查询,请尽量不要使用,以免影响性能或误删) * @param pattern */ public static void batchDel(String... pattern){ for (String kp : pattern) { redisTemplate.delete(redisTemplate.keys(kp + "*")); } } /** * 取得缓存(int型) * @param key * @return */ public static Integer getInt(String key){ String value = stringRedisTemplate.boundValueOps(key).get(); if(StringUtils.isNotBlank(value)){ return Integer.valueOf(value); } return null; } /** * 取得缓存(字符串类型) * @param key * @return */ public static String getStr(String key){ return stringRedisTemplate.boundValueOps(key).get(); } /** * 取得缓存(字符串类型) * @param key * @return */ public static String getStr(String key, boolean retain){ String value = stringRedisTemplate.boundValueOps(key).get(); if(!retain){ redisTemplate.delete(key); } return value; } /** * 获取缓存<br> * 注:基本数据类型(Character除外),请直接使用get(String key, Class<T> clazz)取值 * @param key * @return */ public static Object getObj(String key){ return redisTemplate.boundValueOps(key).get(); } /** * 获取缓存<br> * 注:java 8种基本类型的数据请直接使用get(String key, Class<T> clazz)取值 * @param key * @param retain 是否保留 * @return */ public static Object getObj(String key, boolean retain){ Object obj = redisTemplate.boundValueOps(key).get(); if(!retain){ redisTemplate.delete(key); } return obj; } /** * 获取缓存<br> * 注:该方法暂不支持Character数据类型 * @param key key * @param clazz 类型 * @return */ @SuppressWarnings("unchecked") public static <T> T get(String key, Class<T> clazz) { return (T)redisTemplate.boundValueOps(key).get(); } /** * 获取缓存json对象<br> * @param key key * @param clazz 类型 * @return */ public static <T> T getJson(String key, Class<T> clazz) { return JsonMapper.fromJsonString(stringRedisTemplate.boundValueOps(key).get(), clazz); } /** * 将value对象写入缓存 * @param key * @param value * @param time 失效时间(秒) */ public static void set(String key,Object value,ExpireTime time){ if(value.getClass().equals(String.class)){ stringRedisTemplate.opsForValue().set(key, value.toString()); }else if(value.getClass().equals(Integer.class)){ stringRedisTemplate.opsForValue().set(key, value.toString()); }else if(value.getClass().equals(Double.class)){ stringRedisTemplate.opsForValue().set(key, value.toString()); }else if(value.getClass().equals(Float.class)){ stringRedisTemplate.opsForValue().set(key, value.toString()); }else if(value.getClass().equals(Short.class)){ stringRedisTemplate.opsForValue().set(key, value.toString()); }else if(value.getClass().equals(Long.class)){ stringRedisTemplate.opsForValue().set(key, value.toString()); }else if(value.getClass().equals(Boolean.class)){ stringRedisTemplate.opsForValue().set(key, value.toString()); }else{ redisTemplate.opsForValue().set(key, value); } if(time.getTime() > 0){ redisTemplate.expire(key, time.getTime(), TimeUnit.SECONDS); } } /** * 将value对象以JSON格式写入缓存 * @param key * @param value * @param time 失效时间(秒) */ public static void setJson(String key,Object value,ExpireTime time){ stringRedisTemplate.opsForValue().set(key, JsonMapper.toJsonString(value)); if(time.getTime() > 0){ stringRedisTemplate.expire(key, time.getTime(), TimeUnit.SECONDS); } } /** * 更新key对象field的值 * @param key 缓存key * @param field 缓存对象field * @param value 缓存对象field值 */ public static void setJsonField(String key, String field, String value){ JSONObject obj = JSON.parseObject(stringRedisTemplate.boundValueOps(key).get()); obj.put(field, value); stringRedisTemplate.opsForValue().set(key, obj.toJSONString()); } /** * 递减操作 * @param key * @param by * @return */ public static double decr(String key, double by){ return redisTemplate.opsForValue().increment(key, -by); } /** * 递增操作 * @param key * @param by * @return */ public static double incr(String key, double by){ return redisTemplate.opsForValue().increment(key, by); } /** * 获取double类型值 * @param key * @return */ public static double getDouble(String key) { String value = stringRedisTemplate.boundValueOps(key).get(); if(StringUtils.isNotBlank(value)){ return Double.valueOf(value); } return 0d; } /** * 设置double类型值 * @param key * @param value * @param time 失效时间(秒) */ public static void setDouble(String key, double value, ExpireTime time) { stringRedisTemplate.opsForValue().set(key, String.valueOf(value)); if(time.getTime() > 0){ stringRedisTemplate.expire(key, time.getTime(), TimeUnit.SECONDS); } } /** * 设置double类型值 * @param key * @param value * @param time 失效时间(秒) */ public static void setInt(String key, int value, ExpireTime time) { stringRedisTemplate.opsForValue().set(key, String.valueOf(value)); if(time.getTime() > 0){ stringRedisTemplate.expire(key, time.getTime(), TimeUnit.SECONDS); } } /** * 将map写入缓存 * @param key * @param map * @param time 失效时间(秒) */ public static <T> void setMap(String key, Map<String, T> map, ExpireTime time){ redisTemplate.opsForHash().putAll(key, map); } /** * 将map写入缓存 * @param key * @param map * @param time 失效时间(秒) */ @SuppressWarnings("unchecked") public static <T> void setMap(String key, T obj, ExpireTime time){ Map<String, String> map = (Map<String, String>)JsonMapper.parseObject(obj, Map.class); redisTemplate.opsForHash().putAll(key, map); } /** * 向key对应的map中添加缓存对象 * @param key * @param map */ public static <T> void addMap(String key, Map<String, T> map){ redisTemplate.opsForHash().putAll(key, map); } /** * 向key对应的map中添加缓存对象 * @param key cache对象key * @param field map对应的key * @param value 值 */ public static void addMap(String key, String field, String value){ redisTemplate.opsForHash().put(key, field, value); } /** * 向key对应的map中添加缓存对象 * @param key cache对象key * @param field map对应的key * @param obj 对象 */ public static <T> void addMap(String key, String field, T obj){ redisTemplate.opsForHash().put(key, field, obj); } /** * 获取map缓存 * @param key * @param clazz * @return */ public static <T> Map<String, T> mget(String key, Class<T> clazz){ BoundHashOperations<String, String, T> boundHashOperations = redisTemplate.boundHashOps(key); return boundHashOperations.entries(); } /** * 获取map缓存 * @param key * @param clazz * @return */ public static <T> T getMap(String key, Class<T> clazz){ BoundHashOperations<String, String, String> boundHashOperations = redisTemplate.boundHashOps(key); Map<String, String> map = boundHashOperations.entries(); return JsonMapper.parseObject(map, clazz); } /** * 获取map缓存中的某个对象 * @param key * @param field * @param clazz * @return */ @SuppressWarnings("unchecked") public static <T> T getMapField(String key, String field, Class<T> clazz){ return (T)redisTemplate.boundHashOps(key).get(field); } /** * 删除map中的某个对象 * @author lh * @date 2016年8月10日 * @param key map对应的key * @param field map中该对象的key */ public void delMapField(String key, String... field){ BoundHashOperations<String, String, ?> boundHashOperations = redisTemplate.boundHashOps(key); boundHashOperations.delete(field); } /** * 指定缓存的失效时间 * * @author FangJun * @date 2016年8月14日 * @param key 缓存KEY * @param time 失效时间(秒) */ public static void expire(String key, ExpireTime time) { if(time.getTime() > 0){ redisTemplate.expire(key, time.getTime(), TimeUnit.SECONDS); } } /** * 添加set * @param key * @param value */ public static void sadd(String key, String... value) { redisTemplate.boundSetOps(key).add(value); } /** * 删除set集合中的对象 * @param key * @param value */ public static void srem(String key, String... value) { redisTemplate.boundSetOps(key).remove(value); } /** * set重命名 * @param oldkey * @param newkey */ public static void srename(String oldkey, String newkey){ redisTemplate.boundSetOps(oldkey).rename(newkey); } /** * 短信缓存 * @author fxl * @date 2016年9月11日 * @param key * @param value * @param time */ public static void setIntForPhone(String key,Object value,int time){ stringRedisTemplate.opsForValue().set(key, JsonMapper.toJsonString(value)); if(time > 0){ stringRedisTemplate.expire(key, time, TimeUnit.SECONDS); } } /** * 模糊查询keys * @param pattern * @return */ public static Set<String> keys(String pattern){ return redisTemplate.keys(pattern); } }
3、JsonMaper
package com.lh.common.util; import java.io.IOException; import java.util.TimeZone; import org.apache.commons.lang3.StringEscapeUtils; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.alibaba.fastjson.JSON; import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.core.JsonParser.Feature; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.JavaType; import com.fasterxml.jackson.databind.JsonSerializer; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.SerializationFeature; import com.fasterxml.jackson.databind.SerializerProvider; import com.fasterxml.jackson.databind.module.SimpleModule; import com.fasterxml.jackson.databind.util.JSONPObject; import com.fasterxml.jackson.module.jaxb.JaxbAnnotationModule; /** * 简单封装Jackson,实现JSON String<->Java Object的Mapper. * */ public class JsonMapper extends ObjectMapper { private static final long serialVersionUID = 1L; private final static Logger LOGGER = LoggerFactory.getLogger(JsonMapper.class); private static JsonMapper mapper; public JsonMapper() { this(Include.NON_EMPTY); } public JsonMapper(Include include) { // 设置输出时包含属性的风格 if (include != null) { this.setSerializationInclusion(include); } // 设置输入时忽略在JSON字符串中存在但Java对象实际没有的属性 this.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES); // 空值处理为空串 this.getSerializerProvider().setNullValueSerializer(new JsonSerializer<Object>(){ @Override public void serialize(Object value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException { jgen.writeString(""); } }); // 进行HTML解码。 this.registerModule(new SimpleModule().addSerializer(String.class, new JsonSerializer<String>(){ @Override public void serialize(String value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException { jgen.writeString(StringEscapeUtils.unescapeHtml4(value)); } })); // 设置时区 this.setTimeZone(TimeZone.getDefault());//getTimeZone("GMT+8:00") } /** * 创建只输出非Null且非Empty(如List.isEmpty)的属性到Json字符串的Mapper,建议在外部接口中使用. */ public static JsonMapper getInstance() { if (mapper == null){ mapper = new JsonMapper().enableSimple(); } return mapper; } /** * 创建只输出初始值被改变的属性到Json字符串的Mapper, 最节约的存储方式,建议在内部接口中使用。 */ public static JsonMapper nonDefaultMapper() { if (mapper == null){ mapper = new JsonMapper(Include.NON_DEFAULT); } return mapper; } /** * Object可以是POJO,也可以是Collection或数组。 * 如果对象为Null, 返回"null". * 如果集合为空集合, 返回"[]". */ public String toJson(Object object) { try { return this.writeValueAsString(object); } catch (IOException e) { if(LOGGER.isWarnEnabled()){ LOGGER.warn("write to json string error:" + object, e); } return null; } } /** * 反序列化POJO或简单Collection如List<String>. * * 如果JSON字符串为Null或"null"字符串, 返回Null. * 如果JSON字符串为"[]", 返回空集合. * * 如需反序列化复杂Collection如List<MyBean>, 请使用fromJson(String,JavaType) * @see #fromJson(String, JavaType) */ public <T> T fromJson(String jsonString, Class<T> clazz) { if (StringUtils.isEmpty(jsonString)) { return null; } try { return this.readValue(jsonString, clazz); } catch (IOException e) { if(LOGGER.isWarnEnabled()){ LOGGER.warn("parse json string error:" + jsonString, e); } return null; } } /** * 反序列化复杂Collection如List<Bean>, 先使用函數createCollectionType构造类型,然后调用本函数. * @see #createCollectionType(Class, Class...) */ @SuppressWarnings("unchecked") public <T> T fromJson(String jsonString, JavaType javaType) { if (StringUtils.isEmpty(jsonString)) { return null; } try { return (T) this.readValue(jsonString, javaType); } catch (IOException e) { if(LOGGER.isWarnEnabled()){ LOGGER.warn("parse json string error:" + jsonString, e); } return null; } } /** * 構造泛型的Collection Type如: * ArrayList<MyBean>, 则调用constructCollectionType(ArrayList.class,MyBean.class) * HashMap<String,MyBean>, 则调用(HashMap.class,String.class, MyBean.class) */ public JavaType createCollectionType(Class<?> collectionClass, Class<?>... elementClasses) { return this.getTypeFactory().constructParametricType(collectionClass, elementClasses); } /** * 當JSON裡只含有Bean的部分屬性時,更新一個已存在Bean,只覆蓋該部分的屬性. */ @SuppressWarnings("unchecked") public <T> T update(String jsonString, T object) { try { return (T) this.readerForUpdating(object).readValue(jsonString); } catch (JsonProcessingException e) { if(LOGGER.isWarnEnabled()){ LOGGER.warn("update json string:" + jsonString + " to object:" + object + " error.", e); } } catch (IOException e) { if(LOGGER.isWarnEnabled()){ LOGGER.warn("update json string:" + jsonString + " to object:" + object + " error.", e); } } return null; } /** * 輸出JSONP格式數據. */ public String toJsonP(String functionName, Object object) { return toJson(new JSONPObject(functionName, object)); } /** * 設定是否使用Enum的toString函數來讀寫Enum, * 為False時時使用Enum的name()函數來讀寫Enum, 默認為False. * 注意本函數一定要在Mapper創建後, 所有的讀寫動作之前調用. */ public JsonMapper enableEnumUseToString() { this.enable(SerializationFeature.WRITE_ENUMS_USING_TO_STRING); this.enable(DeserializationFeature.READ_ENUMS_USING_TO_STRING); return this; } /** * 支持使用Jaxb的Annotation,使得POJO上的annotation不用与Jackson耦合。 * 默认会先查找jaxb的annotation,如果找不到再找jackson的。 */ public JsonMapper enableJaxbAnnotation() { JaxbAnnotationModule module = new JaxbAnnotationModule(); this.registerModule(module); return this; } /** * 允许单引号 * 允许不带引号的字段名称 */ public JsonMapper enableSimple() { this.configure(Feature.ALLOW_SINGLE_QUOTES, true); this.configure(Feature.ALLOW_UNQUOTED_FIELD_NAMES, true); return this; } /** * 取出Mapper做进一步的设置或使用其他序列化API. */ public ObjectMapper getMapper() { return this; } /** * 对象转换为JSON字符串 * @param object * @return */ public static String toJsonString(Object object){ return JsonMapper.getInstance().toJson(object); } /** * JSON字符串转换为对象 * @param jsonString * @param clazz * @return */ public static <T> T fromJsonString(String jsonString, Class<T> clazz){ return JsonMapper.getInstance().fromJson(jsonString, clazz); } /** * 将obj对象转换成 class类型的对象 * @param obj * @param clazz * @return */ public static <T> T parseObject(Object obj, Class<T> clazz){ return JSON.parseObject(JSON.toJSONString(obj), clazz); } }
相关推荐
内容概要:本文详细介绍了基于MATLAB GUI界面和卷积神经网络(CNN)的模糊车牌识别系统。该系统旨在解决现实中车牌因模糊不清导致识别困难的问题。文中阐述了整个流程的关键步骤,包括图像的模糊还原、灰度化、阈值化、边缘检测、孔洞填充、形态学操作、滤波操作、车牌定位、字符分割以及最终的字符识别。通过使用维纳滤波或最小二乘法约束滤波进行模糊还原,再利用CNN的强大特征提取能力完成字符分类。此外,还特别强调了MATLAB GUI界面的设计,使得用户能直观便捷地操作整个系统。 适合人群:对图像处理和深度学习感兴趣的科研人员、高校学生及从事相关领域的工程师。 使用场景及目标:适用于交通管理、智能停车场等领域,用于提升车牌识别的准确性和效率,特别是在面对模糊车牌时的表现。 其他说明:文中提供了部分关键代码片段作为参考,并对实验结果进行了详细的分析,展示了系统在不同环境下的表现情况及其潜在的应用前景。
嵌入式八股文面试题库资料知识宝典-计算机专业试题.zip
嵌入式八股文面试题库资料知识宝典-C and C++ normal interview_3.zip
内容概要:本文深入探讨了一款额定功率为4kW的开关磁阻电机,详细介绍了其性能参数如额定功率、转速、效率、输出转矩和脉动率等。同时,文章还展示了利用RMxprt、Maxwell 2D和3D模型对该电机进行仿真的方法和技术,通过外电路分析进一步研究其电气性能和动态响应特性。最后,文章提供了基于RMxprt模型的MATLAB仿真代码示例,帮助读者理解电机的工作原理及其性能特点。 适合人群:从事电机设计、工业自动化领域的工程师和技术人员,尤其是对开关磁阻电机感兴趣的科研工作者。 使用场景及目标:适用于希望深入了解开关磁阻电机特性和建模技术的研究人员,在新产品开发或现有产品改进时作为参考资料。 其他说明:文中提供的代码示例仅用于演示目的,实际操作时需根据所用软件的具体情况进行适当修改。
少儿编程scratch项目源代码文件案例素材-剑客冲刺.zip
少儿编程scratch项目源代码文件案例素材-几何冲刺 转瞬即逝.zip
内容概要:本文详细介绍了基于PID控制器的四象限直流电机速度驱动控制系统仿真模型及其永磁直流电机(PMDC)转速控制模型。首先阐述了PID控制器的工作原理,即通过对系统误差的比例、积分和微分运算来调整电机的驱动信号,从而实现转速的精确控制。接着讨论了如何利用PID控制器使有刷PMDC电机在四个象限中精确跟踪参考速度,并展示了仿真模型在应对快速负载扰动时的有效性和稳定性。最后,提供了Simulink仿真模型和详细的Word模型说明文档,帮助读者理解和调整PID控制器参数,以达到最佳控制效果。 适合人群:从事电力电子与电机控制领域的研究人员和技术人员,尤其是对四象限直流电机速度驱动控制系统感兴趣的读者。 使用场景及目标:适用于需要深入了解和掌握四象限直流电机速度驱动控制系统设计与实现的研究人员和技术人员。目标是在实际项目中能够运用PID控制器实现电机转速的精确控制,并提高系统的稳定性和抗干扰能力。 其他说明:文中引用了多篇相关领域的权威文献,确保了理论依据的可靠性和实用性。此外,提供的Simulink模型和Word文档有助于读者更好地理解和实践所介绍的内容。
嵌入式八股文面试题库资料知识宝典-2013年海康威视校园招聘嵌入式开发笔试题.zip
少儿编程scratch项目源代码文件案例素材-驾驶通关.zip
小区开放对周边道路通行能力影响的研究.pdf
内容概要:本文探讨了冷链物流车辆路径优化问题,特别是如何通过NSGA-2遗传算法和软硬时间窗策略来实现高效、环保和高客户满意度的路径规划。文中介绍了冷链物流的特点及其重要性,提出了软时间窗概念,允许一定的配送时间弹性,同时考虑碳排放成本,以达到绿色物流的目的。此外,还讨论了如何将客户满意度作为路径优化的重要评价标准之一。最后,通过一段简化的Python代码展示了遗传算法的应用。 适合人群:从事物流管理、冷链物流运营的专业人士,以及对遗传算法和路径优化感兴趣的科研人员和技术开发者。 使用场景及目标:适用于冷链物流企业,旨在优化配送路线,降低运营成本,减少碳排放,提升客户满意度。目标是帮助企业实现绿色、高效的物流配送系统。 其他说明:文中提供的代码仅为示意,实际应用需根据具体情况调整参数设置和模型构建。
少儿编程scratch项目源代码文件案例素材-恐怖矿井.zip
内容概要:本文详细介绍了基于STM32F030的无刷电机控制方案,重点在于高压FOC(磁场定向控制)技术和滑膜无感FOC的应用。该方案实现了过载、过欠压、堵转等多种保护机制,并提供了完整的源码、原理图和PCB设计。文中展示了关键代码片段,如滑膜观测器和电流环处理,以及保护机制的具体实现方法。此外,还提到了方案的移植要点和实际测试效果,确保系统的稳定性和高效性。 适合人群:嵌入式系统开发者、电机控制系统工程师、硬件工程师。 使用场景及目标:适用于需要高性能无刷电机控制的应用场景,如工业自动化设备、无人机、电动工具等。目标是提供一种成熟的、经过验证的无刷电机控制方案,帮助开发者快速实现并优化电机控制性能。 其他说明:提供的资料包括详细的原理图、PCB设计文件、源码及测试视频,方便开发者进行学习和应用。
基于有限体积法Godunov格式的管道泄漏检测模型研究.pdf
嵌入式八股文面试题库资料知识宝典-CC++笔试题-深圳有为(2019.2.28)1.zip
少儿编程scratch项目源代码文件案例素材-几何冲刺 V1.5.zip
Android系统开发_Linux内核配置_USB-HID设备模拟_通过root权限将Android设备转换为全功能USB键盘的项目实现_该项目需要内核支持configFS文件系统
C# WPF - LiveCharts Project
少儿编程scratch项目源代码文件案例素材-恐怖叉子 动画.zip
嵌入式八股文面试题库资料知识宝典-嵌⼊式⼯程师⾯试⾼频问题.zip