Python三百行代码实现一简约个人博客网站(全网最小巧)

news2025/1/22 8:58:20

这是全互联网最小巧的博客,没有比这更小的了。虽然小巧,但功能一点儿也不弱,支持文章的分页展示,文章表格,图片和代码语法高亮。文章无限制分类,访问量统计,按时间和按点击量排序,展示最新文章,最热文章,文章留言评论等功能。

前言

如果你也想拥有一个属于自己的个性博客,这种尝试将大幅降低准入门槛,让你看到实现一个个人博客网站是多么的简单。其它的又是建库建表的,或是需要登录管理后台管理,我还是觉得不够简单好用。

用这种写好的markdown文档的形式,你可以直接把markdown笔记变成动态的博客展示出来。后续可基于微信小程序做个入口,如果想要发布文章,则直接把编写好的markdown文件提交发送过去就可以啦,操作使用上更加简单和快捷。这才应该是现在博客该有的特色和创新,原有的旧的登录网站后台编辑和使用的方式,太落后了。

况且使用这种方式还有个好处,可以方便多人同时使用。比如可以在公司内部搭建一个公共博客平台,做个简单入口界面,让每个人都可以往上面提交文档,这也是个不错的内部方案交流平台和技术分享平台。相比传统word文档的方式优点很多,方便文档的查看、归档和线上展示及分享,连留言评论都有啦。

项目开源地址:

tiny-blog: 极小的个人博客,虽然很小,但是很全。使用python+flask+html实现。

体验地址:

我的个人博客

实现原理

其实就是一个基于markdown的轻量级博客,需要按一定格式编写好markdown文件,提交到后台服务。当用户访问网页时由后台读取文件内容并经由流行的markdown-it组件渲染。

后台使用python的flask框架,整个代码仅三百多行。相当的小巧,很容易根据需要修改源码去增加一些其他的功能。当然一个css或js文件都不可能这么短,这里仅指的是后台代码。网页使用了流行的markdown-it(MarkDown渲染),highlight.js(语法高亮)和mermaid.js(画流程图、时序图等的js库)组件。留言评论功能,使用比较火的Valine博客评论系统。

网站模板我是从素材火网站上找了一个好看的博客网站模板。如果你有中意的其他博客网站模板,也可以很容易的改造过来用。文末介绍和分享几个好看的博客模板。

效果展示:

Flask介绍

Flask是一个轻量级的Python Web框架,用于构建Web应用程序和API。它基于Werkzeug工具箱和Jinja2模板引擎,并且具有灵活性和可扩展性。

Flask提供了一些基本的功能,例如路由、请求和响应处理、会话管理等,同时支持各种扩展,可以轻松添加身份验证、数据库集成、邮件发送等功能。由于其简单的学习曲线和活跃的社区支持,Flask已成为最受欢迎的Python Web框架之一。

源码实现

源码实现很简单,仅有三个文件,总代码量三百多行。为了提高访问速度,设计了一种基于字典map的简单数据结构。只有应用启动时加载一次文件,后续文章访问直接从字典数据中取数据,避免每次访问都读文件,提高访问效率。为了方便的查看数据结构,加载完文件后保存了几个json格式的文件。通过json文件很容易看出来。

main.py

# encoding: utf-8
# author:yangyongzhen
from flask import  Flask,render_template,request,redirect
import articles
import atexit
import json
import sys

app=Flask(__name__,template_folder="templates", static_folder="static", static_url_path="/static")

# 首页
@app.route('/')
def index():
    articles.Stat.totalVisit += 1
    page = 1
    page = request.args.get('page',1,int)
    print(page)
    nums = len(articles.AllArts)
    print(nums)
    allpage = nums / 5
    if nums %5 != 0:
        allpage = int(nums/5) + 1
    print(allpage)

    curArts = articles.AllArts
    if (page * 5) < nums :
        curArts = articles.AllArts[(page-1)*5 : page*5]
    else:
        curArts = articles.AllArts[(page-1)*5 : nums]
    #分页表
    tabs = []
    for i in range(0,allpage):
        print(i)
        tabs.append(i)
    print(tabs)
    return render_template("index.html",arts=curArts,news=articles.NewArts[:9],hots=articles.HotArts[:9],items=articles.ItemList,curPage=page,tab=tabs)  #加入变量传递

@app.route('/about')
def about():
    msg="my name is caojianhua, China up!"
    return render_template("about.html",data=msg)  #加入变量传递

#分类页
@app.route('/items')
def items():
    try:
        id = request.args.get('id')
        print(id)
        allArts = []
        allMaps = articles.ItemMap[id]
        #遍历 hash
        for v in allMaps.values():
           allArts.append(v) 
        #按日期排序
        allArts.sort(key=lambda x: x['date'],reverse=True)
        #print(allArts)
        page = 1
        page = request.args.get('page',1,int)
        print(page)
        nums = len(allArts)
        print(nums)
        allpage = int(nums / 5)
        if nums %5 != 0:
            allpage = int(nums/5) + 1
        print(allpage)
        curArts = allArts
        if (page * 5) < nums :
            curArts = allArts[(page-1)*5 : page*5]
        else:
            curArts = allArts[(page-1)*5 : nums]
        #分页表
        tabs = []
        for i in range(0,allpage):
            #print(i)
            tabs.append(i)
        #print(tabs)
        return render_template("items.html",arts=curArts,item=id,news=articles.NewArts[:9],hots=articles.HotArts[:9],curPage=page,tab=tabs) 
    except Exception as e:
        print("Exception occured")
        print(e)
        return render_template('404.html')

# 文章详情页
@app.route('/article_detail')
def article_detail():
    art = articles.Article("","","","","","","","",0,0)
    item_index = 0
    try:
        id = request.args.get('id')
        #print(id)
        #取出分类
        item = articles.ArtRouteMap[id]['item']
        print(item)
        art = articles.ItemMap[item][id]  
        #art_index  = NewPosts.index(id)
        articles.Stat.artStat[id]['visitCnt'] += 1
        articles.Stat.totalVisit += 1
        articles.ItemMap[item][id]['visitCnt'] = articles.Stat.artStat[id]['visitCnt']
        #print(art)
        #print(item_index)
        #print(art_index)
        return render_template("article_detail.html",data=art,news=articles.NewArts[:9],hots=articles.HotArts[:9] ) 
    except Exception as e:
        print("Exception occured")
        return render_template('404.html')
   
# 说说页面  
@app.route('/moodList')
def moodList():
    msg="my name is caojianhua, China up!"
    return render_template("moodList.html",data=msg) 

# 留言页面 
@app.route('/comment')
def comment():
    msg="my name is caojianhua, China up!"
    return render_template("comment.html",data=msg) 

@app.route('/404')
def error_404():
    print("error_404")
    return render_template("404.html") 

@app.errorhandler(404)
def page_not_found(e):
    print("page_not_found")
    print(e)
    return render_template('404.html'), 404

@app.errorhandler(Exception)
def handle_exception(e):
    # 捕获其他异常
    print("handle_exception")
    print(e)
    return render_template('404.html'), 500
 
def saveData():
    #保存访问量数据       
    with open('statistic.json1', 'w',encoding='utf-8') as f:
        json.dump(articles.Stat.__dict__, f,ensure_ascii=False)
           
# 监控退出时保存统计信息
@atexit.register
def exit_handler():
    print("应用程序退出")
    saveData()

if __name__=="__main__":
    #启动时加载访问量数据
    articles.getPosts()
    
    app.run(port=8000,host="127.0.0.1",debug=False)
    print("over")

articles.py

# encoding: utf-8
# author:yangyongzhen
import glob
import os
import pprint
import hashlib
import json
import statistic

#访问量阅读量统计信息
Stat = statistic.AllStat()

# AllArts 总的文章,(按时间排过序的)
AllArts = []
# NewArts 最新文章
NewArts = []
# HotArts 热门文章
HotArts = []
# 文章分类信息
ItemList = []

ItemMap = {}
ArtRouteMap = {}

#文章信息类定义
class Article(object):
    def __init__(self, id, item, title, date, summary, body, imgFile, author, cmtCnt, visitCnt):
        self.id = id
        self.item = item
        self.title = title
        self.date = date
        self.summary = summary
        self.body = body
        self.imgFile = imgFile
        self.author = author
        self.cmtCnt = cmtCnt
        self.visitCnt = visitCnt
    
    def mPrint(self):
        print(self.id)
        print(self.item)
        print(self.title)
        print(self.date)
        print(self.summary)
        print(self.body)
        print(self.imgFile)
        print(self.author)


class ArticlesData():
    def __init__(self):
        self.item = ""
        self.articlesMap = {}


# ArticleRoute 文章的分类和路径信息
class ArticleRoute:
    def __init__(self, item, name):
        self.item = item
        self.name = name

#文章分类 是个集合类型,无重复元素
class ItemCfg:
    def __init__(self):
        self.items = set()
        
        
def strTrip(src):
    str = src.replace(" ", "")
    str = str.replace("\r", "")
    str = str.replace("\n", "")
    return str


#从文件中读取信息,并返回itemMap,artRouteMap,items
def getPosts():
    global ItemMap,ArtRouteMap,ItemList,NewArts
    # 打开访问量统计JSON文件并读取内容
    with open('statistic.json1', 'r',encoding='utf-8') as file:
        json_data = file.read()
        # 将JSON字符串反序列化为字典对象
        Stat.__dict__ = json.loads(json_data)
        print(Stat.totalVisit)
    # 获取"posts/"目录下的所有文件
    files = glob.glob("posts/*")
    # 按修改日期进行排序
    files = sorted(files, key=lambda x: os.path.getmtime(x))
    articleMap = {}
    itemMap = {}
    artRouteMap = {}
    #文章分类,是个集合类型,无重复
    items = set()
    # 遍历文件列表
    for i, f in enumerate(files):
        #print(i)
        #print(f)

        file = f
        file = os.path.basename(file) # 转换路径分隔符
        print(file)
        file = os.path.splitext(file)[0]  # 移除".md"后缀
        fileread = open(f, 'r',encoding='utf-8').read()
        lines = fileread.split('\n')
        #print(lines)
        title = lines[0].strip()
        date = strTrip(lines[1].strip())
        summary = lines[2].strip()
        imgfile = lines[3].strip()
        id = hashlib.md5(file.encode(encoding='UTF-8'))
        id = id.hexdigest()
        #print(id.hexdigest())
        item = strTrip(lines[4].strip())
        author = lines[5].strip()
        imgfile = strTrip(imgfile)
        body = '\n'.join(lines[6:])  # 获取第6行及以后的行
        ar = ArticleRoute(item, title)
        artRouteMap[id] = ar.__dict__
        visitCnt = 0
        if id in Stat.artStat:
           visitCnt = Stat.artStat[id]['visitCnt']
           #print(visitCnt)
        else:
            Stat.artStat[id] = statistic.ArtStat(title,visitCnt,0).__dict__
        post = Article(id,item,title, date, summary, body, imgfile, author, 0,visitCnt)
        articleMap[id] = post
        items.add(item)
    #json_data = json.dumps(posts,ensure_ascii=False)
    #print(json_data)
    itemList = []
    for itm in items:
        itmMp= {}
        for v in articleMap.values():
            if(v.item == itm):
                itmMp[v.id] = v.__dict__
        itemMap[itm] = itmMp
        itemList.append(itm)
            
        
    #保存为json文件
    with open('Articles.json1', 'w',encoding='utf-8') as f:
        json.dump(itemMap, f,ensure_ascii=False)
        
    with open('artRouteMap.json1', 'w',encoding='utf-8') as f:
        json.dump(artRouteMap, f,ensure_ascii=False)
    itemList.sort()
    
    #遍历字典
    for key, val in itemMap.items():
        for idx,art in val.items():
            AllArts.append(art)
            HotArts.append(art)        
    #按日期排序
    AllArts.sort(key=lambda x: x['date'],reverse=True)
    #按访问量排序
    HotArts.sort(key=lambda x: x['visitCnt'],reverse=True)
    NewArts = AllArts
    ItemList = itemList
    #print((HotArts[0]))
    ItemMap = itemMap
    ArtRouteMap = artRouteMap
    return itemMap,artRouteMap,itemList

if __name__=="__main__":
    p,p1,items = getPosts()
    #print(p)
    print(type(p))
    print(type(p1))
    print(p['go学习笔记'])
    print(p1['3eaf98ad2b949b3f93d16aeaa1f45ab0'])
    print(items)

statistic.py

# encoding: utf-8
# author:yangyongzhen
# 文章和总阅读量统计

#文章访问量统计
#param:名称,访问量,评论量
class ArtStat:
    def __init__(self, title,visitCnt,cmtCnt):
        self.title = title
        self.visitCnt = visitCnt
        self.commentCnt = cmtCnt
  
#总的统计        
class AllStat:
    def __init__(self):
        #总访问量
        self.totalVisit = 0
        self.artStat = {}


if __name__=="__main__":
    pass

如何使用

除了flask,无其它依赖。下载源码,pip install flask安装好依赖。然后python main.py即可运行起来。编写新文章,需要按照特定格式写前面几行。因为文章作者,文章分类和日期等信息,都在一个文件里写的。

文章内容格式如下(test.md):

This is a title!
2020-10-22
你好aaaaaaaasssssssssssssssss! 这是你第一次使用 **Markdown编辑器** 所展示的欢迎页。如果你想学习如何使用Markdown编辑器, 可以仔细阅读这篇文章,了解一下Markdown的基本语法知识。
08.jpg
感悟
yangyongzhen


This is the main post!

# Markdown1!
## Markdown2!
### 欢迎使用Markdown编辑器

Name    | Age
--------|------
Bob     | 27
Alice   | 23

你好! 这是你第一次使用 **Markdown编辑器** 所展示的欢迎页。如果你想学习如何使用Markdown编辑器, 可以仔细阅读这篇文章,了解一下Markdown的基本语法知识。

```golang
package main

import "fmt"

func main() {
	fmt.Println("hello ")
}
```

网页前端小技巧 

导航栏选中高亮

网站头部导航栏根据选择自动高亮显示,代码在silder.js中实现:

var obj=null;
var As=document.querySelector(".w_header_nav").getElementsByTagName('a');
obj = As[0];
for(i=1;i<As.length;i++){if(window.location.href.indexOf(As[i].href)>=0)
obj=As[i];}
console.log(obj)
// 添加class属性
obj.classList.add("active");

返回到顶部

返回到顶部,可复用js代码:

var $backToTopEle=$('<a href="javascript:void(0)" class="Hui-iconfont toTop" title="返回顶部" alt="返回顶部" style="display:none">^^</a>').appendTo($("body")).click(function(){
	$("html, body").animate({ scrollTop: 0 }, 120);
});
var backToTopFun = function() {
	var st = $(document).scrollTop(), winh = $(window).height();
	(st > 0)? $backToTopEle.show(): $backToTopEle.hide();
	/*IE6下的定位*/
	if(!window.XMLHttpRequest){
		$backToTopEle.css("top", st + winh - 166);
	}
};
	$(function(){
		$(window).on("scroll",backToTopFun);
		backToTopFun();
	});

分页显示js代码 :

/* 
*page plugin 1.0 
*/
(function ($) {
  //默认参数
  var defaults = {
    totalPages: 9,//总页数
    liNums: 9,//分页的数字按钮数(建议取奇数)
    activeClass: 'active' ,//active类
    firstPage: '首页',//首页按钮名称
    lastPage: '末页',//末页按钮名称
    prv: '«',//前一页按钮名称
    next: '»',//后一页按钮名称
    hasFirstPage: true,//是否有首页按钮
    hasLastPage: true,//是否有末页按钮
    hasPrv: true,//是否有前一页按钮
    hasNext: true,//是否有后一页按钮
    callBack : function(page){
        //回掉,page选中页数
    }
  };

  //插件名称
  $.fn.Page = function (options) {
    //覆盖默认参数
    var opts = $.extend(defaults, options);
    //主函数
    return this.each(function () {
      var obj = $(this);
      var l = opts.totalPages;
      var n = opts.liNums;
      var active = opts.activeClass;
      var str = '';
      var str1 = '<li><a href="javascript:" class="'+ active +'">1</a></li>';
      if (l > 1&&l < n+1) {
        for (i = 2; i < l + 1; i++) {
          str += '<li><a href="javascript:">' + i + '</a></li>';
        }
      }else if(l > n){
        for (i = 2; i < n + 1; i++) {
          str += '<li><a href="javascript:">' + i + '</a></li>';
        }
      }
      var dataHtml = '';
      if(opts.hasNext){
          dataHtml += '<div class="next fr">' + opts.next + '</div>';
      }
      if(opts.hasLastPage){
          dataHtml += '<div class="last fr">' + opts.lastPage + '</div>';
      }
          dataHtml += '<ul class="pagingUl">' + str1 + str + '</ul>';
      if(opts.hasFirstPage){
          dataHtml += '<div class="first fr">' + opts.firstPage + '</div>';
      }
      if(opts.hasPrv){
          dataHtml += '<div class="prv fr">' + opts.prv + '</div>';
      }
      
      obj.html(dataHtml).off("click");//防止插件重复调用时,重复绑定事件
      
      obj.on('click', '.next', function () {
        var pageshow = parseInt($('.' + active).html());
        var nums,flag;
        var a = n % 2;
        if(a == 0){
          //偶数
          nums = n;
          flag = true;
        }else if(a == 1){
          //奇数
          nums = (n+1);
          flag = false;
        }
        if(pageshow >= l) {
          return;
        }else if(pageshow > 0&&pageshow <= nums/2){
          //最前几项
          $('.' + active).removeClass(active).parent().next().find('a').addClass(active);
        }else if((pageshow > l-nums/2&&pageshow < l&&flag==false)||(pageshow > l-nums/2-1&&pageshow < l&&flag==true)){
          //最后几项
          $('.' + active).removeClass(active).parent().next().find('a').addClass(active);
        }else{
          $('.' + active).removeClass(active).parent().next().find('a').addClass(active);
          fpageShow(pageshow+1);
        }
        opts.callBack(pageshow+1);
      });
      obj.on('click', '.prv', function () {
        var pageshow = parseInt($('.' + active).html());
        var nums = odevity(n);
        if (pageshow <= 1) {
            return;
        }else if((pageshow > 1&&pageshow <= nums/2)||(pageshow > l-nums/2&&pageshow < l+1)){
          //最前几项或最后几项
          $('.' + active).removeClass(active).parent().prev().find('a').addClass(active);
        }else {
          $('.' + active).removeClass(active).parent().prev().find('a').addClass(active);
          fpageShow(pageshow-1);
        }
        opts.callBack(pageshow-1);
      });

      obj.on('click', '.first', function(){
        var activepage = parseInt($('.' + active).html());
        if (activepage <= 1){
          return
        }//当前第一页
        opts.callBack(1);
        fpagePrv(0);
      });
      obj.on('click', '.last', function(){
        var activepage = parseInt($('.' + active).html());
        if (activepage >= l){
          return;
        }//当前最后一页
        opts.callBack(l);
        if(l>n){
          fpageNext(n-1);
        }else{
          fpageNext(l-1);
        }
      });

      obj.on('click', 'li', function(){
        var $this = $(this);
        var pageshow = parseInt($this.find('a').html());
        var nums = odevity(n);
        opts.callBack(pageshow);
        if(l>n){
          if(pageshow > l-nums/2&&pageshow < l+1){
            //最后几项
            fpageNext((n-1)-(l-pageshow));
          }else if(pageshow > 0&&pageshow < nums/2){
            //最前几项
            fpagePrv(pageshow-1);
          }else{
            fpageShow(pageshow);
          }
        }else{
          $('.' + active).removeClass(active);
          $this.find('a').addClass(active);
        }
      });

          //重新渲染结构
        /*activePage 当前项*/
        function fpageShow(activePage){
          var nums = odevity(n);
          var pageStart = activePage - (nums/2-1);
          var str1 = '';
          for(i=0;i<n;i++){
            str1 += '<li><a href="javascript:" class="">' + (pageStart+i) + '</a></li>'
          }
          obj.find('ul').html(str1);
          obj.find('ul li').eq(nums/2-1).find('a').addClass(active);
        }
        /*index 选中项索引*/
        function fpagePrv(index){
          var str1 = '';
          if(l>n-1){
            for(i=0;i<n;i++){
              str1 += '<li><a href="javascript:" class="">' + (i+1) + '</a></li>'
            }
          }else{
            for(i=0;i<l;i++){
              str1 += '<li><a href="javascript:" class="">' + (i+1) + '</a></li>'
            }
          }
          obj.find('ul').html(str1);
          obj.find('ul li').eq(index).find('a').addClass(active);
        }
        /*index 选中项索引*/
        function fpageNext(index){
          var str1 = '';
          if(l>n-1){
            for(i=l-(n-1);i<l+1;i++){
              str1 += '<li><a href="javascript:" class="">' + i + '</a></li>'
            }
           obj.find('ul').html(str1);
           obj.find('ul li').eq(index).find('a').addClass(active);
          }else{
            for(i=0;i<l;i++){
              str1 += '<li><a href="javascript:" class="">' + (i+1) + '</a></li>'
            }
           obj.find('ul').html(str1);
           obj.find('ul li').eq(index).find('a').addClass(active);
          }
        }
        //判断liNums的奇偶性
        function odevity(n){
          var a = n % 2;
          if(a == 0){
            //偶数
            return n;
          }else if(a == 1){
            //奇数
            return (n+1);
          }
        }
    });
  }
})(jQuery);

使用方法,在需要分页展示的文章下方添加以下div标签:

<div class="page">
</div>

 在网页头部引入以下js:

<script type="text/javascript" src="plugin/fenye.page.js"></script>
<script type="text/javascript">
$(function(){
	$("#page").Page({
	  totalPages: 7,//分页总数
	  liNums: 5,//分页的数字按钮数(建议取奇数)
	  activeClass: 'activP', //active 类样式定义
	  callBack : function(page){
			//console.log(page)
	  }
  });
})
</script>

markdown文档渲染

<ul class="info>
<div class="md_render">
</div>
</ul>
	<script>
		var md;
		var defaults = {
		html: false, // Enable HTML tags in source
		xhtmlOut: false, // Use '/' to close single tags (<br />)
		breaks: false, // Convert '\n' in paragraphs into <br>
		langPrefix: 'language-', // CSS language prefix for fenced blocks
		linkify: true, // autoconvert URL-like texts to links
		typographer: true, // Enable smartypants and other sweet transforms
		// options below are for demo only
		_highlight: true,
		_strict: false,
		_view: 'html' // html / src / debug
		};
		defaults.highlight = function (str, lang) {
		var esc = md.utils.escapeHtml;
		
		if (lang && hljs.getLanguage(lang)) {
			try {
			return '<pre class="hljs"><code>' +
					hljs.highlight(lang, str, true).value +
					'</code></pre>';
			} catch (__) {}
		}
		return '<pre class="hljs"><code>' + esc(str) + '</code></pre>';
		};
		md = window.markdownit(defaults).use(window.markdownitCheckbox).use(window.markdownitEmoji).use(window.markdownitFootnote);
		var dat = document.querySelector('#enrolled_id').value;
		$('.md_render').html(md.render(dat));
	</script>

 这里有个坑需要注意,jinjia2模版是在后端渲染的,所以在网页的js代码中想使用模版变量不是那么美,不能像网页中{{data}}的方式使用。这里采用了一种取巧的方式,通过一个隐藏标签,先把需要的内容在html网页中渲染出来,再在js中通过操作dom的方式去获取。

<input type="hidden"  id="enrolled_id" value="{{ data.body }}">

其他资源

(自适应手机端)响应式个人博客网站模板

我的博客模版

JSON在线 | JSON解析格式化—SO JSON在线工具

风宇个人博客

丰富的计算机技术分享,多样化的互联网资源分享,第1页 - 吱吱工具箱butterPig

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

端口隔离度

端口隔离度 隔离度为&#xff08;本振或射频信号&#xff09;泄漏到其他端口的功率与输入功率之比&#xff0c;单位是dB。 比如 RF to LO Isolation 表示 射频输入信号的功率 与 泄漏到LO端口的功率 之比。 而 LO to RF Isolation 则表示 本振输入信号的功率 与 泄漏到RF端口的…

深入Python元编程:了解声明与初始化定制元类

更多资料获取 &#x1f4da; 个人网站&#xff1a;ipengtao.com 简介 在Python中&#xff0c;元编程是指在运行时创建或定制类的编程。元类是Python中最强大的元编程工具之一&#xff0c;允许您控制类的创建过程。元类是类的类&#xff0c;它控制类的实例化&#xff0c;允许您…

Xcode 来自身份不明的开发者且与之前打开的版本不同。你确定要打开它吗?

Xcode新建一个项目&#xff0c;模拟器运行的时候频繁跳出 “x x x”来自身份不明的开发者且与之前打开的版本不同。你确定要打开它吗? 如下图&#xff1a; 这个和在mac上安装应用的情况有点不一样&#xff0c;在mac上安装应用遇到这个问题&#xff0c;只需要在“设置”-->…

深入了解Spring Boot中@Async注解的8大坑点

文章目录 1. 缺少EnableAsync注解2. 异步方法需独立3. 不同的异步方法间无法相互调用4. 返回值为void的异步方法无法捕获异常5. 外部无法直接调用带有Async注解的方法6. Async方法不适用于private方法7. 缺失异步线程池配置8. 异步方法与事务的兼容结语 &#x1f389;深入了解S…

对于 ` HttpServletResponse ` , ` HttpServletRequest `我们真的学透彻了吗

对于 **HttpServletResponse , HttpServletRequest**我们真的学透彻了吗 问题引入 PostMapping("/importTemplate") public void importTemplate(HttpServletResponse response) {ExcelUtil<SysUser> util new ExcelUtil<SysUser>(SysUser.class);uti…

深入了解Java8新特性-日期时间API之TemporalQuery、TemporalQueries

阅读建议 嗨&#xff0c;伙计&#xff01;刷到这篇文章咱们就是有缘人&#xff0c;在阅读这篇文章前我有一些建议&#xff1a; 本篇文章大概2000多字&#xff0c;预计阅读时间长需要5分钟。本篇文章的实战性、理论性较强&#xff0c;是一篇质量分数较高的技术干货文章&#x…

网络安全 | 使用人工智能阻止网络攻击

全球范围内分布式拒绝服务 (DDoS) 网络攻击急剧增加&#xff0c;这种数字攻击可以通过大量的互联网流量压垮目标服务器&#xff0c;从而使网站瘫痪。这种攻击每年都会发生数百万起&#xff0c;而且数量和规模都在不断增加。大约三分之一的网站宕机是由于 DDoS 攻击所致。 计算…

UVA 108 Maximum Sum

UVA 108 Maximum Sum 题面翻译 给定一个含有正负数的二维数组&#xff0c;找出有最大和的子矩阵。矩阵的和指矩阵中所有元素的和。 一个子矩阵是任意在总矩阵中大小为1x1或更大的邻近子数组&#xff0c;例如在下面的矩阵中: 0 −2 −7 0 9 2 −6 2 −4 1 −4 1 −1 8 0 −…

C++学习寄录(八.继承)

继承的语法&#xff1a;class 子类 : 继承方式 父类 class A : public B; A 类称为子类 或 派生类 B 类称为父类 或 基类 1.基本使用 未使用继承的代码比较冗余重复 #include <iostream> #include <fstream> #include <string> #include <chrono>…

搞定这三个问题 伦敦金止损就没问题

笔者多次强调&#xff0c;做伦敦金交易&#xff0c;重要的是风险控制。而止损是我们风险控制中一个很重要的概念。设定好止损&#xff0c;就是风险控制的好开始。下面我们通过三个问题&#xff0c;来解决止损的问题。 问题一&#xff0c;你的止损位在哪里&#xff1f;要做止损&…

python -- python安装

1、python的诞生和发展&#xff1a; python语言是一种解释型、面向对象型、动态数据类型的高级程序设计语言。 2、python的安装&#xff1a; 1、安装解析器&#xff1a; 在安装的过程中需要注意的是&#xff1a; 在安装pycharm的时候也是同样的道理&#xff0c;需要指定安装…

解决:IDEA的debug模式只有第一次能拦截请求进行debug,后续所有请求全部失效

解决&#xff1a;IDEA的debug模式只有第一次能拦截请求进行debug&#xff0c;后续所有请求全部失效 一问题描述&#xff1a;IDEA的debug模式只有第一次能拦截请求进行debug&#xff0c;后续所有请求全部失效二问题原因&#xff1a;对IDEA的debug功能不熟悉或者理解有偏差三解决…

vs配置64位汇编

vs开发64位程序无法使用内联汇编&#xff0c;需要将汇编放到一个单独文件中编译链接。 步骤如下&#xff1a; 生成汇编代码。以asm.asm为例&#xff0c;以下是模板&#xff1a; ;64位汇编程序模板 (Template) ;声明一个ExitProcess函数 ExitProcess PROTO.data;在这里声明变量…

外汇天眼:外汇市场中的“双向交易”是什么意思?

说到外汇市场&#xff0c;总免不了提到它双向交易的优势&#xff0c;很多新手会对这一点有所疑问&#xff0c;今天我们就帮大家解决这一个疑问。 何谓双向交易&#xff1f; 金融市场上&#xff0c;交易者最常接触到的股票&#xff0c;多属于单向交易。 单向交易的模式便是「先…

如何快速生成项目目录结构树?

经常在网上看到下面这种由一个项目&#xff0c;生成一个结构树&#xff0c;你知道它是怎么生成的吗&#xff1f; 这就是利用本文要介绍的一个工具——Treer&#xff0c;treer就是一款专门用来快速生成目录结构树的命令行工具。 第一步&#xff1a;安装treer 在终端执行全局…

分布式机器学习、联邦学习、多智能体的区别和联系——一文进行详细解释

1 分布式机器学习、联邦学习、多智能体介绍 最近这三个方面的论文都读过&#xff0c;这里写一篇博客归纳一下&#xff0c;以方便搞这几个领域的其他童鞋入门。我们先来介绍以下这三种机器学习范式的基本概念。 1.1 分布式机器学习介绍 分布式机器学习(distributed machine l…

vivado综合分析与收敛技巧3

1、最优化 RAMB 输入逻辑以允许输出寄存器推断 以下 RTL 代码片段可从块 RAM &#xff08; 实际上为 ROM &#xff09; 生成关键路径 &#xff0c; 其中包含多个止于触发器 (FF) 的逻辑层次。 RAMB单元已在无可选输出寄存器 (DOA-0) 的情况下完成推断 &#xff0c; 这给 R…

美颜SDK是什么?美颜SDK对比测评

为了实现实时、高效的美颜效果&#xff0c;开发者们纷纷转向美颜SDK这一技术解决方案。那么&#xff0c;美颜SDK究竟是什么&#xff1f;本文将深入探讨美颜SDK的概念&#xff0c;并通过对比测评不同美颜SDK&#xff0c;为开发者和用户提供更清晰的选择参考。 一、美颜SDK的概念…

高效管理文件方法:根据文件大小智能移动至目标文件夹

在日常的工作中&#xff0c;会遇到大量的文件&#xff0c;从几个KB的小文档到几个GB的大数据文件。如何有效地管理这些文件&#xff0c;以便能够快速找到所需的资料&#xff0c;是一项重要的任务。传统的文件管理方式往往会在大量的文件和文件夹中迷失&#xff0c;而无法快速找…

SAP 第三方销售

SAP 第三方销售 第三方销售是比较常见的业务&#xff0c;&#xff0c;虽然他的一部分属于SD模块&#xff0c;但配置也并不难&#xff0c;一起测试下。 1、流程概述 第三方采购指的是&#xff1a;公司A和客户B签订销售合同&#xff0c;公司在SAP 系统内开销售订单&#xff0c…