go 使用fyne实现桌面程序的计算器例子

使用Fyne工具包构建跨平台应用是非常简单的,在此之前我们需要做一些准备功能做,比如安装一些gcc基础图形依赖库,还有go语言本身的运行开发环境都是必要的。

在此之前我们希望你是go语言的已入门用户,掌握go的协程,管道,以及大多数语法,这样会让你学习起来更轻松

下面是实现的代码,有一部分还没有实现,如果需要可以继续研究.

package mainimport ("image/color""math""strconv""strings""time""fyne.io/fyne/v2""fyne.io/fyne/v2/app""fyne.io/fyne/v2/canvas""fyne.io/fyne/v2/container""fyne.io/fyne/v2/theme""fyne.io/fyne/v2/widget""fyne.io/fyne/v2/driver/desktop"
)// 自定义按钮样式
type calculatorButton struct {widget.ButtonbgColor     color.ColorpressScale  float32    // 按下时的缩放比例isPressed   bool       // 按钮是否被按下animating   bool       // 是否正在动画中
}func newCalculatorButton(label string, bgColor color.Color, tapped func()) *calculatorButton {button := &calculatorButton{bgColor:    bgColor,pressScale: 0.95,    // 按下时缩小到95%isPressed:  false,animating:  false,}button.ExtendBaseWidget(button)button.Text = labelbutton.OnTapped = tappedreturn button
}// 添加鼠标按下事件处理
func (b *calculatorButton) MouseDown(*desktop.MouseEvent) {b.isPressed = trueb.animating = trueb.Refresh()
}// 添加鼠标释放事件处理
func (b *calculatorButton) MouseUp(*desktop.MouseEvent) {b.isPressed = falseb.animating = trueb.Refresh()
}func (b *calculatorButton) CreateRenderer() fyne.WidgetRenderer {background := &canvas.Circle{FillColor: b.bgColor,}text := canvas.NewText(b.Text, color.White)text.TextSize = 20text.Alignment = fyne.TextAlignCenterrenderer := &calculatorButtonRenderer{button:     b,background: background,text:       text,objects:    []fyne.CanvasObject{background, text},}// 创建动画renderer.animation = fyne.NewAnimation(time.Millisecond*100,    // 动画持续100毫秒func(progress float32) {if b.isPressed {// 从1.0缩pressScalescale := 1.0 - (1.0-b.pressScale)*progressrenderer.updateScale(scale)} else {// 从pressScale恢复到1.0scale := b.pressScale + (1.0-b.pressScale)*progressrenderer.updateScale(scale)}renderer.Refresh()},)return renderer
}type calculatorButtonRenderer struct {button     *calculatorButtonbackground *canvas.Circletext       *canvas.Textobjects    []fyne.CanvasObjectanimation  *fyne.Animation    // 添加动画对象
}// 添加缩放更新函数
func (r *calculatorButtonRenderer) updateScale(scale float32) {baseSize := fyne.NewSize(60, 45)  // 使用固定的基础大小scaledSize := fyne.NewSize(float32(baseSize.Width)*scale,float32(baseSize.Height)*scale,)// 计算偏移以保持按钮居中offset := fyne.NewPos((float32(baseSize.Width)-scaledSize.Width)/2,(float32(baseSize.Height)-scaledSize.Height)/2,)r.background.Resize(scaledSize)r.background.Move(offset)// 更新文本位置textSize := r.text.MinSize()r.text.Resize(textSize)r.text.Move(fyne.NewPos((baseSize.Width-textSize.Width)/2,(baseSize.Height-textSize.Height)/2,))
}// 修改 Refresh 函数
func (r *calculatorButtonRenderer) Refresh() {if r.button.animating {r.animation.Start()r.button.animating = false}r.background.FillColor = r.button.bgColorr.background.Refresh()r.text.Text = r.button.Textr.text.Refresh()
}// 修改 Destroy 函数
func (r *calculatorButtonRenderer) Destroy() {r.animation.Stop()
}// 添加Layout方法
func (r *calculatorButtonRenderer) Layout(size fyne.Size) {// 设置背景大小和位置r.background.Resize(size)// 文本居中textSize := r.text.MinSize()r.text.Resize(textSize)r.text.Move(fyne.NewPos((size.Width-textSize.Width)/2,(size.Height-textSize.Height)/2,))
}// 添加MinSize方法
func (r *calculatorButtonRenderer) MinSize() fyne.Size {return fyne.NewSize(60, 45)
}// 添加Objects方法
func (r *calculatorButtonRenderer) Objects() []fyne.CanvasObject {return r.objects
}// 添加自定义显示组件
type calculatorDisplay struct {widget.BaseWidgettext stringprocess string  // 添加计算过程
}func newCalculatorDisplay() *calculatorDisplay {display := &calculatorDisplay{text: "0", process: ""}display.ExtendBaseWidget(display)return display
}func (d *calculatorDisplay) CreateRenderer() fyne.WidgetRenderer {result := canvas.NewText(d.text, color.White)result.TextSize = 32result.Alignment = fyne.TextAlignTrailingprocess := canvas.NewText(d.process, color.Gray{Y: 180})  // 灰色显示计算过程process.TextSize = 20process.Alignment = fyne.TextAlignTrailingreturn &calculatorDisplayRenderer{display: d,result:  result,process: process,objects: []fyne.CanvasObject{result, process},}
}type calculatorDisplayRenderer struct {display *calculatorDisplayresult  *canvas.Textprocess *canvas.Textobjects []fyne.CanvasObject
}func (r *calculatorDisplayRenderer) MinSize() fyne.Size {return fyne.NewSize(280, 70)  // 增加高度以容纳两行文本
}func (r *calculatorDisplayRenderer) Layout(size fyne.Size) {processHeight := float32(25)r.process.Resize(fyne.NewSize(size.Width, processHeight))r.process.Move(fyne.NewPos(0, 0))r.result.Resize(fyne.NewSize(size.Width, size.Height-processHeight))r.result.Move(fyne.NewPos(0, processHeight))
}func (r *calculatorDisplayRenderer) Refresh() {r.result.Text = r.display.textr.process.Text = r.display.processr.result.Refresh()r.process.Refresh()
}func (r *calculatorDisplayRenderer) Objects() []fyne.CanvasObject {return r.objects
}func (r *calculatorDisplayRenderer) Destroy() {}func main() {a := app.New()w := a.NewWindow("计算器")w.SetFixedSize(true)// 设置深色主题a.Settings().SetTheme(theme.DarkTheme())// 声明计算器状态变量var (firstNumber float64operation   stringnewNumber   = trueshowingResult = false  // 添加这个变量)// 使用新的显示组件替代原来的Entrydisplay := newCalculatorDisplay()// 定义颜色grayColor := &color.NRGBA{R: 51, G: 51, B: 51, A: 255}orangeColor := &color.NRGBA{R: 255, G: 159, B: 10, A: 255}lightGrayColor := &color.NRGBA{R: 165, G: 165, B: 165, A: 255}darkerGrayColor := &color.NRGBA{R: 40, G: 40, B: 40, A: 255}// 数字按钮numbers := map[string]*calculatorButton{}for i := 0; i <= 9; i++ {number := inumbers[strconv.Itoa(i)] = newCalculatorButton(strconv.Itoa(i), grayColor, func() {if newNumber || showingResult {display.text = ""if showingResult {display.process = ""  // 清除之前的计算过程}newNumber = falseshowingResult = false}display.text += strconv.Itoa(number)display.Refresh()})}// 运算符按钮add := newCalculatorButton("+", orangeColor, func() {if showingResult {firstNumber, _ = strconv.ParseFloat(display.text, 64)display.process = display.text + " +"  // 开始新的计算过程showingResult = false} else {if !newNumber {secondNumber, _ := strconv.ParseFloat(display.text, 64)firstNumber = calculateResult(firstNumber, secondNumber, operation)display.text = strconv.FormatFloat(firstNumber, 'f', -1, 64)display.process = display.text + " +"  // 更新计算过程} else {firstNumber, _ = strconv.ParseFloat(display.text, 64)display.process = display.text + " +"  // 显示第一个数字和运算符}}operation = "+"newNumber = truedisplay.Refresh()})subtract := newCalculatorButton("-", orangeColor, func() {if showingResult {firstNumber, _ = strconv.ParseFloat(display.text, 64)showingResult = false} else {if !newNumber {secondNumber, _ := strconv.ParseFloat(display.text, 64)firstNumber = calculateResult(firstNumber, secondNumber, operation)display.text = strconv.FormatFloat(firstNumber, 'f', -1, 64)} else {firstNumber, _ = strconv.ParseFloat(display.text, 64)}}operation = "-"newNumber = truedisplay.Refresh()})multiply := newCalculatorButton("×", orangeColor, func() {if showingResult {firstNumber, _ = strconv.ParseFloat(display.text, 64)showingResult = false} else {if !newNumber {secondNumber, _ := strconv.ParseFloat(display.text, 64)firstNumber = calculateResult(firstNumber, secondNumber, operation)display.text = strconv.FormatFloat(firstNumber, 'f', -1, 64)} else {firstNumber, _ = strconv.ParseFloat(display.text, 64)}}operation = "*"newNumber = truedisplay.Refresh()})divide := newCalculatorButton("÷", orangeColor, func() {if showingResult {firstNumber, _ = strconv.ParseFloat(display.text, 64)showingResult = false} else {if !newNumber {secondNumber, _ := strconv.ParseFloat(display.text, 64)firstNumber = calculateResult(firstNumber, secondNumber, operation)display.text = strconv.FormatFloat(firstNumber, 'f', -1, 64)} else {firstNumber, _ = strconv.ParseFloat(display.text, 64)}}operation = "/"newNumber = truedisplay.Refresh()})equals := newCalculatorButton("=", orangeColor, func() {if !newNumber {secondNumber, _ := strconv.ParseFloat(display.text, 64)display.process += " " + display.text + " ="  // 完成计算过程result := calculateResult(firstNumber, secondNumber, operation)display.text = strconv.FormatFloat(result, 'f', -1, 64)firstNumber = resultshowingResult = truedisplay.Refresh()}})// 额外的功能按钮ac := newCalculatorButton("AC", lightGrayColor, func() {display.text = "0"display.process = ""  // 清除计算过程firstNumber = 0operation = ""newNumber = trueshowingResult = falsedisplay.Refresh()})plusMinus := newCalculatorButton("+/-", lightGrayColor, func() {if current, err := strconv.ParseFloat(display.text, 64); err == nil {display.text = strconv.FormatFloat(-current, 'f', -1, 64)display.Refresh()}})percent := newCalculatorButton("%", lightGrayColor, func() {if current, err := strconv.ParseFloat(display.text, 64); err == nil {display.text = strconv.FormatFloat(current/100, 'f', -1, 64)display.Refresh()}})decimal := newCalculatorButton(".", grayColor, func() {if !strings.Contains(display.text, ".") {display.text += "."display.Refresh()}})// 科学计算器的额外功能按钮mc := newCalculatorButton("mc", darkerGrayColor, func() {// 内存清除功能})mPlus := newCalculatorButton("m+", darkerGrayColor, func() {// 内存加功能})mMinus := newCalculatorButton("m-", darkerGrayColor, func() {// 内存减功能})mr := newCalculatorButton("mr", darkerGrayColor, func() {// 内存调用功能})// 科学运算按钮sin := newCalculatorButton("sin", darkerGrayColor, func() {if val, err := strconv.ParseFloat(display.text, 64); err == nil {result := math.Sin(val * math.Pi / 180) // 转换为弧度display.text = strconv.FormatFloat(result, 'f', -1, 64)display.Refresh()}})cos := newCalculatorButton("cos", darkerGrayColor, func() {if val, err := strconv.ParseFloat(display.text, 64); err == nil {result := math.Cos(val * math.Pi / 180)display.text = strconv.FormatFloat(result, 'f', -1, 64)display.Refresh()}})tan := newCalculatorButton("tan", darkerGrayColor, func() {if val, err := strconv.ParseFloat(display.text, 64); err == nil {result := math.Tan(val * math.Pi / 180)display.text = strconv.FormatFloat(result, 'f', -1, 64)display.Refresh()}})ln := newCalculatorButton("ln", darkerGrayColor, func() {if val, err := strconv.ParseFloat(display.text, 64); err == nil {result := math.Log(val)display.text = strconv.FormatFloat(result, 'f', -1, 64)display.Refresh()}})log := newCalculatorButton("log₁₀", darkerGrayColor, func() {if val, err := strconv.ParseFloat(display.text, 64); err == nil {result := math.Log10(val)display.text = strconv.FormatFloat(result, 'f', -1, 64)display.Refresh()}})sqrt := newCalculatorButton("√x", darkerGrayColor, func() {if val, err := strconv.ParseFloat(display.text, 64); err == nil {result := math.Sqrt(val)display.text = strconv.FormatFloat(result, 'f', -1, 64)display.Refresh()}})square := newCalculatorButton("x²", darkerGrayColor, func() {if val, err := strconv.ParseFloat(display.text, 64); err == nil {result := math.Pow(val, 2)display.text = strconv.FormatFloat(result, 'f', -1, 64)display.Refresh()}})pi := newCalculatorButton("π", darkerGrayColor, func() {display.text = strconv.FormatFloat(math.Pi, 'f', -1, 64)display.Refresh()})e := newCalculatorButton("e", darkerGrayColor, func() {display.text = strconv.FormatFloat(math.E, 'f', -1, 64)display.Refresh()})factorial := newCalculatorButton("x!", darkerGrayColor, func() {if val, err := strconv.ParseFloat(display.text, 64); err == nil {n := int(val)result := 1.0for i := 2; i <= n; i++ {result *= float64(i)}display.text = strconv.FormatFloat(result, 'f', -1, 64)display.Refresh()}})// 添加模式切换状态var isScientificMode = false// 声明updateLayout变量(在最前面)var updateLayout func()// 创建主容器mainContainer := container.NewVBox()// 创建显示区域容器displayContainer := container.NewPadded(display)// 创建基本计算器布局createBasicLayout := func() *fyne.Container {return container.NewGridWithColumns(4,ac, plusMinus, percent, divide,numbers["7"], numbers["8"], numbers["9"], multiply,numbers["4"], numbers["5"], numbers["6"], subtract,numbers["1"], numbers["2"], numbers["3"], add,numbers["0"], decimal, equals,)}// 创建科学计算器布局createScientificLayout := func() *fyne.Container {return container.NewGridWithColumns(10,// 第一行newCalculatorButton("(", darkerGrayColor, nil),newCalculatorButton(")", darkerGrayColor, nil),mc, mPlus, mMinus, mr,ac, plusMinus, percent, divide,// 第二行newCalculatorButton("2ⁿᵈ", darkerGrayColor, nil),square,newCalculatorButton("x³", darkerGrayColor, nil),newCalculatorButton("xʸ", darkerGrayColor, nil),e,  // 使用 e 按钮newCalculatorButton("10ˣ", darkerGrayColor, nil),numbers["7"], numbers["8"], numbers["9"], multiply,// 第三行factorial,  // 使用阶乘按钮sqrt,      // 使用平方根按钮pi,        // 使用 π 按钮ln,        // 使用自然对数按钮log,       // 使用常用对数按钮newCalculatorButton("EE", darkerGrayColor, nil),numbers["4"], numbers["5"], numbers["6"], subtract,// 第四行sin,       // 使用正弦按钮cos,       // 使用余弦按钮tan,       // 使用正切按钮newCalculatorButton("sinh", darkerGrayColor, nil),newCalculatorButton("cosh", darkerGrayColor, nil),newCalculatorButton("tanh", darkerGrayColor, nil),numbers["1"], numbers["2"], numbers["3"], add,// 第五行newCalculatorButton("Rad", darkerGrayColor, nil),newCalculatorButton("sinh⁻¹", darkerGrayColor, nil),newCalculatorButton("cosh⁻¹", darkerGrayColor, nil),newCalculatorButton("tanh⁻¹", darkerGrayColor, nil),newCalculatorButton("Rand", darkerGrayColor, nil),newCalculatorButton("EE", darkerGrayColor, nil),numbers["0"], decimal, equals,)}// 创建顶部工具栏(不包含modeSwitch)toolbar := container.NewHBox(widget.NewSeparator(),)// 定义updateLayout函数updateLayout = func() {var layout fyne.CanvasObjectif isScientificMode {layout = createScientificLayout()} else {layout = createBasicLayout()}mainContainer.Objects = []fyne.CanvasObject{toolbar,displayContainer,layout,}mainContainer.Refresh()}// 现在定义modeSwitch(在updateLayout之后)modeSwitch := newCalculatorButton("⚙", lightGrayColor, func() {isScientificMode = !isScientificModestartSize := w.Canvas().Size()var targetWidth float32if isScientificMode {targetWidth = 600} else {targetWidth = 300}targetSize := fyne.NewSize(targetWidth, 450)animation := fyne.NewAnimation(time.Millisecond*300,func(progress float32) {width := startSize.Width + (targetSize.Width-startSize.Width)*progressheight := startSize.Height + (targetSize.Height-startSize.Height)*progressw.Resize(fyne.NewSize(width, height))},)animation.Start()updateLayout()})// 更新toolbar,添加modeSwitchtoolbar.Objects = append([]fyne.CanvasObject{modeSwitch}, toolbar.Objects...)// 初始化布局updateLayout()// 直接使用mainContainer作为窗口内容w.SetContent(mainContainer)w.Resize(fyne.NewSize(300, 450))w.ShowAndRun()
}// 添加一个辅助函数来计算结果
func calculateResult(first, second float64, op string) float64 {var result float64switch op {case "+":result = first + secondcase "-":result = first - secondcase "*":result = first * secondcase "/":if second != 0 {result = first / second}}return result
}

go.mod文件

module calcgo 1.23.1require fyne.io/fyne/v2 v2.5.2require (fyne.io/systray v1.11.0 // indirectgithub.com/BurntSushi/toml v1.4.0 // indirectgithub.com/davecgh/go-spew v1.1.1 // indirectgithub.com/fredbi/uri v1.1.0 // indirectgithub.com/fsnotify/fsnotify v1.7.0 // indirectgithub.com/fyne-io/gl-js v0.0.0-20220119005834-d2da28d9ccfe // indirectgithub.com/fyne-io/glfw-js v0.0.0-20240101223322-6e1efdc71b7a // indirectgithub.com/fyne-io/image v0.0.0-20220602074514-4956b0afb3d2 // indirectgithub.com/go-gl/gl v0.0.0-20211210172815-726fda9656d6 // indirectgithub.com/go-gl/glfw/v3.3/glfw v0.0.0-20240506104042-037f3cc74f2a // indirectgithub.com/go-text/render v0.2.0 // indirectgithub.com/go-text/typesetting v0.2.0 // indirectgithub.com/godbus/dbus/v5 v5.1.0 // indirectgithub.com/gopherjs/gopherjs v1.17.2 // indirectgithub.com/jeandeaual/go-locale v0.0.0-20240223122105-ce5225dcaa49 // indirectgithub.com/jsummers/gobmp v0.0.0-20151104160322-e2ba15ffa76e // indirectgithub.com/nicksnyder/go-i18n/v2 v2.4.0 // indirectgithub.com/pmezard/go-difflib v1.0.0 // indirectgithub.com/rymdport/portal v0.2.6 // indirectgithub.com/srwiley/oksvg v0.0.0-20221011165216-be6e8873101c // indirectgithub.com/srwiley/rasterx v0.0.0-20220730225603-2ab79fcdd4ef // indirectgithub.com/stretchr/testify v1.8.4 // indirectgithub.com/yuin/goldmark v1.7.1 // indirectgolang.org/x/image v0.18.0 // indirectgolang.org/x/mobile v0.0.0-20231127183840-76ac6878050a // indirectgolang.org/x/net v0.25.0 // indirectgolang.org/x/sys v0.20.0 // indirectgolang.org/x/text v0.16.0 // indirectgopkg.in/yaml.v3 v3.0.1 // indirect
)

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

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

相关文章

鲁班猫的一些踩坑

有坑的地方 1、安装relasense&#xff1a; 错误&#xff1a;不要采用下面的二进制安装&#xff08;在主机、Jetson可以使用&#xff09;&#xff0c;尽管也能安装并运行realsense-viwer&#xff0c;但是链接不到相机设备&#xff01; sudo apt-key adv --keyserver keyserver…

Linux基础知识 - C(自学使用)

1.C语言基础知识 参考博客&#xff1a; https://blog.csdn.net/qq_45254369/article/details/126023482?ops_request_misc%257B%2522request%255Fid%2522%253A%252277629891-A0F3-4EFC-B1AC-410093596085%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fblog.%…

Xcode文件默认存储位置-使用c++file保存文件默认路径以及设置为路径为当前项目路径

Xcode文件默认存储位置-使用cfile保存文件默认路径以及设置为路径为当前项目路径 1.概述 使用Xcode工具开发时候&#xff0c;遇到C调用file创建文件后&#xff0c;在当前项目中找不到文件路径。这是由于xcode会将文件保存到默认设置的路径。下面是查看文件默认存储路径和修改…

DC-9靶场渗透

靶机&#xff1a;DC-9 DC: 9 ~ VulnHub 攻击机&#xff1a;kail linux 2024 1,将两台虚拟机网络连接都改为NAT模式&#xff0c;并查看DC-9的MAC地址 2&#xff0c;进行主机扫描&#xff0c;通过MAC地址发现靶机的IP地址 攻击机IP地址192.168.23.169&#xff0c;靶机IP地址192.1…

MySQL-存储过程/函数/触发器

文章目录 什么是存储过程存储过程的优缺点存储过程的基本使用存储过程的创建存储过程的调用存储过程的删除存储过程的查看delimiter命令 MySQL中的变量系统变量用户变量局部变量参数 if语句case语句while循环repeat循环loop循环游标cursor捕获异常并处理存储函数触发器触发器概…

QT QGestureEvent支持平移,缩放,旋转触摸板手势

一.Gesture释义 平移:点按住触控板,然后拖移,实现平移功能。 缩放:在触控板上,双指张开实现放大,双指合拢实现缩小。 旋转:在触控板上,双指分别反方向移动旋转,实现旋转功能。 二.实现功能 1.重写bool event(QEvent *event) override事件: bool ImageWidget::event…

16. 虚拟化

文章目录 第16章 虚拟化16.1 共享资源16.2 虚拟机16.3 虚拟机镜像16.4 容器16.5 容器和虚拟机16.6 容器的可移植性16.7 Pod&#xff08;容器组&#xff09;16.8 无服务器架构16.9 小结16.10 扩展阅读16.11 问题讨论 第16章 虚拟化 “虚拟”意味着永远不知道你的下一个字节从哪里…

SpringBoot poi-tl通过模板占位符生成word文件

简介&#xff1a; 开发中我们需要通过在word中使用占位符来动态渲染一些数据&#xff0c;本文讲解poi-tl实现动态生成word文档&#xff0c;包括表格循环&#xff0c;对象嵌套。 poi-tl官网文档 Poi-tl Documentation 1. word格式 这是我的test.word 这是导出后的out.docx文件 …

蓝桥杯普及题

[蓝桥杯 2024 省 B] 好数 题目描述 一个整数如果按从低位到高位的顺序,奇数位(个位、百位、万位……)上的数字是奇数,偶数位(十位、千位、十万位……)上的数字是偶数,我们就称之为“好数”。 给定一个正整数 N N N,请计算从 1 1

UE4 材质学习笔记12(水体反射和折射)

一.水体反射和折射 首先就是要断开所有连接到根节点的线&#xff0c;因为水有很多不同的节点成分&#xff0c;当所有其他节点都在用时 要分辨出其中一个是何效果是很难的。 虚幻有五种不同的方法可以创建反射&#xff0c;虚幻中的大多数场景使用多种这些方法 它们会同时运作。…

opencv-platform实现人脸识别

和同事接触了下甲方,对方算是一个资源整合的自由人&#xff0c;手里有项目&#xff0c;然后认识些开发就聊下有什么事情可以做的&#xff0c;对方聊了下做人脸签到&#xff0c;或者说人脸打开。就这方面我做了下简单的了解。做了个java小demo。 我们常用的人脸识别的摄像头屏幕…

shell脚本语言-需要算法?

文章目录 1. 冒泡排序2. 搜索算法3. 文本处理4. 文件操作5. 条件语句6. 循环 Shell脚本语言本身并不包含高级编程语言中的“算法”概念&#xff0c;如排序算法或搜索算法。Shell脚本主要用于自动化命令行任务&#xff0c;如文件操作、文本处理、程序执行等。不过&#xff0c;Sh…

ctfshow-文件上传-151-161

CTFshow文件上传 PHP文件上传&#xff1a;1、代码思路 黑名单是设置不能通过的用户&#xff0c;黑名单以外的用户都能通过。 phtml、pht、php3、php4、php5后缀都会按做php文件执行&#xff0c;且不在黑名单内。 2、绕过 找漏网之鱼:cer、php3、php4、phtml等。 大小写绕…

使用SpringBoot自定义注解+AOP+redisson锁来实现防接口幂等性重复提交

1 前提&#xff0c;整合好springboot和redis,redisson的环境 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId> </dependency> 2 编写自定义注解&#xff0c;注解的作用是标记…

反编译华为-研究功耗联网监控日志

摘要 待机功耗中联网目前已知的盲点&#xff1a;App自己都不知道的push类型的被动联网、app下载场景所需时长、组播联网、路由器打醒AP。 竞品 策略 华为 灭屏使用handler定时检测&#xff08;若灭屏30分钟内则周期1分钟&#xff0c;否则为2分钟&#xff09;&#xff0c;检…

第13次CCF CSP认证真题解

1、跳一跳 题目链接&#xff1a;https://sim.csp.thusaac.com/contest/13/problem/0 本题是小游戏“跳一跳”的模拟题&#xff0c;按照题意模拟即可。 100分代码&#xff1a; #include <iostream> using namespace std; int main(int argc, char *argv[]) {int n 30…

中国人寿财险青岛市分公司:科技保险,助力企业高质量发展

中国人寿财险青岛市分公司深知科技保险对于企业发展的重要性&#xff0c;积极将科技保险融入企业发展战略。公司利用科技手段&#xff0c;为企业提供风险评估、防灾减灾等增值服务&#xff0c;帮助企业降低经营风险。同时&#xff0c;公司还通过科技保险产品&#xff0c;为企业…

第十七周:机器学习

目录 摘要 Abstract 一、MCMC 1、马尔科夫链采样 step1 状态设定 step2 转移矩阵 step3 马尔科夫链的生成 step4 概率分布的估计 2、蒙特卡洛方法 step1 由一个分布产生随机变量 step2 用这些随机变量做实验 3、MCMC算法 4、参考文章 二、flow-based GAN 1、引…

程序员在线面试刷题神器

大家好&#xff0c;我是程序员阿药。推荐大家一款面试刷题神器&#xff01;&#xff01;&#xff01; 简介 微学时光是一款专为计算机专业学生和IT行业求职者设计的面试刷题小程序&#xff0c;它汇集了丰富的计算机面试题和知识点&#xff0c;旨在帮助用户随时随地学习和复习…

Zookeeper面试整理-故障排查和调试

在使用 Zookeeper 的过程中,可能会遇到各种问题,如性能下降、节点失效、集群不可用等。为了保持系统的稳定性和高可用性,掌握 Zookeeper 的故障排查和调试方法至关重要。以下是一些常见的故障排查技巧和调试方法: 1. 日志分析 Zookeeper 的日志是最直接的调试和故障排查工具…