Freemarker实现Html全站静态化
全站静态化
在大型网站中,比如主流电商商品页,访问者看到的页面基本上是静态页面。为什么都要把页面静态化呢?其实把页面静态化,好处有很多。例如:访问速度快,更有利于搜索引擎收录等。
目前主流的静态化主要有两种:
- 1、纯静态方式:将动态页面抓取并保存为静态页面,页面实际存在于服务器的硬盘中。
- 2、伪静态方式:通过WEB服务器的 URL Rewrite 把外部请求的静态地址转化为实际的动态页面地址,页面本质上是动态页面,静态页面是不存在的。
这两种方法都达到了实现URL静态化的效果,但是也各有各自的特点。
优缺点对比
对比项 | 动态 | 伪静态 | 纯静态 |
---|---|---|---|
网站打开速度 | 中等 | 中等 | 快(无DB查询、CPU计算消耗) |
搜索引擎抓取和索引 | 不利 | 有利 | 有利(速度快,权重高) |
安全性 | 低 | 低 | 高(不适用程序、DB,攻击目标少) |
稳定性 | 低 | 低 | 高(不受程序、DB故障影响) |
硬盘容量 | 低 | 低 | 高(静态化网页文件需要存储在硬盘中) |
服务器压力 | 高 | 高 | 低(无DB查询、CPU计算消耗) |
实时性 | 高 | 高 | 低(数据变更后,需要手动触发静态化;静态化难度随网站复杂度提升而提升) |
Freemarker实现Html全站静态化
1、引入maven依赖
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>{最新稳定版}</version>
</dependency>
2、freemarker工具类
- 1、配置FreeMarkerConfigurer(推荐托管在Spring容器,和复用SpringMVC同一套配置)
<bean id="freemarkerConfig" class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
<property name="freemarkerSettings">
<bean class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<property name="location" value="classpath:freemarker.properties" />
</bean>
</property>
<property name="templateLoaderPath" value="/WEB-INF/template/" />
<property name="freemarkerVariables">
<bean
class="org.springframework.beans.factory.config.PropertiesFactoryBean">
<property name="location" value="classpath:freemarker.variables.properties" />
</bean>
</property>
</bean>
- 2、引入HtmlTemplateUtil.java文件
package com.xxl.util.core.util;import freemarker.ext.beans.BeansWrapper;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import freemarker.template.TemplateHashModel;
import org.springframework.ui.freemarker.FreeMarkerTemplateUtils;
import org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer;import java.io.*;
import java.util.Map;/**
* HTML模板.Util
*
* 功能简介:
* 1、根据Ftl生成Html字符串;
* 2、根据Ftl生成Html文件(网站静态化);
* 3、Ftl支持使用静态类方法;
*
* @author xuxueli
*/
public class HtmlTemplateUtil {private static FreeMarkerConfigurer freemarkerConfig;public static FreeMarkerConfigurer loadConfig(){
if (freemarkerConfig == null) {
freemarkerConfig = (FreeMarkerConfigurer) SpringContentAwareUtil.getBeanByName("freemarkerConfig");
}
return freemarkerConfig;
}/**
* generate static model
* @param packageName
* @return
*/
public static TemplateHashModel generateStaticModel(String packageName) {
try {
BeansWrapper wrapper = BeansWrapper.getDefaultInstance();
TemplateHashModel staticModels = wrapper.getStaticModels();
TemplateHashModel fileStatics = (TemplateHashModel) staticModels.get(packageName);
return fileStatics;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}/**
* 生成HTML字符串
*
* @param content : 页面传参
* @param templateName : 模板名称路径,相对于模板目录
*/
public static String generateString(Map<?, ?> content, String templateName) {
String htmlText = "";
try {
// 通过指定模板名获取FreeMarker模板实例
Template tpl = loadConfig().getConfiguration().getTemplate(templateName);
htmlText = FreeMarkerTemplateUtils.processTemplateIntoString(tpl, content);
} catch (Exception e) {
e.printStackTrace();
}
return htmlText;
}/**
* 生成HTML文件
*
* @param content : 页面传参
* @param templatePathName : 模板名称路径,相对于模板目录
* @param filePathName : 文件名称路径,相对于项目跟目录
* DEMO:HtmlTemplateUtil.generate(freemarkerConfig, new HashMap<String, Object>(), "net/index.ftl", "/index.html");
*/
public static void generateFile(Map<?, ?> content, String templatePathName, String filePathName) {
Writer out = null;
try {
// mkdirs
File htmlFile = new File(WebPathUtil.webPath() + filePathName);
if (!htmlFile.getParentFile().exists()) {
htmlFile.getParentFile().mkdirs();
}
// process
Template template = loadConfig().getConfiguration().getTemplate(templatePathName);
out = new OutputStreamWriter(new FileOutputStream(WebPathUtil.webPath() + filePathName), "UTF-8");
template.process(content, out);
out.flush();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (TemplateException e) {
e.printStackTrace();
} finally {
if (out != null) {
try {
out.close();
out = null;
} catch (IOException e) {
e.printStackTrace();
}
}
}
}public static void main(String[] args) {
String temp = generateString(null, "hello.ftl");
System.out.println(temp);/*// generate String
Map<String, Object> params= new HashMap<String, Object>();
params.put("WebPathUtil", HtmlTemplateUtil.generateStaticModel(WebPathUtil.class.getName()));String result = HtmlTemplateUtil.generateString(params, "freemarker-test.ftl");// generate Html File
HtmlTemplateUtil.generateFile(params, "freemarker-test.ftl", "freemarker-test.html");*/
}}
要点:
1、“freemarkerConfig”中的配置“templateLoaderPath”,为include新ftl文件时的根目录“/”位置(省去了繁琐的相对路径配置,相当方便);
2、“freemarkerConfig”必须放在spring中,springMVC和静态化UTIL公用;因为web.xml加载顺序为:web.xml加载顺序,listener(spring) -> filter -> servlet(springMVC);因此,如果放在springMVC中,Service中注入不了该config,静态化UTIL注入时还未初始化bean会报错;
3、freemarker静态化-单页面
public static void main(String[] args) {
String temp = generateString(null, "hello.ftl");
System.out.println(temp);/*// generate String
Map<String, Object> params= new HashMap<String, Object>();
params.put("WebPathUtil", HtmlTemplateUtil.generateStaticModel(WebPathUtil.class.getName())); // 可以在Ftl中使用静态工具类 "${WebPathUtil.webPath()}"String result = HtmlTemplateUtil.generateString(params, "freemarker-test.ftl");// generate Html File
HtmlTemplateUtil.generateFile(params, "freemarker-test.ftl", "freemarker-test.html");*/
}
4、freemarker静态化-分页
- 1、分页代码:HtmlGenerateServiceImpl.java
// 调用处:一面墙,html分页
List<WallInfo> wallInfoList = wallInfoDao.getPageList(0, 10000);
generateHtmlPagination(wallInfoList, null, 20, "net/wall/index.ftl", "wall/", "index");/**
* html分页工具
* @param allList : html分页列表
* @param pagesize : 每页显示记录数量
* @param templatePathName : 模板页面,完整地址 (相相对于freeamrker配置根目录)
* @param filePath : html文件,路径目录 --/-/
* @param index : html文件,默认前缀 index
*/
private void generateHtmlPagination(List<?> allList, Map<String, Object> paramMap,int pagesize, String templatePathName , String filePath , String index){
int allCount = allList!=null?allList.size():0;Map<String, Object> params = new HashMap<String, Object>();
params.put("pageNumAll", 1);
params.put("pageNum", 1);
params.put("filePath", filePath);
params.put("index", index);if (MapUtils.isNotEmpty(paramMap)) {
params.putAll(paramMap);
}if (allCount > 0) {
int pageNumAll = allCount%pagesize==0 ? allCount/pagesize : allCount/pagesize + 1;
for (int pageNum = 1; pageNum <= pageNumAll; pageNum++) {
params.put("pageNumAll", pageNumAll);
params.put("pageNum", pageNum);int from = (pageNum-1)*pagesize;
int to = (from + pagesize) <= allCount ? (from + pagesize) : allCount;
params.put("pageList", allList.subList(from, to));String fileName = (pageNum==1) ? index : (index + "_" + pageNum);
HtmlTemplateUtil.generate(params, templatePathName, filePath + fileName + ".html");
}
} else {
HtmlTemplateUtil.generate(params, templatePathName, filePath + index + ".html");
}
}
2、分页模板:index.ftl
<#list pageList as item>
<div class="well text-justify">${item.content}</div>
</#list><!--html分页-->
<#import "/net/common/common.html.pagination.ftl" as pagination>
<@pagination.htmlPaging pageNumAll=pageNumAll pageNum=pageNum html_base_url=base_url+filePath index=index />
3、分页模板,公共分页标签:common.html.pagination.ftl
<#--
html分页模板,文件名称
------------------
pageNum : 当前页数、(1-max)
html_base_url : html文件路径、
-->
<#macro htmlPagingName pageNum html_base_url index >
<#if pageNum == 1 >${html_base_url}${index}.html
<#else>${html_base_url}${index}_${pageNum}.html</#if>
</#macro>
<#--
html分页模板
------------------
pageNumAll : 总页数、
pageNum : 当前页数、
html_base_url : html文件路径、
-->
<#macro htmlPaging pageNumAll pageNum html_base_url index >
<ul class="pagination">
<!--pre-->
<#if pageNum-1 gte 1><li><a href="<@htmlPagingName pageNum=pageNum-1 html_base_url=html_base_url index=index />" >«</a></li>
<#else><li class="disabled"><a>«</a></li></#if>
<!--every pre-->
<#if pageNum-1 gte 5>
<li><a href="<@htmlPagingName pageNum=1 html_base_url=html_base_url index=index />" >1</a></li>
<li><a href="<@htmlPagingName pageNum=2 html_base_url=html_base_url index=index />" >2</a></li>
<li><a>...</a></li>
<li><a href="<@htmlPagingName pageNum=pageNum-2 html_base_url=html_base_url index=index />" >${pageNum-2}</a></li>
<li><a href="<@htmlPagingName pageNum=pageNum-1 html_base_url=html_base_url index=index />" >${pageNum-1}</a></li>
<#elseif 1 lte (pageNum-1) >
<#list 1..(pageNum-1) as item>
<li><a href="<@htmlPagingName pageNum=item html_base_url=html_base_url index=index />" >${item}</a></li>
</#list>
</#if>
<!--every now-->
<li class="active" ><a href="<@htmlPagingName pageNum=pageNum html_base_url=html_base_url index=index />" >${pageNum}</a></li>
<!--every next-->
<#if pageNumAll-pageNum gte 5>
<li><a href="<@htmlPagingName pageNum=pageNum+1 html_base_url=html_base_url index=index />" >${pageNum+1}</a></li>
<li><a href="<@htmlPagingName pageNum=pageNum+2 html_base_url=html_base_url index=index />" >${pageNum+2}</a></li>
<li><a>...</a></li>
<li><a href="<@htmlPagingName pageNum=pageNumAll-1 html_base_url=html_base_url index=index />" >${pageNumAll-1}</a></li>
<li><a href="<@htmlPagingName pageNum=pageNumAll html_base_url=html_base_url index=index />" >${pageNumAll}</a></li>
<#elseif (pageNum+1) lte pageNumAll >
<#list (pageNum+1)..pageNumAll as item>
<li><a href="<@htmlPagingName pageNum=item html_base_url=html_base_url index=index />" >${item}</a></li>
</#list>
</#if>
<!--next-->
<#if pageNum+1 lte pageNumAll><li><a href="<@htmlPagingName pageNum=pageNum+1 html_base_url=html_base_url index=index />" >»</a></li>
<#else><li class="disabled"><a>»</a></li></#if>
</ul>
</#macro>
补充:freemarker动态分页
- 1、动态分页对象:Pager.java
package com.xxl.core.model.vo;import java.io.Serializable;
import java.util.List;@SuppressWarnings("serial")
public class Pager<T> implements Serializable{private int page; // 入参-第N页
private int pagesize; // 入参-每页长度
@SuppressWarnings("unused")
private int offset; // 起始行号【return this.page-1<0 ? 0 : (this.page-1)*this.rows;】
private List<T> data; // 查询-分页数据
private int total; // 查询-总记录数
@SuppressWarnings("unused")
private int totalPage; // 查询-总页数【return (total + pagesize - 1)/pagesize;】public Pager(int page, int pagesize){
this.page = page;
this.pagesize = pagesize;
}public int getPage() {
return page;
}
public void setPage(int page) {
this.page = page;
}
public int getPagesize() {
return pagesize;
}
public void setPagesize(int pagesize) {
this.pagesize = pagesize;
}
public int getOffset() {
return this.page-1<0 ? 0 : (this.page-1)*this.pagesize;
}
public void setOffset(int offset) {
this.offset = offset;
}
public List<T> getData() {
return data;
}
public void setData(List<T> data) {
this.data = data;
}
public int getTotal() {
return total;
}
public void setTotal(int total) {
this.total = total;
}
public int getTotalPage() {
return (total + pagesize - 1)/pagesize;
}
public void setTotalPage(int totalPage) {
this.totalPage = totalPage;
}}
- 2、后端分页代码
// Controller层代码 @RequestMapping("/orderList") @PermessionType public String orderList(HttpServletRequest request, Model model, @RequestParam(required=false, defaultValue="1")int page, @RequestParam(required=false, defaultValue="20")int pagesize){Pager<OrderInfo> pager = new Pager<OrderInfo>(page, pagesize); orderService.selectPage(pager, identity);model.addAttribute("pager", pager); return "net/order/orderList"; }
// Service层代码 @Override public void selectPage(Pager<OrderInfo> pager, LoginIdentity identity) { List<OrderInfo> data = orderInfoDao.selectPage(pager.getOffset(), pager.getPagesize(), identity.getUserId()); int total = orderInfoDao.selectPageCount(pager.getOffset(), pager.getPagesize(), identity.getUserId()); pager.setData(data); pager.setTotal(total); }
- 3、前端模板
<!-- 分页数据 -->
<#if pager?exists && pager.data?exists >
<#list pager.data as item>
<tr>
<td>${item.orderId}</td>
<td>${item.userId}</td>
<td>${item.prodId}</td>
<td>${item.orderTime?string('yyyy-MM-dd')}</td>
</tr>
</#list>
</#if>
<!-- 分页标签 -->
<@netCommon.pager pager=pager baseUrl=base_url+'order/orderList.do' />
- 4、分页标签,公共模板:net.common.ftl
<#macro pager pager baseUrl>
<!--pre-->
<#if pager.page gt 1><a href="${baseUrl}?page=${pager.page - 1}" >上页</a>
<#else>上页</#if><!--every pre-->
<#if pager.page-1 gte 5>
<a href="${baseUrl}?page=1" >1</a>
<a href="${baseUrl}?page=2" >2</a>
<a>...</a>
<a href="${baseUrl}?page=${pager.page-2}" >${pager.page-2}</a>
<a href="${baseUrl}?page=${pager.page-1}" >${pager.page-1}</a>
<#elseif 1 lte (pager.page-1) >
<#list 1..(pager.page-1) as item>
<a href="${baseUrl}?page=${item}" >${item}</a>
</#list>
</#if><!--every now-->
${pager.page}<!--every next-->
<#if pager.totalPage-pager.page gte 5>
<a href="${baseUrl}?page=${pager.page}" >${pager.page+1}</a>
<a href="${baseUrl}?page=${pager.page}" >${pager.page+2}</a>
<a>...</a>
<a href="${baseUrl}?page=${pager.page}" >${pager.page-1}</a>
<a href="${baseUrl}?page=${pager.page}" >${pager.page}</a>
<#elseif (pager.page+1) lte pager.totalPage >
<#list (pager.page+1)..pager.totalPage as item>
<a href="${baseUrl}?page=${pager.page}" >${item}</a>
</#list>
</#if><!--next-->
<#if pager.page lt pager.totalPage><a href="${baseUrl}?page=${pager.page+1}" >下页</a>
<#else>下页</#if>
</#macro>
相关文章:
Freemarker实现Html全站静态化
全站静态化 在大型网站中,比如主流电商商品页,访问者看到的页面基本上是静态页面。为什么都要把页面静态化呢?其实把页面静态化,好处有很多。例如:访问速度快,更有利于搜索引擎收录等。 目前主流的静态化…...

16.顺子日期(14)
题目 public class Main {public static boolean isLegal(String date) {int l 0;int n date.length();while(l<(n-3)) {int t1 (int)Integer.valueOf(date.substring(l,l1));int t2 (int)Integer.valueOf(date.substring(l1,l2));int t3 (int)Integer.valueOf(date.s…...

《动手学深度学习》学习笔记 第5章 深度学习计算
本系列为《动手学深度学习》学习笔记 书籍链接:动手学深度学习 笔记是从第四章开始,前面三章为基础知道,有需要的可以自己去看看 关于本系列笔记: 书里为了让读者更好的理解,有大篇幅的描述性的文字,内容很…...

【Redis】非关系型数据库之Redis的介绍及安装配置
目录 前言 一、关系型数据库与非关系型数据库 1.1关系型数据库 1.2非关系型数据库 1.3两者的区别 1.4非关系型数据库产生的背景 1.5总结 二、Redis介绍 2.1Redis是什么 2.2Redis的优点 2.3Redis的使用场景 2.4那些数据适合放在缓存中 2.5Redis为什么那么快…...

3D模型轻量化
在线工具推荐:3D数字孪生场景编辑器 - GLTF/GLB材质纹理编辑器 - 3D模型在线转换 - Three.js AI自动纹理开发包 - YOLO 虚幻合成数据生成器 - 三维模型预览图生成器 - 3D模型语义搜索引擎 近来,基于3D模型在影视作品、数字旅游项目诸多3D视觉领域都取得…...

数据分析——快递电商
一、任务目标 1、任务 总体目的——对账 本项目解决同时使用多个快递发货,部分隔离区域出现不同程度涨价等情形下,如何快速准确核对账单的问题。 1、在订单表中新增一列【运费差异核对】来表示订单运费实际有多少差异,结果为数值。 2、将…...

《PCI Express体系结构导读》随记 —— 第I篇 第2章 PCI总线的桥与配置(8)
接前一篇文章:《PCI Express体系结构导读》随记 —— 第I篇 第2章 PCI总线的桥与配置(7) 2.2 HOST主桥 MPC8548处理器的拓扑结构如图2-2所示: 2.2.2 存储器域地址空间到PCI总线域地址空间的转换 MPC8548处理器使用ATMUÿ…...

Hadoop分布式文件系统(二)
目录 一、Hadoop 1、文件系统 1.1、文件系统定义 1.2、传统常见的文件系统 1.3、文件系统中的重要概念 1.4、海量数据存储遇到的问题 1.5、分布式存储系统的核心属性及功能含义 2、HDFS 2.1、HDFS简介 2.2、HDFS设计目标 2.3、HDFS应用场景 2.4、HDFS重要特性 2.4…...

macOS跨进程通信: FIFO(有名管道) 创建实例
一: 简介 在类linux系统中管道分为有名管道和匿名管道。两者都能单方向的跨进程通信。 匿名管道(pipe): 必须是父子进程之间,而且子进程只能由父进程fork() 出来的,才能继承父进程的管道句柄,一般mac 开发…...

推荐几个免费的HTTP接口Mock网站和工具
在前后端分离开发架构下,经常遇到调用后端数据API接口进行测试、集成、联调等需求,比如: (1)前端开发人员很快开发完成了UI界面,但后端开发人员的API接口还没有完成,不能进行前后端数据接口对接…...

企业数据库安全管理规范
1.目的 为规范数据库系统安全使用活动,降低因使用不当而带来的安全风险,保障数据库系统及相关应用系统的安全,特制定本数据库安全管理规范。 2.适用范围 本规范中所定义的数据管理内容,特指存放在信息系统数据库中的数据。 本…...
react:ffcreator中FFCreatorCenter视频队例
最近项目要求,一键生成房子的推荐视频,选几张图,加上联系人的方式就是一个简单的视频,因为有web端、小程序端,为了多端口用,决定放在服务器端生成。 目前用的是react中的nextjs来开发项目。 nextjs中怎样…...
力扣(leetcode)第434题字符串中的单词数(Python)
434.字符串中的单词数 题目链接:434.字符串中的单词数 统计字符串中的单词个数,这里的单词指的是连续的不是空格的字符。 请注意,你可以假定字符串里不包括任何不可打印的字符。 示例: 输入: “Hello, my name is John” 输出: 5 解释: 这…...

django学习:页面渲染与请求和响应
1.请求过程 2.页面渲染 在app中新建一个目录(Directory),文件名命名为templates。该文件名命名是固定的,不可命名出错,如若后续步骤出错,该目录文件名是一个检查的重点项目。在该目录下新建一个html文件&a…...
Redis 数据一致性
概述 当我们在使用缓存时,如果发生数据变更,那么你需要同时操作缓存和数据库,而它们两个又分属不同的系统,因此无法做到同时操作成功或失败,因此在并发读写下很可能出现缓存与数据库数据不一致的情况 理论上可以通过…...

Mac环境下反编译apk
Mac环境下反编译apk 安装反编译工具dex2jar:[官网下载](https://sourceforge.net/projects/dex2jar/)JD-GUI:[官网下载](https://jd-gui.apponic.com/) 实操1. 将需要反编译的 .apk 文件放在下载的 dex2jar 文件夹目录下2. 使用 cd /xxx/dex2jar-2.0 命令…...
计算机网络——网络模型的组织、看法以及标准化流程
1. 通信技术和标准化领域中扮演重要角色的组织 1.1 国际和国家官方标准化机构 OSI:国际标准化组织(ISO),负责国际标准的制定,旨在确保全球产品和服务的安全性、可靠性和效率。它有许多国家分支机构,包括法…...

【JAVA】volatile 关键字的作用
🍎个人博客:个人主页 🏆个人专栏: JAVA ⛳️ 功不唐捐,玉汝于成 目录 前言 正文 volatile 的作用: 结语 我的其他博客 前言 在多线程编程中,保障数据的一致性和线程之间的可见性是…...

Next.js 第一次接触
因为需要整个漂亮的在线文档,所以接触了next.js,因为对前端js本身不够熟悉,别说对react.js 又不会,时间又不允许深入研究,所以,为了加一个导航菜单,极其痛苦。 有点小bug,不过不影响…...
CISSP 第7章:PKI和密码学应用
第七章 PKI和密码学应用 7.1 非对称密码学 对称密码系统具有共享的秘钥系统,从而产生了安全秘钥分发的问题 非对称密码学使用公钥和私钥对,无需支出复杂密码分发系统 7.1.1 公钥与私钥 7.1.2 RSA(兼具加密和数字签名) RSA算法依赖…...

TDengine 快速体验(Docker 镜像方式)
简介 TDengine 可以通过安装包、Docker 镜像 及云服务快速体验 TDengine 的功能,本节首先介绍如何通过 Docker 快速体验 TDengine,然后介绍如何在 Docker 环境下体验 TDengine 的写入和查询功能。如果你不熟悉 Docker,请使用 安装包的方式快…...
React hook之useRef
React useRef 详解 useRef 是 React 提供的一个 Hook,用于在函数组件中创建可变的引用对象。它在 React 开发中有多种重要用途,下面我将全面详细地介绍它的特性和用法。 基本概念 1. 创建 ref const refContainer useRef(initialValue);initialValu…...

学校招生小程序源码介绍
基于ThinkPHPFastAdminUniApp开发的学校招生小程序源码,专为学校招生场景量身打造,功能实用且操作便捷。 从技术架构来看,ThinkPHP提供稳定可靠的后台服务,FastAdmin加速开发流程,UniApp则保障小程序在多端有良好的兼…...

[ICLR 2022]How Much Can CLIP Benefit Vision-and-Language Tasks?
论文网址:pdf 英文是纯手打的!论文原文的summarizing and paraphrasing。可能会出现难以避免的拼写错误和语法错误,若有发现欢迎评论指正!文章偏向于笔记,谨慎食用 目录 1. 心得 2. 论文逐段精读 2.1. Abstract 2…...

Ascend NPU上适配Step-Audio模型
1 概述 1.1 简述 Step-Audio 是业界首个集语音理解与生成控制一体化的产品级开源实时语音对话系统,支持多语言对话(如 中文,英文,日语),语音情感(如 开心,悲伤)&#x…...
Angular微前端架构:Module Federation + ngx-build-plus (Webpack)
以下是一个完整的 Angular 微前端示例,其中使用的是 Module Federation 和 npx-build-plus 实现了主应用(Shell)与子应用(Remote)的集成。 🛠️ 项目结构 angular-mf/ ├── shell-app/ # 主应用&…...

算法岗面试经验分享-大模型篇
文章目录 A 基础语言模型A.1 TransformerA.2 Bert B 大语言模型结构B.1 GPTB.2 LLamaB.3 ChatGLMB.4 Qwen C 大语言模型微调C.1 Fine-tuningC.2 Adapter-tuningC.3 Prefix-tuningC.4 P-tuningC.5 LoRA A 基础语言模型 A.1 Transformer (1)资源 论文&a…...

基于Java+MySQL实现(GUI)客户管理系统
客户资料管理系统的设计与实现 第一章 需求分析 1.1 需求总体介绍 本项目为了方便维护客户信息为了方便维护客户信息,对客户进行统一管理,可以把所有客户信息录入系统,进行维护和统计功能。可通过文件的方式保存相关录入数据,对…...

免费PDF转图片工具
免费PDF转图片工具 一款简单易用的PDF转图片工具,可以将PDF文件快速转换为高质量PNG图片。无需安装复杂的软件,也不需要在线上传文件,保护您的隐私。 工具截图 主要特点 🚀 快速转换:本地转换,无需等待上…...
用递归算法解锁「子集」问题 —— LeetCode 78题解析
文章目录 一、题目介绍二、递归思路详解:从决策树开始理解三、解法一:二叉决策树 DFS四、解法二:组合式回溯写法(推荐)五、解法对比 递归算法是编程中一种非常强大且常见的思想,它能够优雅地解决很多复杂的…...