对兼容各操作系统的Anki选择题模板的更新——提供更方便的笔记修改功能

news2024/11/27 14:37:34

2021年当我想做一个兼容各操作系统的Anki选择题模板的时候,到处搜索茧中网,根本找不到相关内容,直到偶然在github上看到Simon Lammer的Anki持久化模块,才算真正实现。现在再在茧中网上搜索兼容各种操作系统的Anki选择题模板,已经有很多结果了——我不免猜想是不是直接或间接从我这里得了点启示?如果真得了启示,也不用声明,不妨留个赞。^_^^_^只想拷贝卡片模版内容的可直接滚动到文末,无需看前面的更新说明。

后来看到一个anki插件Edit Field During Review(安装代码:1020366288),提供了在复习界面修改修改笔记内容的功能,十分方便。我对这个插件做了一点微小的修改,使它在复习界面修改笔记时不但可以修改文本内容,还支持用HTML标签改变文本的显示样式,插入表格和图片等,详见anki插件Edit Field During Review的使用及改造。当时有人说还是不够方便,因为还要靠手工输入HTML代码,如果直接有按钮一点就实现文字样式的修改那就好了。今年刚好又打算考试,于是弄个Anki题库帮助学习,复习的时候修改笔记,很多时候只是想把某些文字加个粗换个颜色突出显示一下,输入HTML代码确实比较麻烦,因此对原来的模板进行了更新,实现了在复习界面按几下按钮就改变被选择的文本的显示样式的功能。演示见下图:

目前,这个选择题模板设置有五个字段:Question——选择题题干;Options——选择题选项,Answer——正确答案;Extra——解析;Section——相关知识点所属教材章节。要让上面的演示图片中做的样式修改永久保存到笔记中,必须安装anki插件Edit Field During Review(安装代码:1020366288),并且必须要按照anki插件Edit Field During Review的使用及改造这篇文章的介绍修改插件的源代码,并且在模版中的字段前增加“edit:”过滤器,否则复习时的修改不能保存到笔记中。当然,如果不需要将复习时的修改保存到笔记中,就无需这个插件了。

除了插件支持外,笔记卡片的样式文件要包含如下内容:

/*说明:以下用u,a,i,b四个标签和4个css类定义相同的样式。
卡片背面模板中创建的临时HTML元素可以是u,a,i,b,也可以是span。
创建span元素时为不同样式指定不同类名,创建u,a,i,b时无需指定类名。
创建u,a,i,b时笔记最终保存的HTML字符串较短。
*/
u, .red{
    color:red;
    font-weight: bold;
    text-decoration:none;
}

.orange, a,a:visited,a:hover,a:link,a:active{
    color:#F90;
    font-weight:bold;
}

.green, i{
    font-weight: bold; 
    font-style:normal;color: #0f0;
}

.blue, b{ 
    font-weight: bold; 
    font-style:normal;color: #3cf;
}

卡片背面内容模版中添加以下HTML代码增加4个按钮:

<div id='styleButtons'> 
	<button id="blue_bold">蓝色加粗</button>
	<button id="red_bold">红色加粗</button>
	<button id="green_bold">绿色加粗</button>
	<button id="orange_bold">橙色加粗</button>
</div>

用于为以上按钮提供样式修改功能的JavaScript代码如下:

/*以下对在复习界面中选择的文本的显示样式进行处理*/
	var styleButtonDiv = document.getElementById('styleButtons');
	var styleButtons = styleButtonDiv.getElementsByTagName('button');
	for(i=0;i<styleButtons.length;i++){
		styleButtons[i].onclick=function(ev){
			var selection = document.getSelection();
      		var selectStr = selection.toString();
      		if (selectStr.trim() != '') {
				var rang = selection.getRangeAt(0);
				//卡片样式如果用u,b,i,a等标签名定义,只需声明tmpEle
				var tmpEle
				//卡片样式如果用.red之类的类名定义,可创建span元素
				//var tmpEle = document.createElement('span');
				var eleId=ev.target.getAttribute('id')//获取触发事件的元素的id				
				if(eleId=='blue_bold'){//如果是蓝色加粗按钮
					//用标签名定义样式,需创建相应样式的元素
					tmpEle = document.createElement('b');
					//用类名定义样式,为前面创建的span元素指定类名
					//tmpEle.className = 'blue';
				}else if(eleId=='red_bold'){//如果是红色加粗按钮
					//用标签名定义样式,需创建相应样式的元素
					tmpEle = document.createElement('u');
					//用类名定义样式,为前面创建的span元素指定类名
					//tmpEle.className = 'red';
				}else if(eleId=='green_bold'){//如果是绿色加粗按钮
					//用标签名定义样式,需创建相应样式的元素
					tmpEle = document.createElement('i');
					//用类名定义样式,为前面创建的span元素指定类名
					//tmpEle.className = 'green';
				}else{//如果是橙色加粗按钮
					//用标签名定义样式,需创建相应样式的元素
					tmpEle = document.createElement('a');
					//用类名定义样式,为前面创建的span元素指定类名
					//tmpEle.className = 'orange';
				}
                //将选中的文本插入临时元素内部
				rang.surroundContents(tmpEle);
				rang.deleteContents(); // 删除选中内容
				rang.insertNode(tmpEle); //插入临时元素替换内容
			} else {
				alert('请先选择文本!');
			}
				
		}
	}	

最后,将整个选择题卡片模板文件提供如下:

正面内容模板:

<script>
// v1.1.8 - https://github.com/SimonLammer/anki-persistence/blob/584396fea9dea0921011671a47a0fdda19265e62/script.js
if(void 0===window.Persistence){var e="github.com/SimonLammer/anki-persistence/",t="_default";if(window.Persistence_sessionStorage=function(){var i=!1;try{"object"==typeof window.sessionStorage&&(i=!0,this.clear=function(){for(var t=0;t<sessionStorage.length;t++){var i=sessionStorage.key(t);0==i.indexOf(e)&&(sessionStorage.removeItem(i),t--)}},this.setItem=function(i,n){void 0==n&&(n=i,i=t),sessionStorage.setItem(e+i,JSON.stringify(n))},this.getItem=function(i){return void 0==i&&(i=t),JSON.parse(sessionStorage.getItem(e+i))},this.removeItem=function(i){void 0==i&&(i=t),sessionStorage.removeItem(e+i)},this.getAllKeys=function(){for(var t=[],i=Object.keys(sessionStorage),n=0;n<i.length;n++){var s=i[n];0==s.indexOf(e)&&t.push(s.substring(e.length,s.length))}return t.sort()})}catch(n){}this.isAvailable=function(){return i}},window.Persistence_windowKey=function(i){var n=window[i],s=!1;"object"==typeof n&&(s=!0,this.clear=function(){n[e]={}},this.setItem=function(i,s){void 0==s&&(s=i,i=t),n[e][i]=s},this.getItem=function(i){return void 0==i&&(i=t),void 0==n[e][i]?null:n[e][i]},this.removeItem=function(i){void 0==i&&(i=t),delete n[e][i]},this.getAllKeys=function(){return Object.keys(n[e])},void 0==n[e]&&this.clear()),this.isAvailable=function(){return s}},window.Persistence=new Persistence_sessionStorage,Persistence.isAvailable()||(window.Persistence=new Persistence_windowKey("py")),!Persistence.isAvailable()){var i=window.location.toString().indexOf("title"),n=window.location.toString().indexOf("main",i);i>0&&n>0&&n-i<10&&(window.Persistence=new Persistence_windowKey("qt"))}}</script>

 
<!--正面模板-->
<div class="text" id="question">{{Question}}<span class='imp'>【所属章节:{{Section}}】<span></div>
<ol class="options" id="optionList"></ol>
<div id="options" style="display:none">{{Options}}</div>
<div id="answer" style="display:none">{{text:Answer}}</div>

 
<script>
    var myinfo;
    //if (Persistence.isAvailable()) {
        myinfo = Persistence.getItem();
        if (myinfo == null) {
            myinfo = {
                single: 0, //本次已做全部练习题中单选题数量
                singleCorrect: 0, //本次已做全部练习题中单选题正确数量
                multi: 0, //本次已做全部练习题中多选题数量
                multiCorrect: 0, //本次已做全部练习题中多选题完全正确数量
                partCorrect: 0, //本次已做全部练习题中多选部分正确数量
                multiScore: 0, //本次已做全部练习题中多选题得分
                score: 0, //当前所作练习题得分
                sum: 0, //本次已做全部练习题累计得分
                total: 0, //本次已做练习总数量
                totalScore: 0, //本次已做练习满分
                newOrderOps: [], //当前所作练习题打乱顺序后的选项
                newOrderAnswer: '', //当前所作练习题打乱选项顺序后新的正确答案编号
                choiced: '', //当前所作练习题选中的选项
                ifright: '' //当前所作练习题选中的选项是否正确
            };
        }
        myinfo.total++;
        myinfo.choiced = '';
        myinfo.newOrderAnswer = '';
        myinfo.newOrderOps = [];
 
        var question = document.getElementById("question");
 
        //读入答案,去掉多余字符和空格
        var correctAnswer = document.getElementById('answer').innerHTML
            .toUpperCase().replace(/[^A-Z]+/, "");
        if (correctAnswer.length > 1) { //正确答案大于一个为多选题
            myinfo.totalScore += 2;
            myinfo.multi++;
            question.innerHTML = "<span class='imp'>【多选题】</span>" + question.innerHTML;
        } else { //单选题  
            myinfo.totalScore++;
            myinfo.single++;
            question.innerHTML = "<span class='imp'>【单选题】</span>" + question.innerHTML;
        }
 
        var options = document.getElementById("options"),
            optionList = document.getElementById("optionList");
 
        var s = 0;
        var indexs = [];
        //处理原始顺序的选项,将div标签和br标签以及多余的换行替换掉
        var options = options.innerHTML;
        options = options.replace(/<\/?div>/g, "\n");
        options = options.replace(/\n+/g, "\n");
        options = options.replace(/<br.*?>/g, "\n");
        options = options.replace(/^\n/, "");
        options = options.replace(/\n$/, "");
        //以换行符分隔选项为数组
        options = options.split("\n");
 
        //随机组合选项
        for (var op in options) {
            //随机产生一个索引,如果产生的索引已处理过,继续产生下一个索引,没处理过就中断循环开始处理
            do {
                s = Math.random() * (options.length);
                s = Math.floor(s);
                if (indexs.join().indexOf(s.toString()) == -1) {
                    indexs.push(s);
                    myinfo.newOrderOps.push(options[s]);
                    break;
                }
            } while (true);
            //将随机产生的选项组合成li包着的input和label
            list = document.createElement("li");
            label = document.createElement("label");
            label.innerHTML = options[s];
            var input = document.createElement("input");
				//根据答案字符长短判定应该用多选框还是单选框
            input.type = correctAnswer.length > 1?"checkbox":"radio";
            input.value = s;
			   input.name = "opts";//将选项成组,以防单选题可选择多个选项
				input.id = "opts_" + s;
				label.for = "opts_" + s;
            list.addEventListener("click", clickOption);
            list.appendChild(input);
            list.appendChild(label);
            optionList.appendChild(list);
 
        }
 
        for (i = 0; i < options.length; i++) {
            //将正确答案的字母序号转换成打乱顺序后的字母编号,并记录到myinfo.newOrderAnswer中
            if (correctAnswer.indexOf(String.fromCharCode(65 + indexs[i])) >= 0) {
                myinfo.newOrderAnswer += String.fromCharCode(65 + i);
            }
        }
Persistence.setItem(myinfo);
        //在选项li标签所在区域点击时,实际触发事件的可能是li、label或者input组件,无论是那个组件,都定位到checkbox
        function clickOption(ev) {
            var checkbox = ev.target;
				
            var tagName = checkbox.tagName;
            if (tagName == 'LI') {
                checkbox = checkbox.children[0];
            } else if (tagName == 'LABEL') {
                checkbox = checkbox.parentNode.children[0];
            }
            checkbox.checked = 'checked';
				
            var s = checkbox.value;
            //在打乱顺序后的索引数组中找到选项的新数字序号,再转换成对应的字母编号
            var ch = String.fromCharCode(65 + indexs.join('').indexOf(s.toString()));
            if (myinfo.choiced.indexOf(ch) == -1) {
                if(correctAnswer.length > 1){//多选题,在已选择项上加上一个新选项
						myinfo.choiced += ch;
					}else{//单选题,将已选择项变更为刚选的选项
						myinfo.choiced = ch;						
					}
            } else { //点击已选中的选项则取消该选项的选中状态
                myinfo.choiced = myinfo.choiced.replace(ch, '');
                checkbox.checked = null;
            }
            //if (Persistence.isAvailable()) {
                Persistence.setItem(myinfo);
            /*} else {
                window.myinfo = myinfo;
            }*/
			//根据选项是否被选择赋予不同的显示样式
            for (var j=0;j<optionList.children.length;j++) {
					var ch = String.fromCharCode(65 + j)
					if (myinfo.choiced.indexOf(ch) == -1) {
						optionList.children[j].className = "unchoiced";
					} else {
						optionList.children[j].className = "choiced";
					}
				}
        }
 
    /*} else {//无法持久化js对象,只能针对单面单题练习
    }*/
</script>

背面内容模版:

<!--背面模板-->
<script>
// v1.1.8 - https://github.com/SimonLammer/anki-persistence/blob/584396fea9dea0921011671a47a0fdda19265e62/script.js
if(void 0===window.Persistence){var e="github.com/SimonLammer/anki-persistence/",t="_default";if(window.Persistence_sessionStorage=function(){var i=!1;try{"object"==typeof window.sessionStorage&&(i=!0,this.clear=function(){for(var t=0;t<sessionStorage.length;t++){var i=sessionStorage.key(t);0==i.indexOf(e)&&(sessionStorage.removeItem(i),t--)}},this.setItem=function(i,n){void 0==n&&(n=i,i=t),sessionStorage.setItem(e+i,JSON.stringify(n))},this.getItem=function(i){return void 0==i&&(i=t),JSON.parse(sessionStorage.getItem(e+i))},this.removeItem=function(i){void 0==i&&(i=t),sessionStorage.removeItem(e+i)},this.getAllKeys=function(){for(var t=[],i=Object.keys(sessionStorage),n=0;n<i.length;n++){var s=i[n];0==s.indexOf(e)&&t.push(s.substring(e.length,s.length))}return t.sort()})}catch(n){}this.isAvailable=function(){return i}},window.Persistence_windowKey=function(i){var n=window[i],s=!1;"object"==typeof n&&(s=!0,this.clear=function(){n[e]={}},this.setItem=function(i,s){void 0==s&&(s=i,i=t),n[e][i]=s},this.getItem=function(i){return void 0==i&&(i=t),void 0==n[e][i]?null:n[e][i]},this.removeItem=function(i){void 0==i&&(i=t),delete n[e][i]},this.getAllKeys=function(){return Object.keys(n[e])},void 0==n[e]&&this.clear()),this.isAvailable=function(){return s}},window.Persistence=new Persistence_sessionStorage,Persistence.isAvailable()||(window.Persistence=new Persistence_windowKey("py")),!Persistence.isAvailable()){var i=window.location.toString().indexOf("title"),n=window.location.toString().indexOf("main",i);i>0&&n>0&&n-i<10&&(window.Persistence=new Persistence_windowKey("qt"))}}</script>


 
<div id="performance">正确率:100%</div>
<hr />
<div class="text">{{edit:Question}}</div>
<ol class="options" id="optionList"></ol>
<hr />
<div id="key" class="text"><span class="small_text">上面的选项以<span class="green">此种形式</span>显示的为被你选中的正确选项,以<span class="blue">此种形式</span>显示的为未被你选中的正确选项,以<span class="wrong">此种形式</span>显示的不是正确选项却被你选中了。本题结果如下:</sapn><br/></div>
<hr>
<div class="extra">
    <sapn class="imp">【解析】</sapn><br>{{edit:Extra}}</div>
<div id='styleButtons'> 
	<button id="blue_bold">蓝色加粗</button>
	<button id="red_bold">红色加粗</button>
	<button id="green_bold">绿色加粗</button>
	<button id="orange_bold">橙色加粗</button>
</div>

<script>
	/*以下对在复习界面中选择的文本的显示样式进行处理*/
	var styleButtonDiv = document.getElementById('styleButtons');
	var styleButtons = styleButtonDiv.getElementsByTagName('button');
	for(i=0;i<styleButtons.length;i++){
		styleButtons[i].onclick=function(ev){
			var selection = document.getSelection();
      		var selectStr = selection.toString();
      		if (selectStr.trim() != '') {
				var rang = selection.getRangeAt(0);
				//卡片样式如果用u,b,i,a等标签名定义,只需声明tmpEle
				var tmpEle
				//卡片样式如果用.red之类的类名定义,可创建span元素
				//var tmpEle = document.createElement('span');
				var eleId=ev.target.getAttribute('id')//获取触发事件的元素的id				
				if(eleId=='blue_bold'){//如果是蓝色加粗按钮
					//用标签名定义样式,需创建相应样式的元素
					tmpEle = document.createElement('b');
					//用类名定义样式,为前面创建的span元素指定类名
					//tmpEle.className = 'blue';
				}else if(eleId=='red_bold'){//如果是红色加粗按钮
					//用标签名定义样式,需创建相应样式的元素
					tmpEle = document.createElement('u');
					//用类名定义样式,为前面创建的span元素指定类名
					//tmpEle.className = 'red';
				}else if(eleId=='green_bold'){//如果是绿色加粗按钮
					//用标签名定义样式,需创建相应样式的元素
					tmpEle = document.createElement('i');
					//用类名定义样式,为前面创建的span元素指定类名
					//tmpEle.className = 'green';
				}else{//如果是橙色加粗按钮
					//用标签名定义样式,需创建相应样式的元素
					tmpEle = document.createElement('a');
					//用类名定义样式,为前面创建的span元素指定类名
					//tmpEle.className = 'orange';
				}
                //将选中的文本插入临时元素内部
				rang.surroundContents(tmpEle);
				rang.deleteContents(); // 删除选中内容
				rang.insertNode(tmpEle); //插入临时元素替换内容
			} else {
				alert('请先选择文本!');
			}
				
		}
	}	
	
	/*以下处理对做题结果的判断和输出*/
   var myinfo;
   myinfo = Persistence.getItem();
 
   //计算成绩的函数
   function calcScore() {
            if (myinfo.choiced.length == 0) {
                myinfo.ifright = "为什么一个都不选?"
                myinfo.score = 0;
            } else {
                myinfo.score = 1;
                for (var i = 0; i < myinfo.choiced.length; i++) {
                    if (myinfo.newOrderAnswer.indexOf(myinfo.choiced.charAt(i)) == -1) {
                        myinfo.score = 0;
                        myinfo.ifright = "错误";
                        break;
                    }
                }
                if (myinfo.score != 0) {
                    if (myinfo.newOrderAnswer.length == 1) {
                        myinfo.singleCorrect++;
                        myinfo.score = 1;
                        myinfo.ifright = "完全正确";
                    } else {
                        if (myinfo.choiced.length == myinfo.newOrderAnswer.length) {
                            myinfo.multiCorrect++;
                            myinfo.multiScore += 2;
                            myinfo.score = 2;
                            myinfo.choiced = myinfo.newOrderAnswer;
                            myinfo.ifright = "完全正确";
                        } else {
                            myinfo.partCorrect++;
                            myinfo.score = myinfo.choiced.length * 0.5;
                            myinfo.multiScore += myinfo.score;
                            myinfo.ifright = "不完全正确";
                        }
                    }
                }
            }
            myinfo.sum += myinfo.score;
            Persistence.setItem(myinfo);
        }
        //显示选项
        var optionOl = document.getElementById("optionList");
        ops = myinfo.newOrderOps;
        for (var i = 0; i < ops.length; i++) {
            var ch = String.fromCharCode(65 + i);
            list = document.createElement("li");
            label = document.createElement("label");
            label.innerHTML = ops[i];
            var input = document.createElement("input");
            //根据选择的答案是否有多个字符判断应选用多选框还是单选框
            input.type = myinfo.choiced.length > 1?"checkbox":"radio";
            list.appendChild(input);
            list.appendChild(label);
            optionOl.appendChild(list);
            if (myinfo.newOrderAnswer.indexOf(ch) >= 0) {
                if (myinfo.choiced.indexOf(ch) >= 0) {
                    list.className = 'green';
                    input.checked = 'checked';
                } else {
                    list.className = 'blue';
                }
            } else {
                if (myinfo.choiced.indexOf(ch) >= 0) {
                    list.className = 'wrong';
                    input.checked = 'checked';
                } else {
                    list.className = 'unchoiced'
                }
            }
        }
 
        //显示成绩
        calcScore();
        var performance = document.getElementById("performance");
        var key = document.getElementById("key");
        var total = myinfo.single + myinfo.multi;
        if (typeof(myinfo) != "undefined") {
            var singlePer = myinfo.single == 0 ? "100.00" :
                ((myinfo.singleCorrect / myinfo.single) * 100).toFixed(2);
            var multiErr = myinfo.multi - myinfo.multiCorrect - myinfo.partCorrect
            var multiPer = myinfo.multi == 0 ? "100.00" :
                ((myinfo.multiScore / (myinfo.multi * 2)) * 100).toFixed(2);
            var scorePer = ((myinfo.sum / myinfo.totalScore) * 100).toFixed(2)
            performance.innerHTML = "本次练习<span class='imp'>" + total +
                "</span>题---单选题<span class='imp'>" + myinfo.single +
                "</span>题---多选题<span class='imp'>" + myinfo.multi +
                "</span>题;<br>单选正确<span class='imp'>" + myinfo.singleCorrect +
                "</span>题---单选正确率<span class='imp'>" + singlePer +
                "%</span>;<br>多选正确<span class='imp'>" + myinfo.multiCorrect +
                "</span>题---多选部分正确<span class='imp'>" + myinfo.partCorrect +
                "</span>题---多选错误<span class='imp'>" + multiErr +
                "</span>题---多选得分<span class='imp'>" + myinfo.multiScore +
                "</span>分---多选得分率<span class='imp'>" + multiPer +
                "%</span>;<br>累计得分:<span class='imp'>" + myinfo.sum +
                "</span>分---已做题目满分<span class='imp'>" + myinfo.totalScore +
                "</span>分---得分率<span class='imp'>" + scorePer + "%</span>";
            key.innerHTML += "<div>正确答案:<span class='imp'>" + myinfo.newOrderAnswer +
                ";</span>你的答案:<span class='imp'>" + myinfo.choiced +
                ";</span>结果判定:<span class='imp'>" +
                myinfo.ifright + "</span>;本题得分:<span class='imp'>" +
                myinfo.score + "</span>。</div>";
        }
    //} else {}
</script>

样式:

.card { font-family: Cambria-modify,Aa虎头虎脑,哈天随性体,干就完事了简,微软雅黑; font-size:1.3em; text-align:left; 
			color: white; background-color:#000000;}
	table{border-collapse:collapse; }
	td{padding:5px;text-align:center;border:2px solid green;vertical-align: middle;}
	td.left{text-align:left;}
	td.red{
		border-right: solid thick red;
	}
	span {display:inline-block;}
	hr{border: none;
		height: 5px;
		background-color:yellow;}
	p{text-indent:2em;}
	div{margin:5px auto }
	.text{color:#ff0;font-weight:bold;font-size:1.2em;}
	.orange, .imp,a, a:visited,a:hover,a:link,a:active{color:#F90;font-weight:bold;}
	u, .red{color:red;font-weight: bold;text-decoration:none;}
	.unchoiced{ color: white;}
	.choiced{font-weight: bold; color: #f00;background-color:green;}
	.extra{ margin-top:15px; font-size:1.2em; color: #eeeebb; text-align:left;line-height:1.5em;}
	.green,i{  font-weight: bold; font-style:normal;color: #0f0;}
	.blue,b{ font-weight: bold; font-style:normal;color: #3cf;}
	.wrong{  font-weight: bold;  color: red;text-decoration:line-through;}
	.options{ list-style:upper-latin;font-size:1.2em;}
	.options *{ cursor:pointer;}
	.options *:hover[class="options"]{ font-weight:bold;color: #f90;}
	.options li{ margin-top:0.8em;}
	/*下面两行样式定义决定是否显示选项前面的圆形或方形框,注释掉就会显示*/
	.options input[type="radio"]{display:none;}
	.options input[type="checkbox"]{display:none;}
	#performance{ text-align:left; font-size:16px;}0

最后说明:由于本文的功能用到了Anki插件,因此不支持插件的安卓和iOS版的Anki不能应用本文的功能。本文在windows11及Anki2.1.54上完成。

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

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

相关文章

剖析 Kafka 消息丢失的原因

文章目录 前言一、生产者导致消息丢失的场景场景1&#xff1a;消息体太大解决方案 &#xff1a;1、减少生产者发送消息体体积2、调整参数max.request.size 场景2&#xff1a;异步发送机制解决方案 &#xff1a;1、使用带回调函数的发送方法 场景3&#xff1a;网络问题和配置不当…

FineReport报表案例

普通报表 保存的文件类型为 cpt&#xff0c;依靠着单元格的扩展与父子格的关系来实现模板效果&#xff0c;可进行参数查询&#xff0c;填报报表&#xff0c;图表设计等等&#xff0c;但是在分页预览模式下不能在报表主体中展示控件&#xff0c;而且单元格间相互影响&#xff0c…

IDEA快速入门02-快速入门

二、快速入门 2.1 打开IDEA,点击New一个项目 入口&#xff0c;依次打开 File -> New -> Project。 2.2 使用Spring Initializr方式构建Spring Boot项目 2.3 设置项目所属组、项目名称、java版本等 2.4 选择SpringBoot版本及依赖组件 点击Create进行创建。 2.6 创建成…

【第一性原理】邓巴数字

这里写自定义目录标题 什么是邓巴数字邓巴数背后的科学历史上各个组织的人数与邓巴数字的关系在人类进化中的意义现代社会中邓巴数字的体现邓巴数字的意义其他与沟通相关的数据注意事项结论参考 罗宾邓巴教授生于1947年&#xff0c;进化心理学家&#xff0c;牛津大学教授&#…

一种微弱故障特征增强的旋转机械故障诊断方法(MATLAB)

导致轴承失效的根本原因是由异常磨损和局部间的机械冲击所导致的。对轴箱轴承日常运转的下所产生的均匀磨损而言&#xff0c;其振动信号特征与正常轴承振动信号大致一样&#xff0c;随机性较强&#xff0c;其概率密度函数呈现出高斯分布的现象&#xff0c;但由于磨损所导致的不…

C语言程序设计-2 程序的灵魂—算法

【例 2.1】求 12345。 最原始方法&#xff1a; 步骤 1&#xff1a;先求 12&#xff0c;得到结果 2。 步骤 2&#xff1a;将步骤 1 得到的乘积 2 乘以 3&#xff0c;得到结果 6。 步骤 3&#xff1a;将 6 再乘以 4&#xff0c;得 24。 步骤 4&#xff1a;将 24 再乘以 5&#xf…

Python自动化(2)——键盘模拟

Python自动化(2)——键盘模拟 前台键盘模拟 前台键盘模拟和后台键盘模拟的区别在于&#xff0c;是否绑定窗口。即前台模拟是只模拟键盘操作&#xff0c;例如按下按键a&#xff0c;如果聚焦在一个文本文档的编辑区&#xff0c;那么就会把这个a输入进去。但如果是聚焦到了浏览器…

测试辅助工具(抓包工具)的使用1 之初识抓包工具(fiddler)

1.什么是抓包&#xff1f; 说明&#xff1a;客户端向服务器发送请求以及服务器响应客户端的请求,都是以数据包来传递的。 抓包&#xff08;packet capture&#xff09;&#xff1a;通过工具拦截客户端与服务器交互的数据包。 抓包后可以修改数据包的内容 2.为什么要抓包&…

【洛谷P3366】【模板】最小生成树 解题报告

洛谷P3366 -【模板】最小生成树 题目描述 如题&#xff0c;给出一个无向图&#xff0c;求出最小生成树&#xff0c;如果该图不连通&#xff0c;则输出 orz。 输入格式 第一行包含两个整数 N , M N,M N,M&#xff0c;表示该图共有 N N N 个结点和 M M M 条无向边。 接下…

解决js打开新页面百度网盘显示不存在方法:啊哦,你所访问的页面不存在了。

用js打开新页面open或window.location.href打开百度网盘后都显示&#xff1a;啊哦&#xff0c;你所访问的页面不存在了。 window.open(baidu_url); window.location.href baidu_url;在浏览器上&#xff0c;回车后网盘资源是可以打开的&#xff0c;刷新也是打开的。这是很奇怪…

IPv6知识点整理

IPv6&#xff1a;是英文“Internet Protocol Version 6”&#xff08;互联网协议第6版&#xff09;的缩写&#xff0c;是互联网工程任务组&#xff08;IETF&#xff09;设计的用于替代IPv4的下一代IP协议&#xff0c;其地址数量号称可以为全世界的每一粒沙子编上一个地址 。 国…

OkHttp框架源码深度剖析【Android热门框架分析第一弹】

OkHttp介绍 OkHttp是当下Android使用最频繁的网络请求框架&#xff0c;由Square公司开源。Google在Android4.4以后开始将源码中的HttpURLConnection底层实现替换为OKHttp&#xff0c;同时现在流行的Retrofit框架底层同样是使用OKHttp的。 源码传送门 优点: 支持Http1、Http…

初学者的TensorFlow 2.0 开发环境安装 -《MCU嵌入式AI开发笔记》(第七集)

MCU嵌入式AI开发笔记 初学者的TensorFlow 2.0 开发环境安装 -《MCU嵌入式AI开发笔记》&#xff08;第七集&#xff09;。抖音、B站、视频号等站点搜索柔贝特三哥&#xff0c;《MCU嵌入式AI开发笔记》视频同步更新&#xff0c;视频详细讲解。 07 初学者的 TensorFlow 2.0 教程 …

【tomcat】tomcat系统架构以及核心启动流程

对于web后端开发工程师来说&#xff0c;tomcat作为一个应用服务器框架本质上就是一个HTTP服务Servlet容器。研究过spring、spring mvc源码的同学应该了解&#xff0c;spring mvc其实就是基于Servlet规范实现的请求的转发路由、转发处理。而Spring和SpringMVC就是通过web.xml文件…

DINO-DETR

DINO-DETR DETR收敛慢的问题1. Contrastive DeNoising Training(对比方法降噪训练)2. Mixed Query Selection(混合查询选择方法对锚点进行初始化)3. Look Forward Twice(两次前向方法)==DINO模型的传播过程,以及部分模块的改进==DETR收敛慢的问题 PnP-DETR(ICCV 2021) 改进了…

同时使用接口文档swagger和knife4j

项目场景&#xff1a; springboot项目中同时使用接口文档swagger和knife4j 问题描述 在实体类中设置了字段必填的属性&#xff0c;在访问接口文档时出现异常 实体类关键代码片段 /*** 部门表 sys_dept*/ public class SysDept extends BaseEntity {private static final lo…

大聪明教你学Java | 深入浅出聊 Kafka

前言 &#x1f34a;作者简介&#xff1a; 不肯过江东丶&#xff0c;一个来自二线城市的程序员&#xff0c;致力于用“猥琐”办法解决繁琐问题&#xff0c;让复杂的问题变得通俗易懂。 &#x1f34a;支持作者&#xff1a; 点赞&#x1f44d;、关注&#x1f496;、留言&#x1f4…

2024年6月23日 十二生肖 今日运势

小运播报&#xff1a;2024年6月23日&#xff0c;星期日&#xff0c;农历五月十八 &#xff08;甲辰年庚午月戊午日&#xff09;&#xff0c;法定节假日。今天国际奥林匹克日&#xff0c;坚不可摧的意志&#xff0c;披荆斩棘的豪情&#xff0c;永远值得拥有&#xff01; 红榜生…

YOLOv8改进 | SPPF | 双通道特征处理的池化结构——SPPFCSPC【全网独家】

&#x1f4a1;&#x1f4a1;&#x1f4a1;本专栏所有程序均经过测试&#xff0c;可成功执行&#x1f4a1;&#x1f4a1;&#x1f4a1; 专栏目录 &#xff1a;《YOLOv8改进有效涨点》专栏介绍 & 专栏目录 | 目前已有40篇内容&#xff0c;内含各种Head检测头、损失函数Loss、…

LLM主流架构和模型

本文参考自https://github.com/HqWu-HITCS/Awesome-Chinese-LLM?tabreadme-ov-file和Huggingface中的ModelCard&#xff08;https://huggingface.co/&#xff09; LLM主要类别架构 LLM本身基于transformer架构。自2017年&#xff0c;attention is all you need诞生起&#x…