摘要
日常开发中,需要用到各种各样的框架来实现API、系统的构建。作为程序员,除了会使用框架还必须要了解框架工作的原理。这样可以便于我们排查问题,和自定义的扩展。那么如何去学习框架呢。通常我们通过阅读文档、查看源码,然后又很快忘记。始终不能融汇贯通。本文主要基于Spring Cache扩展为例,介绍如何进行高效的源码阅读。
SpringCache的介绍
为什么以Spring Cache为例呢,原因有两个
Spring框架是web开发最常用的框架,值得开发者去阅读代码,吸收思想
缓存是企业级应用开发必不可少的,而随着系统的迭代,我们可能会需要用到内存缓存、分布式缓存。那么Spring Cache作为胶水层,能够屏蔽掉我们底层的缓存实现。
一句话解释Spring Cache: 通过注解的方式,利用AOP的思想来解放缓存的管理。
step1 查看文档
首先通过查看官方文档,概括了解Spring Cache https://docs.spring.io/spring- boot/docs/current/reference/html/boot-features-caching.html
重点两点
两个接口抽象 Cache
, CacheManager
,具体的实现都是基于这两个抽象实现。典型的SPI机制,和eat your dog food。当需要提供接口给外部调用,首先自己内部的实现也必须基于同样一套抽象机制
The cache abstraction does not provide an actual store and relies on abstraction materialized by the org.springframework.cache.Cache and org.springframework.cache.CacheManager interfaces.
Spring Cache提供了这些缓存的实现,如果没有一种 CacheManage
,或者 CacheResolver
,会按照指定的顺序去实现
If you have not defined a bean of type CacheManager or a CacheResolver named cacheResolver (see CachingConfigurer), Spring Boot tries to detect the following providers (in the indicated order): 1.Generic 2.JCache (JSR-107) (EhCache 3, Hazelcast, Infinispan, and others) 3.EhCache 2.x 4.Hazelcast 5.Infinispan 6.Couchbase 7.Redis 8.Caffeine 9.Simple
step2 run demo
对Spring Cache有了一个大概的了解后,我们首先使用起来,跑个demo。
定义一个用户查询方法
1. @Component
2. public class CacheSample {
3. @Cacheable(cacheNames = "users")
4. public Map getUser(final Collection userIds) {
5. System.out.println("not cache");
6. final Map mapUser = new HashMap<>();
7. userIds.forEach(userId -> {
8. mapUser.put(userId, User.builder().userId(userId).name("name").build());
9. });
10. return mapUser;
11. }
配置一个CacheManager
1. @Configuration
2. public class CacheConfig {
3. @Primary
4. @Bean(name = { "cacheManager" })
5. public CacheManager getCache() {
6. return new ConcurrentMapCacheManager("users");
7. }
API调用
1. @RestController
2. @RequestMapping("/api/cache")
3. public class CacheController {
4. @Autowired
5. private CacheSample cacheSample;
6. @GetMapping("/user/v1/1")
7. public List getUser() {
8. return cacheSample.getUser(Arrays.asList(1L,2L)).values().stream().collect(Collectors.toList());
9. }
10. }
step3 debug 查看实现
demo跑起来后,就是debug看看代码如何实现的了。因为直接看源代码的,没有调用关系,看起来会一头雾水。通过debug能够使你更快了解一个实现。
通过debug我们会发现主要控制逻辑是在切面CacheAspectSupport 会先根据cache key找缓存数据,没有的话put进去。
1. // Check if we have a cached item matching the conditions
2. Cache.ValueWrapper cacheHit = findCachedItem(contexts.get(CacheableOperation.class));
3. 4. // Collect puts from any @Cacheable miss, if no cached item is found
5. List cachePutRequests = new LinkedList<>();
6. if (cacheHit == null) {
7. collectPutRequests(contexts.get(CacheableOperation.class),
8. CacheOperationExpressionEvaluator.NO_RESULT, cachePutRequests);
9. }
step4 实现扩展
知道如何使用Spring Cache后,我们需要进一步思考,就是如何扩展。那么带着问题出发。比如Spring Cache不支持批量key的缓存,像上文我们举的例子,我们希望缓存的key是userId,而不是CollectionuserIds。以userId为key,这样的缓存命中率更高,存储的成本更小。
1. @Cacheable(cacheNames = "users")
2. public Map getUser(final Collection userIds) {
所以我们要实现对Spring Cache进行扩展。step3中我们已经大致了解了Spring Cache的实现。那么实现这个扩展的功能就是拆分CollectionuserIds,缓存命中的从缓存中获取,没有命中的,调用源方法。
1. @Aspect
2. @Component
3. public class CacheExtenionAspect {
4. 5. @Autowired
6. private CacheExtensionManage cacheExtensionManage;
7. 8. /**
9. * 返回的结果中缓存命中的从缓存中获取,没有命中的调用原来的方法获取
10. * @param joinPoint
11. * @return
12. */
13. @Around("@annotation(org.springframework.cache.annotation.Cacheable)")
14. @SuppressWarnings("unchecked")
15. public Object aroundCache(final ProceedingJoinPoint joinPoint) {
16. 17. // 修改掉Collection值,cacheResult需要重新构造一个
18. args[0] = cacheResult.getMiss();
19. try {
20. final Map notHit = CollectionUtils.isEmpty(cacheResult.getMiss()) ? null
21. : (Map) (method.invoke(target, args));
22. final Map hits = cacheResult.getHit();
23. if (Objects.isNull(notHit)) {
24. return hits;
25. }
26. // 设置缓存
27. cacheResult.getCache().putAll(notHit);
28. hits.putAll(notHit);
29. return hits;
30. }
31. }
然后扩展 Cache
, CacheManage
重写Cache的查找缓存方法,返回新的CacheResult
1. public static Object lookup(final CacheExtension cache, final Object key) {
2. if (key instanceof Collection) {
3. final Collection originalKeys = ((Collection) key);
4. if (originalKeys == null || originalKeys.isEmpty()) {
5. return CacheResult.builder().cache(cache).miss(
6. Collections.emptySet())
7. .build();
8. }
9. final List keys = originalKeys.stream()
10. .filter(Objects::nonNull).collect(Collectors.toList());
11. final Map hits = cache.getAll(keys);
12. final Set miss = new HashSet(keys);
13. miss.removeAll(hits.keySet());
14. return CacheResult.builder().cache(cache).hit(hits).miss(miss).build();
15. }
16. return null;
17. }
CacheResult就是新的缓存结果格式
1. @Builder
2. @Setter
3. @Getter
4. static class CacheResult {
5. final CacheExtension cache;
6. // 命中的缓存结果
7. final Map hit;
8. // 需要重新调用源方法的keys
9. private Set miss;
10. }
然后扩展CacheManager,没什么重写,就是自定义一种manager类型 为缓存指定新的CacheManager
1. @Primary
2. @Bean
3. public CacheManager getExtensionCache() {
4. return new CacheExtensionManage("users2");
5. }
总结
本文主要介绍一种源码学习方法,纯属抛砖引玉,如果你有好的方法,欢迎分享。
你可能感兴趣的:(如何进行高效的SpringBoot源码阅读)
【Java】代理模式
非 白
代理模式 java 开发语言
代理模式代理模式是指给某一个对象提供一个代理,并由代理对象来控制对真实对象的访问代理模式是一种结构型设计模式背景如果不采用代理,对一个类的多个方法进行监控时,重复的代码总是重复出现,不但破坏了原方法,如果要实现多个监控,将会对代码造成大量冗余。同时,还导致业务代码,与非业务的监控代码掺杂在一起,不利于扩展和维护。代理类在无限制膨胀,就需要无限的修改业务代码。而采用代理后,原方法不需要做任何改动,操
1-刷力扣问题记录
leaf_leaves_leaf
算法 数据结构
25.1.191.size()和.length()有什么区别2.result.push_back({nums[i],nums[left],nums[right]});为什么用大括号?使用大括号{}是C++11引入的初始化列表语法,它允许我们在构造或初始化对象时直接传入一组值。大括号的使用在许多情况下都能让代码更加简洁和直观。{nums[i],nums[left],nums[right]}是一个初始
国外7个最佳大语言模型 (LLM) API推荐
程序员后端
大型语言模型(LLM)API将彻底改变我们处理语言的方式。在深度学习和机器学习算法的支持下,LLMAPI提供了前所未有的自然语言理解能力。通过利用这些新的API,开发人员现在可以创建能够以前所未有的方式理解和响应书面文本的应用程序。下面,我们将比较从Bard到ChatGPT、PaLM等市场上顶级LLMAPI。我们还将探讨整合这些LLM的潜在用例,并考虑其对语言处理的影响。什么是大语言模型(LLM)
QT界面自适应
天生爱打工
qt qt 开发语言
一自适应工具类介绍:1.1功能控件能跟随界面大小的变化实现字体、大小同比例的变化1.2优点控件大小,字体可跟随界面大小同比例任意变化。同一套程序能兼容不同分辨率及不同DPI的显示器对于控件数目固定不变的UI区域:只需要将控件拖拽到指定位置即可,不需要使用弹簧及布局等qt属性对于控件数目有可能会根据需求变化的UI区域:可以使用qt原有的布局,但解放了qt原有布局中不能改变字体的属性。二自适应工具类使
[QT] 断点调试
天生爱打工
qt qt 开发语言
目录一设置断点二调试窗口信息2.1默认窗口2.2详细窗口属性三调试方法和技巧一设置断点在QtCreator中我们有两种方式添加断点。用鼠标直接点击代码编辑窗口中的某一行按下F9添加/取消断点(操作的是当前鼠标光标所在的代码行)二调试窗口信息2.1默认窗口这里列出几个默认的窗口红色圆点表示断点,黄色箭头表示当前程序运行位置。stack:堆栈表示当前函数之间的调用关系,比如位于哪个函数体中。Local
百度地图显示多个infoWindow信息窗口时只展示最后一条数据
射手buff
前端 百度
这两天遇到一个问题,百度地图在循环加载多个信息窗口的时候所有的窗口显示的都是最后一条数据的内容效果如下:如图所示两个信息窗口都是一样的值,代码如下$.ajax({type:"POST",url:"../api/zhandian.json",success:function(res){vardata=res.data;for(vari=0;i联系电话:"+data[i].phone,opts);//
责任链模式原理详解和源码实例以及Spring AOP拦截器链的执行源码如何使用责任链模式?
一个儒雅随和的男子
spring 设计模式 责任链模式 spring java
前言 本文首先介绍了责任链的基本原理,并附带一个例子说明责任链模式,确保能够理解责任链的前提下,在进行SpringAOP执行责任链的源码分析。责任链模式允许将多个处理对象连接成链,请求沿着链传递,直到被处理或结束。每个处理者可以选择处理请求或传递给下一个。 SpringAOP的拦截器链,拦截器或者过滤器链,都是典型的责任链应用。比如,当一个方法被调用时,多个拦截器按顺序执行,每个拦截器可以决定
【部署】Ktransformer是什么、如何利用单卡24GB显存部署Deepseek-R1 和 Deepseek-V3
仙人掌_lz
人工智能 人工智能 AI 部署 自然语言处理
简介KTransformers是一个灵活的、以Python为中心的框架,旨在通过先进的内核优化和放置/并行策略提升HuggingFaceTransformers的使用体验。它具有高度的可扩展性,用户可通过单行代码注入优化模块,获得兼容Transformers的接口、符合OpenAI和Ollama的RESTfulAPI,甚至简化的ChatGPT风格的WebUI。KTransformers的性能优化基
深圳SMT贴片加工厂家核心技术及服务优势解析
安德胜SMT贴片
其他
内容概要在电子制造领域,高效、精准的生产能力已成为企业保持竞争力的关键要素。如何通过技术创新与服务优化实现快速交付与品质保障,是当前行业关注的核心议题。深圳作为国内电子制造产业的重要聚集地,其SMT贴片加工厂家通过持续的技术迭代与服务升级,形成了独特的市场竞争力。本文将系统解析该类企业在核心技术与服务模式上的突破路径,涵盖设备精度提升、工艺创新、品控体系完善等关键维度。首先,高精度贴片设备与智能化
SMT贴片加工报价构成要素与成本优化策略解析
安德胜SMT贴片
其他
内容概要在现代电子制造领域,SMT贴片加工报价的精准核算直接影响企业供应链成本控制效能。本文通过结构化分析框架,系统解构报价体系的五大核心要素,并建立可操作的优化模型。研究路径覆盖从基材选型到生产规划的完整价值链,重点揭示各环节成本动因的相互作用机制。为直观呈现报价要素的关联性,特构建以下参数对照表:要素类别成本占比范围关键波动因素优化切入点PCB基材成本15-25%层数/板材类型/表面处理工艺标
技术分享:MyBatis SQL 日志解析脚本
£漫步 云端彡
运维趣分享 sql java mybatis 日志解析
技术分享:MyBatisSQL日志解析脚本1.脚本功能概述2.实现细节2.1HTML结构2.2JavaScript逻辑3.脚本代码4.使用方法4.1示例5.总结在日常开发中,使用MyBatis作为持久层框架时,我们经常需要查看SQL日志以调试和优化查询。然而,MyBatis的日志输出通常包含占位符和参数信息,这使得直接执行这些SQL语句变得困难。为了解决这个问题,我们开发了一个简单的HTML和Ja
SMT贴片生产的发展趋势与技术创新解析
安德胜SMT贴片
人工智能
内容概要SMT贴片生产作为现代电子制造的重要组成部分,其发展一直颇具前景与活力。当前,行业内的技术进步与市场需求的快速变化使得SMT贴片生产面临新的机遇与挑战。尤其是在自动化技术方面,许多企业逐步引入更加智能化的设备,从而提升生产效率并降低人为错误。这不仅能够缩短生产周期,还能提高产品的一致性和可靠性。另外,材料科技的进步也促进了SMT贴片生产的变革。新型材料的应用,例如高电导率材料和环保型焊料,
C语言-回调函数的应用
woainizhongguo.
C/C++ c语言
什么是回调函数回调函数就是一个被作为参数传递的函数。在C语言中,回调函数只能使用函数指针实现,在C++、Python、ECMAScript等更现代的编程语言中还可以使用仿函数或匿名函数。工作机制⑴定义一个回调函数;⑵提供函数实现的一方在初始化的时候,将回调函数的函数指针注册给调用者;⑶当特定的事件或条件发生的时候,调用者使用函数指针调用回调函数对事件进行处理。应用案例(1)应用层:通过调用hal层
技术爱好者不容错过!探秘 Thrive 现代化博客管理系统
秋野酱
前端 课程设计 java 开源 java spring boot vue.js 课程设计
探索ThriveX:现代化博客管理系统的技术与实现在当今数字化时代,知识的分享与交流变得愈发重要。对于技术爱好者和从业者而言,一个优质的博客管理系统不仅是知识输出的窗口,更是思想碰撞的平台。今天,让我们一同走进ThriveX,领略其独特的魅力。一、开源助力,点亮项目之星开源的道路充满艰辛与挑战,每一段代码都凝聚着开发者的心血。如果您在了解ThriveX的过程中有所收获,不妨花费短短10秒钟,为这个
C语言结构体学习笔记
BUG 劝退师
c语言 c语言 学习 笔记
C语言结构体学习笔记目录结构体基本概念结构体变量定义结构体初始化结构体数组结构体指针共用体枚举类型typedef自定义类型总结结构体基本概念1.什么是结构体?结构体:一种用户自定义的数据类型,用于将多个不同类型的变量组合成一个整体。用途:表示复杂数据(如学生信息:学号、姓名、成绩等)。2.结构体定义struct结构体名{数据类型成员1;数据类型成员2;//可以嵌套结构体struct子结构体名子成员
mds_stores不能关闭
nicekwell
mac mac mds_stores alfred
有次发现mds_stores占用了很高的cpu,网上有人建议把它关掉:sudomdutil-a-ioff关掉之后发现alfred不能找到新安装的应用了,所以最好还是不要关掉。sudomdutil-a-ion
解决win11下taskmgr放在“启动”文件夹中无法自启动问题
nicekwell
windows的使用 windows
https://superuser.com/questions/1647652/why-the-task-manager-automatically-does-not-start-from-the-startup-folder-at-usewindows中设置开机自动启动的常用方法是把要启动的程序或文件的快捷方式放到C:\Users\\AppData\Roaming\Microsoft\Windo
ubuntu下vscode ctrl+tab松开ctrl后不自动选中文件
nicekwell
ubuntu vscode linux
vscode用ctrl+tab切换文件时,松开ctrl键后会自动选中切换的文件。但是在ubuntu下发现有时不能自动选中切换的文件,需要再次按enter键才能打开文件。经过测试发现解决方法有两个:方法1:确认wayland状态,关闭wayland。(编辑/etc/gdm3/custom.conf,设置WaylandEnable=false)方法2:我用tweaks调换了capslock和ctrl,
Tomcat 8 安装包下载
m0_74824517
面试 学习路线 阿里巴巴 tomcat java
Tomcat8安装包下载【下载地址】Tomcat8安装包下载本仓库提供了一个包含Windows和Linux版本的Tomcat8安装包,方便用户快速下载并部署Tomcat8服务器[这里是图片001]项目地址:https://gitcode.com/open-source-toolkit/fda7c简介本仓库提供了一个包含Windows和Linux版本的Tomcat8安装包,方便用户快速下载并部署To
前端:纯前端快速实现html导出word和pdf
m0_74823715
前端 html word
实现html导出word,需要使用两个库。html-docx-js和file-saver导出word的js方法>npminstallhtml-docx-js>npminstallfile-saverjs引入importFileSaverfrom“file-saver”;importhtmlDocxfrom“html-docx-js/dist/html-docx”;/**导出word方法*/expo
Python Union 联合类型注解详解
人才程序员
杂谈 python 服务器 java linux 后端 软件工程 开发语言
文章目录PythonUnion联合类型注解详解1.什么是Union联合类型?**语法(Python3.9及之前版本)**:**语法(Python3.10及之后版本)**:2.Union联合类型注解示例**(1)使用Union来表示多个类型的参数****(2)使用`|`来表示联合类型(Python3.10及之后版本)**3.使用Union进行复杂类型注解**(1)使用Union与列表结合****(2
Ubuntu22.4.03服务器版安装及搭建深度学习环境的问题总结
蜡笔小祎在线学习
问题集合 深度学习 人工智能
Ubuntu22.4.03服务器版安装流程整个流程已经有很多分享帖了,这里概述一下:下载iso制作启动U盘,按f2进入安装,选择语言,键盘布局english,ubuntuserver安装,DHCP自动配置网络(问题1),代理服务器我们没填,配置阿里云镜源http://mirrors.aliyun.com/ubuntu/,磁盘分区(问题2),设置服务器密码,安装ssh远程工具,重启reboot。可参
macOS Catalina 10.15 - 新增功能及其他信息记录
伊织code
Apple 开发+ 10.15 macOS Catalina Sidecar
文章目录推荐阅读参考一、基本信息WWDC2019壁纸二、beta版本安装macOS10.15Xcode11三、新功能添加屏幕使用时间iPadOS应用可在Mac上运行APFS宗卷被拆分为只读的系统宗卷(System)和用户数据宗卷(Data)增加Findmy查找添加由Siri控制的「捷径」和「屏幕时间」AppleWatch可解锁MacSidecar:将iPad作为副显示屏四、其他变更终端shell建
PCB 打样哪家好?探寻专业猎板之选
lboyj
运维
在电子产业蓬勃发展的当下,PCB(印制电路板)作为电子产品的关键组成部分,其打样质量对于产品的研发和后续生产至关重要。对于众多电子工程师和企业而言,寻找一家可靠的PCB打样厂商是一项重要且具有挑战性的任务。那么,PCB打样究竟哪家好呢?接下来,让我们从多个维度来探讨这一问题,并深入了解猎板PCB在其中的表现。一、品质保障是基石优质的PCB打样,首先体现在品质上。从原材料的选择到生产工艺的把控,每一
猎板 PCB:HDI 技术精要解读
lboyj
人工智能
HDI技术凭借增加盲埋孔的方式,达成了高密度布局,在高端服务器、智能手机、多功能POS机以及安防摄像机等诸多领域均有广泛应用。尤其在通讯和计算机行业中,对HDI线路板有着较高的需求,这在一定程度上有力地推动了科技的持续进步,使得HDI板在国内市场展现出十分乐观的发展前景。然而,HDI技术作为一种特殊工艺,也面临诸多挑战。一方面,其成本相对较高;另一方面,对制造商的生产能力有着严格要求。倘若缺乏先进
Spring Bean 生命周期详解
黑风风
java 多线程 spring java 数据库
SpringBean生命周期详解在Spring框架中,Bean的生命周期由Spring容器全权管理。了解和掌握Bean的生命周期对于使用Spring开发稳定且高效的应用程序至关重要。本文将详细介绍SpringBean生命周期的五个主要阶段:实例化、属性注入、初始化、使用和销毁,并涵盖各个阶段的关键步骤和扩展点。1.实例化(Instantiation)实例化阶段包括以下关键步骤:BeanNameAw
OpenAI揭示o3的推理过程,以弥合与DeepSeek-R1的差距
c++服务器开发
人工智能 deepseek
生成式人工智能开发商OpenAI公司首席执行官SamAltman最近在RedditAMA问答活动中承认,该公司在开源软件研究方面站在了“历史错误的一边”。尽管OpenAI公司尚未发布其开源模型,但已经迈出了提高透明度的第一步。正如该公司在其X帐号上所宣布的那样,其最新的推理模型o3-mini现在展示了其思维链(CoT)跟踪的更详细版本。此前,OpenAI公司的推理模型仅展示了CoT的高级概述,这使
对于一个程序员来说,电脑的内存需要多大?
c++服务器开发
电脑
1、程序员电脑内存有多大内存够用足够了,纯写代码的编程对电脑要求不高,尤其对显卡几乎没有要求,一般编程可能开的任务窗口比较多,所以只要cpu和内存大点就可以了一般来说,处理器确实比显卡来得重要一些,因为我们的电脑中只配备了一块处理器,而处理器内置正正好有内置了一个核心显卡,如果没有特别需求我们无需再次购买独立显卡,但是对于游戏玩家来说,独立显卡显得重要一些,有的人甚至不惜下血本去配备多块显卡。2、
释放 DeepSeek 的力量:像专家一样本地安装与探索!
guzhoumingyue
AI python
要在本地运行DeepSeek,您需要遵循以下步骤。请确保您的计算机上已安装Python和Git,并且满足DeepSeek的依赖项。步骤1:安装依赖项安装Python和pip确保您已安装Python(建议使用Python3.6及以上版本)。您可以通过在终端/命令提示符中输入以下命令来检查Python是否已安装:bash复制代码python--version或者bash复制代码python3--ver
国鑫DeepSeek 671B本地部署方案:以高精度、高性价比重塑AI推理新标杆
Gooxi国鑫
人工智能 服务器
随着DeepSeek大模型应用火爆全球,官方服务器总是被挤爆。而且基于企业对数据安全、网络、算力的更高需求,模型本地化部署的需求日益增长,如何在有限预算内实现高效、精准的AI推理能力,成为众多企业的核心诉求。国鑫作为深耕AI领域的技术先锋,推出基于4台48GRTX4090或8台24GRTX4090服务器的2套DeepSeek“满血”版本地部署方案,以FP16高精度、高性价比、强扩展性三大优势,为企
解线性方程组
qiuwanchi
package gaodai.matrix;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class Test {
public static void main(String[] args) {
Scanner scanner = new Sc
在mysql内部存储代码
annan211
性能 mysql 存储过程 触发器
在mysql内部存储代码
在mysql内部存储代码,既有优点也有缺点,而且有人倡导有人反对。
先看优点:
1 她在服务器内部执行,离数据最近,另外在服务器上执行还可以节省带宽和网络延迟。
2 这是一种代码重用。可以方便的统一业务规则,保证某些行为的一致性,所以也可以提供一定的安全性。
3 可以简化代码的维护和版本更新。
4 可以帮助提升安全,比如提供更细
Android使用Asynchronous Http Client完成登录保存cookie的问题
hotsunshine
android
Asynchronous Http Client是android中非常好的异步请求工具
除了异步之外还有很多封装比如json的处理,cookie的处理
引用
Persistent Cookie Storage with PersistentCookieStore
This library also includes a PersistentCookieStore whi
java面试题
Array_06
java 面试
java面试题
第一,谈谈final, finally, finalize的区别。
final-修饰符(关键字)如果一个类被声明为final,意味着它不能再派生出新的子类,不能作为父类被继承。因此一个类不能既被声明为 abstract的,又被声明为final的。将变量或方法声明为final,可以保证它们在使用中不被改变。被声明为final的变量必须在声明时给定初值,而在以后的引用中只能
网站加速
oloz
网站加速
前序:本人菜鸟,此文研究总结来源于互联网上的资料,大牛请勿喷!本人虚心学习,多指教.
1、减小网页体积的大小,尽量采用div+css模式,尽量避免复杂的页面结构,能简约就简约。
2、采用Gzip对网页进行压缩;
GZIP最早由Jean-loup Gailly和Mark Adler创建,用于UNⅨ系统的文件压缩。我们在Linux中经常会用到后缀为.gz
正确书写单例模式
随意而生
java 设计模式 单例
单例模式算是设计模式中最容易理解,也是最容易手写代码的模式了吧。但是其中的坑却不少,所以也常作为面试题来考。本文主要对几种单例写法的整理,并分析其优缺点。很多都是一些老生常谈的问题,但如果你不知道如何创建一个线程安全的单例,不知道什么是双检锁,那这篇文章可能会帮助到你。
懒汉式,线程不安全
当被问到要实现一个单例模式时,很多人的第一反应是写出如下的代码,包括教科书上也是这样
单例模式
香水浓
java
懒汉 调用getInstance方法时实例化
public class Singleton {
private static Singleton instance;
private Singleton() {}
public static synchronized Singleton getInstance() {
if(null == ins
安装Apache问题:系统找不到指定的文件 No installed service named "Apache2"
AdyZhang
apache http server
安装Apache问题:系统找不到指定的文件 No installed service named "Apache2"
每次到这一步都很小心防它的端口冲突问题,结果,特意留出来的80端口就是不能用,烦。
解决方法确保几处:
1、停止IIS启动
2、把端口80改成其它 (譬如90,800,,,什么数字都好)
3、防火墙(关掉试试)
在运行处输入 cmd 回车,转到apa
如何在android 文件选择器中选择多个图片或者视频?
aijuans
android
我的android app有这样的需求,在进行照片和视频上传的时候,需要一次性的从照片/视频库选择多条进行上传
但是android原生态的sdk中,只能一个一个的进行选择和上传。
我想知道是否有其他的android上传库可以解决这个问题,提供一个多选的功能,可以使checkbox之类的,一次选择多个 处理方法
官方的图片选择器(但是不支持所有版本的androi,只支持API Level
mysql中查询生日提醒的日期相关的sql
baalwolf
mysql
SELECT sysid,user_name,birthday,listid,userhead_50,CONCAT(YEAR(CURDATE()),DATE_FORMAT(birthday,'-%m-%d')),CURDATE(), dayofyear( CONCAT(YEAR(CURDATE()),DATE_FORMAT(birthday,'-%m-%d')))-dayofyear(
MongoDB索引文件破坏后导致查询错误的问题
BigBird2012
mongodb
问题描述:
MongoDB在非正常情况下关闭时,可能会导致索引文件破坏,造成数据在更新时没有反映到索引上。
解决方案:
使用脚本,重建MongoDB所有表的索引。
var names = db.getCollectionNames();
for( var i in names ){
var name = names[i];
print(name);
Javascript Promise
bijian1013
JavaScript Promise
Parse JavaScript SDK现在提供了支持大多数异步方法的兼容jquery的Promises模式,那么这意味着什么呢,读完下文你就了解了。
一.认识Promises
“Promises”代表着在javascript程序里下一个伟大的范式,但是理解他们为什么如此伟大不是件简
[Zookeeper学习笔记九]Zookeeper源代码分析之Zookeeper构造过程
bit1129
zookeeper
Zookeeper重载了几个构造函数,其中构造者可以提供参数最多,可定制性最多的构造函数是
public ZooKeeper(String connectString, int sessionTimeout, Watcher watcher, long sessionId, byte[] sessionPasswd, boolea
【Java命令三】jstack
bit1129
jstack
jstack是用于获得当前运行的Java程序所有的线程的运行情况(thread dump),不同于jmap用于获得memory dump
[hadoop@hadoop sbin]$ jstack
Usage:
jstack [-l] <pid>
(to connect to running process)
jstack -F
jboss 5.1启停脚本 动静分离部署
ronin47
以前启动jboss,往各种xml配置文件,现只要运行一句脚本即可。start nohup sh /**/run.sh -c servicename -b ip -g clustername -u broatcast jboss.messaging.ServerPeerID=int -Djboss.service.binding.set=p
UI之如何打磨设计能力?
brotherlamp
UI ui教程 ui自学 ui资料 ui视频
在越来越拥挤的初创企业世界里,视觉设计的重要性往往可以与杀手级用户体验比肩。在许多情况下,尤其对于 Web 初创企业而言,这两者都是不可或缺的。前不久我们在《右脑革命:别学编程了,学艺术吧》中也曾发出过重视设计的呼吁。如何才能提高初创企业的设计能力呢?以下是 9 位创始人的体会。
1.找到自己的方式
如果你是设计师,要想提高技能可以去设计博客和展示好设计的网站如D-lists或
三色旗算法
bylijinnan
java 算法
import java.util.Arrays;
/**
问题:
假设有一条绳子,上面有红、白、蓝三种颜色的旗子,起初绳子上的旗子颜色并没有顺序,
您希望将之分类,并排列为蓝、白、红的顺序,要如何移动次数才会最少,注意您只能在绳
子上进行这个动作,而且一次只能调换两个旗子。
网上的解法大多类似:
在一条绳子上移动,在程式中也就意味只能使用一个阵列,而不使用其它的阵列来
警告:No configuration found for the specified action: \'s
chiangfai
configuration
1.index.jsp页面form标签未指定namespace属性。
<!--index.jsp代码-->
<%@taglib prefix="s" uri="/struts-tags"%>
...
<s:form action="submit" method="post"&g
redis -- hash_max_zipmap_entries设置过大有问题
chenchao051
redis hash
使用redis时为了使用hash追求更高的内存使用率,我们一般都用hash结构,并且有时候会把hash_max_zipmap_entries这个值设置的很大,很多资料也推荐设置到1000,默认设置为了512,但是这里有个坑
#define ZIPMAP_BIGLEN 254
#define ZIPMAP_END 255
/* Return th
select into outfile access deny问题
daizj
mysql txt 导出数据到文件
本文转自:http://hatemysql.com/2010/06/29/select-into-outfile-access-deny%E9%97%AE%E9%A2%98/
为应用建立了rnd的帐号,专门为他们查询线上数据库用的,当然,只有他们上了生产网络以后才能连上数据库,安全方面我们还是很注意的,呵呵。
授权的语句如下:
grant select on armory.* to rn
phpexcel导出excel表简单入门示例
dcj3sjt126com
PHP Excel phpexcel
<?php
error_reporting(E_ALL);
ini_set('display_errors', TRUE);
ini_set('display_startup_errors', TRUE);
if (PHP_SAPI == 'cli')
die('This example should only be run from a Web Brows
美国电影超短200句
dcj3sjt126com
电影
1. I see. 我明白了。2. I quit! 我不干了!3. Let go! 放手!4. Me too. 我也是。5. My god! 天哪!6. No way! 不行!7. Come on. 来吧(赶快)8. Hold on. 等一等。9. I agree。 我同意。10. Not bad. 还不错。11. Not yet. 还没。12. See you. 再见。13. Shut up!
Java访问远程服务
dyy_gusi
httpclient webservice get post
随着webService的崛起,我们开始中会越来越多的使用到访问远程webService服务。当然对于不同的webService框架一般都有自己的client包供使用,但是如果使用webService框架自己的client包,那么必然需要在自己的代码中引入它的包,如果同时调运了多个不同框架的webService,那么就需要同时引入多个不同的clien
Maven的settings.xml配置
geeksun
settings.xml
settings.xml是Maven的配置文件,下面解释一下其中的配置含义:
settings.xml存在于两个地方:
1.安装的地方:$M2_HOME/conf/settings.xml
2.用户的目录:${user.home}/.m2/settings.xml
前者又被叫做全局配置,后者被称为用户配置。如果两者都存在,它们的内容将被合并,并且用户范围的settings.xml优先。
ubuntu的init与系统服务设置
hongtoushizi
ubuntu
转载自:
http://iysm.net/?p=178 init
Init是位于/sbin/init的一个程序,它是在linux下,在系统启动过程中,初始化所有的设备驱动程序和数据结构等之后,由内核启动的一个用户级程序,并由此init程序进而完成系统的启动过程。
ubuntu与传统的linux略有不同,使用upstart完成系统的启动,但表面上仍维持init程序的形式。
运行
跟我学Nginx+Lua开发目录贴
jinnianshilongnian
nginx lua
使用Nginx+Lua开发近一年的时间,学习和实践了一些Nginx+Lua开发的架构,为了让更多人使用Nginx+Lua架构开发,利用春节期间总结了一份基本的学习教程,希望对大家有用。也欢迎谈探讨学习一些经验。
目录
第一章 安装Nginx+Lua开发环境
第二章 Nginx+Lua开发入门
第三章 Redis/SSDB+Twemproxy安装与使用
第四章 L
php位运算符注意事项
home198979
位运算 PHP &
$a = $b = $c = 0;
$a & $b = 1;
$b | $c = 1
问a,b,c最终为多少?
当看到这题时,我犯了一个低级错误,误 以为位运算符会改变变量的值。所以得出结果是1 1 0
但是位运算符是不会改变变量的值的,例如:
$a=1;$b=2;
$a&$b;
这样a,b的值不会有任何改变
Linux shell数组建立和使用技巧
pda158
linux
1.数组定义 [chengmo@centos5 ~]$ a=(1 2 3 4 5) [chengmo@centos5 ~]$ echo $a 1 一对括号表示是数组,数组元素用“空格”符号分割开。
2.数组读取与赋值 得到长度: [chengmo@centos5 ~]$ echo ${#a[@]} 5 用${#数组名[@或
hotspot源码(JDK7)
ol_beta
java HotSpot jvm
源码结构图,方便理解:
├─agent Serviceab
Oracle基本事务和ForAll执行批量DML练习
vipbooks
oracle sql
基本事务的使用:
从账户一的余额中转100到账户二的余额中去,如果账户二不存在或账户一中的余额不足100则整笔交易回滚
select * from account;
-- 创建一张账户表
create table account(
-- 账户ID
id number(3) not null,
-- 账户名称
nam