基于Springmvc+MyBatis+Spring+Bootstrap+EasyUI+Mysql的个人博客系统

基于Springmvc+MyBatis+Spring+Bootstrap+EasyUI+Mysql的个人博客系统

1.项目介绍

  1. 使用Maven3+Spring4+Springmvc+Mybatis3架构;数据库使用Mysql,数据库连接池使用阿里巴巴的Druid;
  2. 使用Bootstrap3 UI框架实现博客的分页显示,博客分类,文章归类显示;完成用户评论和分享功能;
  3. 使用EasyUI实现后台对博客、博客类别、用户评论、博主信息的管理,包括增删改查,文件上传等;实现刷新后台缓存等功能;
  4. 使用Shiro作为项目安全框架,验证不同url的请求,包括后台博主的登陆;
  5. 实现Lucene对全站的检索功能,对检索出的博客标题和内容实现高亮显示;
  6. 使用百度的Ueditor编辑器实现写博客功能,支持单图、多图上传,支持截图上传,支持代码高亮特性等。

2.数据库设计

2.1表结构

博客表

博主表

博客类型表

评论表

友情链接表

2.2ER图

3.项目设计

3.1项目配置

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
	xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context"
	xmlns:jee="http://www.springframework.org/schema/jee" xmlns:tx="http://www.springframework.org/schema/tx"
	xsi:schemaLocation="    
        http://www.springframework.org/schema/aop 
        http://www.springframework.org/schema/aop/spring-aop-4.0.xsd  
        http://www.springframework.org/schema/beans 
        http://www.springframework.org/schema/beans/spring-beans-4.0.xsd  
        http://www.springframework.org/schema/context 
        http://www.springframework.org/schema/context/spring-context-4.0.xsd  
        http://www.springframework.org/schema/jee 
        http://www.springframework.org/schema/jee/spring-jee-4.0.xsd  
        http://www.springframework.org/schema/tx 
        http://www.springframework.org/schema/tx/spring-tx-4.0.xsd">

	<!-- 鑷姩鎵弿鍖呬腑鐨刡ean -->
	<context:component-scan base-package="ssm.blog.*" />

	<!-- 閰嶇疆鏁版嵁婧愶紝浣跨敤闃块噷宸村反杩炴帴姹燚ruid -->
	<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
		<property name="url" value="jdbc:mysql://localhost:3306/db_blog"/>
		<property name="username" value="root"/>
		<property name="password" value="root"/>
	</bean>

	<!-- 閰嶇疆mybatis鐨剆qlSessionFactory -->
	<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
		<property name="dataSource" ref="dataSource" />
		<!-- 鑷姩鎵弿mappers.xml鏂囦欢 -->
		<property name="mapperLocations" value="classpath:ssm/blog/mappers/*.xml"></property>
		<!-- 鍔犺浇mybatis鍏ㄥ眬閰嶇疆鏂囦欢 -->
		<property name="configLocation" value="classpath:mybatis-config.xml"></property>
	</bean>

	<!-- 鎵弿mapper鎺ュ彛锛堝嵆dao锛夛紝Spring浼氳嚜鍔ㄦ煡鎵惧叾涓嬬殑绫?-->
	<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
		<property name="basePackage" value="ssm.blog.dao" />
		<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"></property>
	</bean>

	<!-- 浜嬪姟绠$悊锛坱ransaction manager锛?-->
	<bean id="transactionManager"
		class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
		<property name="dataSource" ref="dataSource" />
	</bean>

	<!-- 鑷畾涔塕ealm -->
	<bean id="myRealm" class="ssm.blog.realm.MyRealm" />

	<!-- 瀹夊叏绠$悊鍣?-->
	<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
		<property name="realm" ref="myRealm" />
	</bean>

	<!-- Shiro杩囨护鍣?-->
	<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
		<!-- Shiro鐨勬牳蹇冨畨鍏ㄦ帴鍙?杩欎釜灞炴ф槸蹇呴』鐨?-->
		<property name="securityManager" ref="securityManager" />
		<!-- 韬唤璁よ瘉澶辫触锛屽垯璺宠浆鍒扮櫥褰曢〉闈㈢殑閰嶇疆 -->
		<property name="loginUrl" value="/login.jsp" />
		<!-- 鏉冮檺璁よ瘉澶辫触锛屽垯璺宠浆鍒版寚瀹氶〉闈紝鍥犱负涓汉鍗氬灏变竴涓汉鐧婚檰锛屽氨涓嶉渶瑕佹潈闄愪簡 -->
		<!-- <property name="unauthorizedUrl" value="/unauthorized.jsp" />  -->
		<!-- Shiro杩炴帴绾︽潫閰嶇疆,鍗宠繃婊ら摼鐨勫畾涔?-->
		<property name="filterChainDefinitions">
			<value>
				/login=anon
				/admin/**=authc
			</value>
		</property>
	</bean>

	<!-- 淇濊瘉瀹炵幇浜哠hiro鍐呴儴lifecycle鍑芥暟鐨刡ean鎵ц -->
	<bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor" />

	<!-- 寮鍚疭hiro娉ㄨВ -->
	<bean
		class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"
		depends-on="lifecycleBeanPostProcessor" />
	<bean
		class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
		<property name="securityManager" ref="securityManager" />
	</bean>

	<!-- 閰嶇疆浜嬪姟閫氱煡灞炴?-->
	<tx:advice id="txAdvice" transaction-manager="transactionManager">
		<!-- 瀹氫箟浜嬪姟浼犳挱灞炴?-->
		<tx:attributes>
			<tx:method name="insert*" propagation="REQUIRED" />
			<tx:method name="update*" propagation="REQUIRED" />
			<tx:method name="edit*" propagation="REQUIRED" />
			<tx:method name="save*" propagation="REQUIRED" />
			<tx:method name="add*" propagation="REQUIRED" />
			<tx:method name="new*" propagation="REQUIRED" />
			<tx:method name="set*" propagation="REQUIRED" />
			<tx:method name="remove*" propagation="REQUIRED" />
			<tx:method name="delete*" propagation="REQUIRED" />
			<tx:method name="change*" propagation="REQUIRED" />
			<tx:method name="check*" propagation="REQUIRED" />
			<tx:method name="get*" propagation="REQUIRED" read-only="true" />
			<tx:method name="find*" propagation="REQUIRED" read-only="true" />
			<tx:method name="load*" propagation="REQUIRED" read-only="true" />
			<tx:method name="*" propagation="REQUIRED" read-only="true" />
		</tx:attributes>
	</tx:advice>

	<!-- 閰嶇疆浜嬪姟鍒囬潰 -->
	<aop:config>
		<aop:pointcut id="pointCut" expression="execution(* ssm.blog.service.*.*(..))" />
		<aop:advisor advice-ref="txAdvice" pointcut-ref="pointCut" />
	</aop:config>

</beans>

3.2监听器

package ssm.blog.listener;

import java.util.List;

import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

import ssm.blog.entity.Blog;
import ssm.blog.entity.BlogType;
import ssm.blog.entity.Blogger;
import ssm.blog.entity.Link;
import ssm.blog.service.BlogService;
import ssm.blog.service.BlogTypeService;
import ssm.blog.service.BloggerService;
import ssm.blog.service.LinkService;

@Component
public class InitBloggerData implements ServletContextListener, ApplicationContextAware {

	private static ApplicationContext applicationContext;
	
	public void contextInitialized(ServletContextEvent sce) {
		System.out.println(applicationContext);
		//先获取servlet上下文
		ServletContext application = sce.getServletContext();
		
		//根据spring的上下文获取bloggerService这个bean
		BloggerService bloggerService = (BloggerService) applicationContext.getBean("bloggerService");
		//获取博主信息
		Blogger blogger = bloggerService.getBloggerData();
		//由于密码也获取到了,比较敏感,我们也不需要这个,所以把密码清空掉
		blogger.setPassword(null);
		//将博主信息存入application域中
		application.setAttribute("blogger", blogger);
		
		//同上,获取友情链接信息
		LinkService linkService = (LinkService) applicationContext.getBean("linkService");
		List<Link> linkList = linkService.getLinkData(); 
		application.setAttribute("linkList", linkList);
		
		//同上,获取博客类别信息
		BlogTypeService blogTypeService = (BlogTypeService) applicationContext.getBean("blogTypeService");
		List<BlogType> blogTypeList = blogTypeService.getBlogTypeData();
		application.setAttribute("blogTypeList", blogTypeList);
		
		//同上,获取博客信息,按照时间分类的
		BlogService blogService = (BlogService) applicationContext.getBean("blogService");
		List<Blog> blogTimeList = blogService.getBlogData();
		application.setAttribute("blogTimeList", blogTimeList);
	}

	public void contextDestroyed(ServletContextEvent sce) {
		// TODO Auto-generated method stub
		
	}

	public void setApplicationContext(ApplicationContext applicationContext) 
			throws BeansException {
		InitBloggerData.applicationContext = applicationContext;
	}

}

3.3博客全文索引

/**
 * @Description 博客索引类
 * @author Ni Shengwu
 *
 */
public class BlogIndex {

	private Directory dir;
	
	private IndexWriter getWriter() throws Exception {		
		dir = FSDirectory.open(Paths.get("D:\\blog_index"));
		SmartChineseAnalyzer analyzer = new SmartChineseAnalyzer();
		IndexWriterConfig config = new IndexWriterConfig(analyzer);
		IndexWriter writer = new IndexWriter(dir, config);	
		return writer;
	}
	
	//添加博客索引
	public void addIndex(Blog blog)  throws Exception {
		IndexWriter writer = getWriter();
		Document doc = new Document();
		doc.add(new StringField("id", String.valueOf(blog.getId()), Field.Store.YES));
		doc.add(new TextField("title", blog.getTitle(), Field.Store.YES));
		doc.add(new StringField("releaseDate", DateUtil.formatDate(new Date(), "yyyy-MM-dd"), Field.Store.YES));		
		doc.add(new TextField("content", blog.getContentNoTag(), Field.Store.YES));		
		writer.addDocument(doc);
		writer.close();
	}
	
	//删除指定博客的索引
	public void deleteIndex(String blogId) throws Exception {
		IndexWriter writer = getWriter();
		writer.deleteDocuments(new Term("id", blogId));
		writer.forceMergeDeletes();//强制删除
		writer.commit();
		writer.close();
	}
	
	//更新博客索引
	public void updateIndex(Blog blog) throws Exception {
		IndexWriter writer = getWriter();
		Document doc = new Document();
		doc.add(new StringField("id", String.valueOf(blog.getId()), Field.Store.YES));
		doc.add(new TextField("title", blog.getTitle(), Field.Store.YES));
		doc.add(new StringField("releaseDate", DateUtil.formatDate(new Date(), "yyyy-MM-dd"), Field.Store.YES));		
		doc.add(new TextField("content", blog.getContentNoTag(), Field.Store.YES));		
		writer.updateDocument(new Term("id", String.valueOf(blog.getId())), doc);
		writer.close();
	}
	
	//查询博客索引信息
	public List<Blog> searchBlog(String q) throws Exception {
		
		dir = FSDirectory.open(Paths.get("D:\\blog_index"));
		IndexReader reader = DirectoryReader.open(dir);
		IndexSearcher search = new IndexSearcher(reader);
		BooleanQuery.Builder booleanQuery = new BooleanQuery.Builder();
		SmartChineseAnalyzer analyzer = new SmartChineseAnalyzer();
		
		QueryParser parser1 = new QueryParser("title", analyzer); //查询标题
		Query query1 = parser1.parse(q);
		
		QueryParser parser2 = new QueryParser("content", analyzer); //查询内容
		Query query2 = parser2.parse(q);
		
		booleanQuery.add(query1, BooleanClause.Occur.SHOULD);
		booleanQuery.add(query2, BooleanClause.Occur.SHOULD);
		
		TopDocs hits = search.search(booleanQuery.build(), 100);
		
		QueryScorer scorer = new QueryScorer(query1);//使用title得分高的排前面
		Fragmenter fragmenter = new SimpleSpanFragmenter(scorer); //得分高的片段
		SimpleHTMLFormatter simpleHTMLFormatter = new SimpleHTMLFormatter("<b><font color='red'>", "</font></b>");
		Highlighter highlighter = new Highlighter(simpleHTMLFormatter, scorer); //高亮显示
		highlighter.setTextFragmenter(fragmenter); //将得分高的片段设置进去
		
		List<Blog> blogIndexList = new LinkedList<Blog>(); //用来封装查询到的博客
		for(ScoreDoc score : hits.scoreDocs) {
			Document doc = search.doc(score.doc);
			Blog blog = new Blog();
			blog.setId(Integer.parseInt(doc.get("id")));
			blog.setReleaseDateStr(doc.get("releaseDate"));
			String title = doc.get("title");
			String content = doc.get("content");
			if(title != null) {
				TokenStream tokenStream = analyzer.tokenStream("title", new StringReader(title));
				String hTitle = highlighter.getBestFragment(tokenStream, title);
				if(StringUtil.isEmpty(hTitle)) {
					blog.setTitle(title);
				} else {
					blog.setTitle(hTitle);
				}
			}
			if(content != null) {
				TokenStream tokenStream = analyzer.tokenStream("content", new StringReader(content));
				String hContent = highlighter.getBestFragment(tokenStream, content);
				if(StringUtil.isEmpty(hContent)) {
					if(content.length() > 100) { //如果没查到且content内容又大于100的话
						blog.setContent(content.substring(0, 100)); //截取100个字符
					} else {
						blog.setContent(content);
					}
				} else {
					blog.setContent(hContent);
				}
			}
			blogIndexList.add(blog);
		}
		
		return blogIndexList;
	}
}

3.4工具类

md5加密工具类


/**
 * md5加密工具类
 * @author Administrator
 *
 */
public class CryptographyUtil {

	
	/**
	 * @Description 使用Shiro中的md5加密
	 * @param str
	 * @param salt
	 * @return
	 */
	public static String md5(String str,String salt){
		//Md5Hash是Shiro中的一个方法
		return new Md5Hash(str, salt).toString();
	}
	
	//我自己生成一下测试用的
	public static void main(String[] args) {
		String password="123456";
		
		System.out.println("Md5加密:"+CryptographyUtil.md5(password, "javacoder"));
	}
}

分页工具类

/**
 * 分页工具类
 * @author Administrator
 *
 */
public class PageUtil {

	/**
	 * 生成分页代码
	 * @param targetUrl 目标地址
	 * @param totalNum 总记录数
	 * @param currentPage 当前页
	 * @param pageSize 每页大小
	 * @return
	 */
	public static String genPagination(
										String targetUrl, //目标url
										long totalNum,    //总记录数
										int currentPage,  //当前页
										int pageSize,     //每页显示记录数
										String param) {   //参数
		//计算总页数
		long totalPage = totalNum % pageSize==0 ? totalNum/pageSize : totalNum/pageSize+1; 
		if(totalPage == 0){
			return "未查询到数据";
		}else{
			StringBuffer pageCode = new StringBuffer();
			if(currentPage > 1) {
				pageCode.append("<li><a href='" + targetUrl + "?page=1&" + param + "'>首页</a></li>");
				pageCode.append("<li><a href='" + targetUrl + "?page=" + (currentPage-1) + "&" + param + "'>上一页</a></li>");			
			}else{
				pageCode.append("<li class='disabled'><a>首页</a></li>");
				pageCode.append("<li class='disabled'><a>上一页</a></li>");		
			}
			for(int i = currentPage - 2; i <= currentPage + 2; i++) {
				if(i < 1 || i > totalPage) {
					continue;
				}
				if(i == currentPage) {
					pageCode.append("<li class='active'><a href='" + targetUrl + "?page=" + i + "&" + param + "'>" + i + "</a></li>");	
				}else{
					pageCode.append("<li><a href='" + targetUrl + "?page=" + i + "&" + param + "'>" + i + "</a></li>");	
				}
			}
			if(currentPage < totalPage) {
				pageCode.append("<li><a href='" + targetUrl + "?page=" + (currentPage+1) + "&" + param + "'>下一页</a></li>");
				pageCode.append("<li><a href='" + targetUrl + "?page=" + totalPage + "&" + param + "'>尾页</a></li>");
			}else{
				pageCode.append("<li class='disabled'><a>下一页</a></li>");	
				pageCode.append("<li class='disabled'><a>尾页</a></li>");
			}
			return pageCode.toString();
		}
	}
	
	public static String getPrevAndNextPageCode(Blog prev, Blog next, String projectContent) {
		StringBuffer pageCode = new StringBuffer();
		if(prev == null || prev.getId() == null) {
			pageCode.append("<p>上一篇:无</P>");
		} else {
			pageCode.append("<p>上一篇:<a href='" + projectContent + "/blog/articles/" + prev.getId() + ".html'>" + prev.getTitle() + "</a></p>");
		}
		
		if(next == null || next.getId() == null) {
			pageCode.append("<p>下一篇:无</P>");
		} else {
			pageCode.append("<p>上一篇:<a href='" + projectContent + "/blog/articles/" + next.getId() + ".html'>" + next.getTitle() + "</a></p>");
		}
		
		return pageCode.toString();
	}
	
	//Lucence搜索博客结果的分页
	public static String getUpAndDownPageCode (
			Integer page, 
			Integer totalNum, 
			String q, 
			Integer pageSize, 
			String projectContext) {
		
		//计算总页数
		long totalPage = totalNum % pageSize==0 ? totalNum/pageSize : totalNum/pageSize+1; 
		StringBuffer pageCode = new StringBuffer();
		if(totalPage == 0) {
			return "";
		} else {
			pageCode.append("<nav>");
			pageCode.append("<ul class='pager'>");
			if(page > 1) {
				pageCode.append("<li><a href='"+projectContext+"/blog/search.html?page="+(page-1)+"&q="+q+"'>上一页</a></li>");
			} else {
				pageCode.append("<li class='disabled'><a>上一页</a></li>");
			}
			if(page < totalPage) {
				pageCode.append("<li><a href='"+projectContext+"/blog/search.html?page="+(page+1)+"&q="+q+"'>下一页</a></li>");
			} else {
				pageCode.append("<li class='disabled'><a>下一页</a></li>");
			}
			pageCode.append("</ul>");
			pageCode.append("<nav>");
			pageCode.append("<nav>");
			pageCode.append("<nav>");
		}
		
		return pageCode.toString();
	}

}

4.项目展示

4.1前台效果展示

1. 博客主页显示

2. 侧边栏显示

3. 博客内容显示

4. 搜索结果显示

5. 评论模块显示

4.2后台效果展示

1. 博主登陆

2. 修改博主信息

3. 写博客功能

4. 博客管理

5. 添加博客类别等等

5.总结

后台的其他功能就不一个个展示了,都差不多。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/967803.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

香港中文大学 Adobe 推出 MotionCanvas:开启用户掌控的电影级图像视频创意之旅。

简介&#xff1a; 亮点直击 将电影镜头设计引入图像到视频的合成过程中。 推出了MotionCanvas&#xff0c;这是一种简化的视频合成系统&#xff0c;用于电影镜头设计&#xff0c;提供整体运动控制&#xff0c;以场景感知的方式联合操控相机和对象的运动。 设计了专门的运动条…

数据结构 单链表的模拟实现

一、链表的定义 线性表的链式存储就是链表。 它是将元素存储在物理上任意的存储单元中&#xff0c;由于⽆法像顺序表⼀样通过下标保证数据元素之间的逻辑关系&#xff0c;链式存储除了要保存数据元素外&#xff0c;还需额外维护数据元素之间的逻辑关系&#xff0c;这两部分信息…

Avalonia-wpf介绍

文章目录 工程简述窗体样式暗色模式亚克力模糊效果ExperimentalAcrylicBorder” 和 “ExperimentalAcrylicMaterial” 的介绍ExperimentalAcrylicBorderExperimentalAcrylicMaterial按钮排版按钮图标按钮命令响应式命令添加一个新对话框对话框窗口样式对话框的输入与输出显示对…

Node.js开发属于自己的npm包(发布到npm官网)

在 Node.js 中开发并发布自己的 npm 包是一个非常好的练习&#xff0c;可以帮助我们更好地理解模块化编程和包管理工具&#xff0c;本篇文章主要阐述如何使用nodejs开发一个属于自己的npm包&#xff0c;并且将其发布在npm官网。在开始之前确保已经安装了 Node.js 和 npm。可以在…

操作系统常见调度算法的详细介绍

目录 1. 先进先出算法&#xff08;FIFO&#xff09; 2. 前后台调度算法 3. 最短处理机运行期优先调度算法&#xff08;短进程优先算法&#xff09; 4. 最高响应比优先调度算法&#xff08;HRRN&#xff09; 5. 优先级调度算法 6. 时间片轮转调度算法 7. 多级反馈队列轮转…

ADB详细教程

目录 一、ADB简介 二、配置 配置环境变量 验证是否安装成功 三、简单使用 基本命令 设备连接管理 USB连接 WIFI连接&#xff08;需要USB线&#xff09; 开启手机USB调试模式 开启USB调试 四、其他 更换ADB默认启动端口 一、ADB简介 ADB&#xff08;Android Debug…

WEB攻防-第60天:PHP反序列化POP链构造魔术方法流程漏洞触发条件属性修改

目录 一、序列化与反序列化基础 1.1 什么是序列化与反序列化 二、魔术方法的生命周期 2.1 常见的魔术方法 2.2 模式方法的生命周期触发调用 2.2.1 __construct() 2.2.2 __destruct() 2.2.3 __sleep() 2.2.4 __wakeup() 2.2.5 __invoke() 2.2.6 __toS…

SQLMesh系列教程-2:SQLMesh入门项目实战(下篇)

上篇我介绍了环境搭建、duckdb数据准备、sqlmesh数据模型、plan命令运行。本文继续介绍审计、测试、生成血缘关系以及python模型等。 有两种方法可以在SQLMesh中创建宏。一种方法是使用Python&#xff0c;另一种方法是使用Jinja。这里我们创建Python宏。让我们构建简单的Python…

自主项目面试点总结

1、许苑–OJ判题系统 技术栈&#xff1a;Spring BootSpring Cloud AlibabaRedisMybatisMQDocker 项目地址: https://github.com/xuyuan-upward/xyoj-backend-microservice 1.1、项目介绍: 一个基于微服务的OJ系统&#xff0c;具备能够根据管理员预设的题目用例对用户提交的代…

Macbook Pro快速搭建Easysearch学习环境

在学习过程中&#xff0c;我们有时身边没有可用的服务器&#xff0c;这时就需要借助自己的 Mac 来安装和学习 Easysearch。然而&#xff0c;Easysearch 官网并未提供 Mac 版本的安装教程&#xff0c;下面我将详细整理我在 Mac 上安装和使用 Easysearch 的折腾经历。 Easysearc…

Arduino 第十三章:红外接收

Arduino 第十三章&#xff1a;红外接收 一、红外接收概述 红外接收在日常生活和电子制作中十分常见&#xff0c;像电视、空调等家电的遥控器就是利用红外信号来实现远程控制的。在 Arduino 项目里&#xff0c;借助红外接收模块能够让设备接收红外信号&#xff0c;进而实现诸如…

朝天椒USB服务器:解决加密狗远程连接

本文探讨朝天椒USB服务器用Usb Over Network技术&#xff0c;解决加密狗在虚拟机、云主机甚至异地的远程连接问题。 在企业数字化转型的浪潮中&#xff0c;加密狗作为防止软件盗版的重要手段&#xff0c;广泛应用于各类软件授权场景。然而&#xff0c;随着企业超融合进程不断加…

第二篇:电压与电流的“锡安之战”——电路定律在800V高压平台中的应用

——基尔霍夫与戴维南如何破解新能源汽车的“高压密码” 核心隐喻&#xff1a;电路定律的“数字起义” 在《黑客帝国》中&#xff0c;锡安的反抗军通过破解母体协议实现逆袭。而在新能源汽车的800V高压平台中&#xff0c; 基尔霍夫定律 和 戴维南定理 正是工程师手中的“通…

【牛客】动态规划专题一:斐波那契数列

文章目录 DP1 斐波那契数列法1&#xff1a;递归法2&#xff1a;动态规划法3&#xff1a;优化空间复杂度 2.分割连接字符串3. 给定一个字符串s和一组单词dict&#xff0c;在s中添加空格将s变成一个句子 DP1 斐波那契数列 法1&#xff1a;递归 // 递归 #include <iostream>…

innovus如何分步长func和dft时钟

在Innovus工具中&#xff0c;分步处理功能时钟&#xff08;func clock&#xff09;和DFT时钟&#xff08;如扫描测试时钟&#xff09;需要结合设计模式&#xff08;Function Mode和DFT Mode&#xff09;进行约束定义、时钟树综合&#xff08;CTS&#xff09;和时序分析。跟随分…

5-R循环

R 循环 ​ 有的时候&#xff0c;我们可能需要多次执行同一块代码。一般情况下&#xff0c;语句是按顺序执行的&#xff1a;函数中的第一个语句先执行&#xff0c;接着是第二个语句&#xff0c;依此类推。 编程语言提供了更为复杂执行路径的多种控制结构。 循环语句允许我们多…

DeepSeek AI R1推理大模型API集成文档

DeepSeek AI R1推理大模型API集成文档 引言 随着自然语言处理技术的飞速发展&#xff0c;大语言模型在各行各业的应用日益广泛。DeepSeek R1作为一款高性能、开源的大语言模型&#xff0c;凭借其强大的文本生成能力、高效的推理性能和灵活的接口设计&#xff0c;吸引了大量开发…

知识图谱_protege的安装

目录 1.下载protege 2.安装可视化工具Graphviz 3.配置 参考【知识图谱】3.Protege下载安装-CSDN博客 1.下载protege 我在官网下载不了所以我就没有在官网下载 项目首页 - Protege-5.5.0Windows版本快速下载指南:Protege是一个广受欢迎的、强大的知识建模工具&#xff0c;用…

从BERT到ChatGPT:大模型训练中的存储系统挑战与技术发展——论文泛读

计算机研究与发展 2024 Paper 论文阅读笔记整理 问题 以ChatGPT为代表的大模型在文字生成、语义理解等任务上表现卓越&#xff0c;但大模型的参数量在3年内增长数万倍&#xff0c;且仍呈现增长的趋势。大模型训练面临存储挑战&#xff0c;存储需求大&#xff0c;且具有独特的…

船舶维保管理系统

一、项目介绍 381.基于SpringBoot的船舶维保管理系统&#xff0c;系统包含四种角色&#xff1a;管理员、船家、维保人员、维保公司,系统分为前台和后台两大模块&#xff0c;主要功能如下。 船家&#xff1a; - 个人中心&#xff1a;管理个人信息。 - 公告管理&#xff1a;查看…