百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术文章 > 正文

AI编程新对决:Deepseek与Qwen2.5谁能在扫雷游戏中更胜一筹?

myzbx 2025-03-20 16:52 6 浏览

在当今快速发展的科技时代,人工智能(AI)已经渗透到各个领域,软件开发也不例外。AI编程工具的出现不仅改变了传统的编码方式,还大大提高了开发效率和代码质量。在这场技术革命中,Deepseek和Qwen-2.5作为代表性的AI编程工具,展现了各自独特的功能和优势。

Deepseek以其快速响应和直观的代码生成能力著称,特别适合需要迅速完成原型开发的场景。它能够根据用户的需求,快速生成相应的代码片段或完整的项目结构,极大地简化了开发流程。而对于复杂任务的支持,则是Qwen-2.5的强项。支持多语言编程的Qwen-2.5在处理复杂的逻辑和优化代码性能方面表现出色,为开发者提供了更多可能性。



通过详细解析Deepseek和Qwen-2.5在实现扫雷游戏过程中的表现,我们将探讨它们各自的优势与不足。这不仅有助于理解AI编程工具的实际应用效果,也为开发者选择合适的开发工具有所启发。

第一部分:评测模型介绍

由于个人电脑配置限制,本次评测的两个国产明星大模型都是32b版本,其中由于Deepseek-r1 没有专门的编程版本,所以采用通用版本,Qwen2.5采用Qwen2.5-coder编程版本。

  • Deepseek-r1:32B: 模型大小20G,320亿参数,基础版,非蒸馏版本。


  • Qwen-code:32B


第二部分:模型表现

Qweb2.5-coder:32b

首先上场的是Qweb2.5-coder:32b, 首先是一段任务分析:

然后就开始进入代码编写阶段了,token生成速度还可以,一秒10个左右:

编写扫雷游戏代码

index.html




    
    
    网页版扫雷游戏
    


    

网页版扫雷游戏

<script src="script.js"></script>

styles.css

body {
    font-family: Arial, sans-serif;
    display: flex;
    justify-content: center;
    align-items: center;
    height: 100vh;
    margin: 0;
    background-color: #f4f4f9;
}

.container {
    text-align: center;
}

#game-board {
    display: grid;
    gap: 2px;
    width: fit-content;
    margin: auto;
}

.cell {
    width: 30px;
    height: 30px;
    background-color: #ddd;
    border: 1px solid #ccc;
    cursor: pointer;
    font-size: 18px;
    display: flex;
    justify-content: center;
    align-items: center;
}

.cell.revealed {
    background-color: #fff;
    border: 1px solid #999;
}

.cell.flagged {
    background-image: url('flag.png');
    background-size: cover;
}

#status {
    margin-top: 20px;
    font-weight: bold;
}

script.js

const gameBoard = document.getElementById('game-board');
const newGameBtn = document.getElementById('new-game-btn');
const statusDisplay = document.getElementById('status');

let boardSize = 10; // 游戏板大小(10x10)
let numMines = 20; // 地雷数量
let board = [];
let revealedCells = 0;

function createBoard() {
    gameBoard.innerHTML = '';
    board = Array.from({ length: boardSize }, () => Array(boardSize).fill(0));
    revealedCells = 0;
    statusDisplay.textContent = '';

    placeMines();
    calculateNumbers();

    for (let i = 0; i < boardSize; i++) {
        for (let j = 0; j < boardSize; j++) {
            const cell = document.createElement('div');
            cell.classList.add('cell');
            cell.dataset.row = i;
            cell.dataset.col = j;
            cell.addEventListener('click', handleCellClick);
            cell.addEventListener('contextmenu', handleRightClick);
            gameBoard.appendChild(cell);
        }
    }
}

function placeMines() {
    let minesPlaced = 0;
    while (minesPlaced < numMines) {
        const row = Math.floor(Math.random() * boardSize);
        const col = Math.floor(Math.random() * boardSize);
        if (board[row][col] !== -1) {
            board[row][col] = -1;
            minesPlaced++;
        }
    }
}

function calculateNumbers() {
    for (let i = 0; i < boardSize; i++) {
        for (let j = 0; j < boardSize; j++) {
            if (board[i][j] === -1) continue;
            let mineCount = 0;
            for (let x = Math.max(0, i - 1); x <= Math.min(boardSize - 1, i + 1); x++) {
                for (let y = Math.max(0, j - 1); y <= Math.min(boardSize - 1, j + 1); y++) {
                    if (board[x][y] === -1) mineCount++;
                }
            }
            board[i][j] = mineCount;
        }
    }
}

function handleCellClick(event) {
    const row = parseInt(event.target.dataset.row);
    const col = parseInt(event.target.dataset.col);

    if (board[row][col] === -1) {
        revealMines();
        statusDisplay.textContent = '游戏结束!你踩到地雷了!';
    } else {
        revealCell(row, col);
        if (revealedCells === boardSize * boardSize - numMines) {
            statusDisplay.textContent = '恭喜,你赢了!';
        }
    }
}

function revealCell(row, col) {
    const cell = document.querySelector(`.cell[data-row="${row}"][data-col="${col}"]`);
    if (cell.classList.contains('revealed') || cell.classList.contains('flagged')) return;

    cell.classList.add('revealed');
    revealedCells++;

    if (board[row][col] === 0) {
        for (let x = Math.max(0, row - 1); x <= Math.min(boardSize - 1, row + 1); x++) {
            for (let y = Math.max(0, col - 1); y <= Math.min(boardSize - 1, col + 1); y++) {
                revealCell(x, y);
            }
        }
    } else if (board[row][col] !== -1) {
        cell.textContent = board[row][col];
    }
}

function revealMines() {
    for (let i = 0; i < boardSize; i++) {
        for (let j = 0; j < boardSize; j++) {
            const cell = document.querySelector(`.cell[data-row="${i}"][data-col="${j}"]`);
            if (board[i][j] === -1) {
                cell.classList.add('revealed');
                cell.textContent = '';
            }
        }
    }
}

function handleRightClick(event) {
    event.preventDefault();
    const row = parseInt(event.target.dataset.row);
    const col = parseInt(event.target.dataset.col);
    const cell = document.querySelector(`.cell[data-row="${row}"][data-col="${col}"]`);

    if (cell.classList.contains('revealed')) return;

    if (cell.classList.contains('flagged')) {
        cell.classList.remove('flagged');
    } else {
        cell.classList.add('flagged');
    }
}

newGameBtn.addEventListener('click', createBoard);

createBoard();

代码写完了还提供了一段说明:


还是看看成品吧:


纳尼,这样式好像有些问题啊?但是还是可以点击的,多点几下就踩雷了:

总结:代码完成读30分,可玩性30分,需要二次样式调整优化。

Qweb2.5-coder:32b

接着上场的是Deepseek-r1:32b, 首先是一段任务分析:


接着进入正式编码阶段:

网页版扫雷游戏源代码实现步骤说明

为了创建一个网页版的扫雷游戏,我们将按照以下步骤进行:

1. 创建基本的HTML结构

首先,我们需要定义一个HTML页面,其中包含游戏的主要元素:网格容器、控制按钮和难度选择器。




    
    网页版扫雷
    


    

时间: 0

剩余地雷: 0

<script src="script.js"></script>

2. 添加CSS样式

body {
    font-family: Arial, sans-serif;
    display: flex;
    justify-content: center;
    align-items: center;
    height: 100vh;
    margin: 0;
    background-color: #f0f0f0;
}

.game-container {
    text-align: center;
    background-color: white;
    padding: 20px;
    border-radius: 10px;
    box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
}

.grid-container {
    margin: 10px auto;
}

.cell {
    width: 40px;
    height: 40px;
    border: 1px solid #ccc;
    display: inline-block;
    background-color: #eee;
    cursor: pointer;
}

.controls {
    margin-bottom: 10px;
}

.info p {
    margin: 5px 0;
}

3. 编写JavaScript核心逻辑


let grid = [];
let gridSize = { rows: 10, cols: 10 };
let mineCount = 10;
let gameOver = false;
let timer = null;
let firstClick = true;

// 初始化网格
function initGrid() {
    const container = document.getElementById('gridContainer');
    container.innerHTML = '';
    grid = [];
    
    for (let i = 0; i < gridSize.rows; i++) {
        grid[i] = [];
        const row = document.createElement('div');
        
        for (let j = 0; j < gridSize.cols; j++) {
            grid[i][j] = { isMine: false, isOpened: false, isFlagged: false };
            const cell = document.createElement('div');
            cell.className = 'cell';
            cell.dataset.row = i;
            cell.dataset.col = j;
            cell.addEventListener('click', handleClick);
            row.appendChild(cell);
        }
        
        container.appendChild(row);
    }
}

// 设置地雷
function setMines(firstRow, firstCol) {
    let minesPlaced = 0;
    
    while (minesPlaced < mineCount) {
        const row = Math.floor(Math.random() * gridSize.rows);
        const col = Math.floor(Math.random() * gridSize.cols);
        
        if (!grid[row][col].isMine && !(row === firstRow && col === firstCol)) {
            grid[row][col].isMine = true;
            minesPlaced++;
        }
    }
}

// 计算相邻地雷数量
function getAdjacentMines(row, col) {
    let count = 0;
    
    for (let i = -1; i <= 1; i++) {
        for (let j = -1; j <= 1 j const newrow='row' i const newcol='col' j if newrow>= 0 && newRow < gridsize.rows newcol>= 0 && newCol < gridSize.cols &&
                grid[newRow][newCol].isMine) {
                count++;
            }
        }
    }
    
    return count;
}

// 处理点击事件
function handleClick() {
    if (gameOver || this.classList.contains('flagged')) return;

    const row = parseInt(this.dataset.row);
    const col = parseInt(this.dataset.col);

    if (firstClick) {
        firstClick = false;
        setMines(row, col);
        startTimer();
    }

    if (grid[row][col].isMine) {
        gameOver = true;
        revealAll();
        alert('游戏结束!');
        return;
    }

    const adjacentMines = getAdjacentMines(row, col);

    if (adjacentMines === 0) {
        floodFill(row, col);
    } else {
        grid[row][col].isOpened = true;
        this.textContent = adjacentMines.toString();
        checkWin();
    }
}

// 洪水填充算法,递归打开相邻空格
function floodFill(row, col) {
    if (row < 0 row>= gridSize.rows || 
        col < 0 col>= gridSize.cols ||
        grid[row][col].isOpened ||
        grid[row][col].isMine) {
        return;
    }

    const adjacentMines = getAdjacentMines(row, col);
    
    grid[row][col].isOpened = true;
    this.textContent = (adjacentMines > 0 ? adjacentMines.toString() : '');
    
    if (adjacentMines === 0) {
        // 递归检查相邻的八个格子
        for (let i = -1; i <= 1; i++) {
            for (let j = -1; j <= 1 j floodfillrow i col j checkwin function checkwin let remainingcells='0;' for let row of grid for let cell of row if cell.ismine cell.isopened remainingcells if remainingcells='== 0)' gameover='true;' clearintervaltimer alert function revealall for let row of grid for let cell of row if cell.ismine const element='document.querySelector(`[data-row="${row}"][data-col="${col}"]`);' element.textcontent function starttimer let seconds='0;' timer='setInterval(()'> {
        document.getElementById('time').textContent = seconds++;
    }, 1000);
}

// 新游戏
function newGame() {
    gameOver = false;
    firstClick = true;
    clearInterval(timer);
    initGrid();
}

// 设置难度
function setDifficulty(rows, cols, mines) {
    gridSize.rows = rows;
    gridSize.cols = cols;
    mineCount = mines;
    newGame();
}

// 初始化游戏
initGrid();

// 绑定事件监听器到难度按钮
document.querySelectorAll('.difficulty-btn').forEach(btn => {
    btn.addEventListener('click', () => {
        const difficulty = btn.dataset.difficulty;
        switch(difficulty) {
            case 'easy':
                setDifficulty(10, 10, 10);
                break;
            case 'medium':
                setDifficulty(20, 20, 40);
                break;
            case 'hard':
                setDifficulty(30, 30, 90);
                break;
        }
    });
});

// 绑定右键点击事件
document.addEventListener('contextmenu', (e) => {
    if (!gameOver && e.target.classList.contains('cell')) {
        e.preventDefault();
        
        const cell = e.target;
        if (!cell.classList.contains('flagged') && !cell.classList.contains('opened')) {
            cell.classList.toggle('flagged');
            updateMineCount();
        }
    }
});

// 更新剩余地雷数量
function updateMineCount() {
    let flaggedMines = 0;
    
    document.querySelectorAll('.cell').forEach(cell => {
        if (cell.classList.contains('flagged')) flaggedMines++;
    });
    
    const mineDisplay = document.getElementById('mine-count');
    mineDisplay.textContent = mineCount - flaggedMines;
}

// 初始化剩余地雷显示
updateMineCount();


### 回答

为了帮助你逐步解决这个问题,我将提供一个分步骤的解决方案。以下是详细的步骤说明:

### 步骤 1:理解需求

我们需要开发一个经典的“扫雷”游戏,该游戏需要以下功能:
- **开始新游戏**:点击按钮后,重置游戏状态。
- **难度选择**:支持三种不同的难度级别(简单、中等、困难)。
- **显示剩余地雷数量**:实时更新剩余未标记的地雷数量。
- **右键标记功能**:允许玩家用右键标记可能包含地雷的方块。

### 步骤 2:规划游戏逻辑

首先,我们需要明确扫雷游戏的基本规则和逻辑:
1. **网格初始化**:根据选择的难度级别,创建一个指定大小的网格。
2. **放置地雷**:在网格中随机放置一定数量的地雷。注意,在第一次点击时,不能将地雷放在被点击的方块及其相邻的方块内。
3. **揭开方块**:当玩家点击一个方块时,如果该方块是地雷,则游戏结束;否则,显示该方块周围地雷的数量。如果数量为零,则递归打开所有相邻的空白方块( floods fill 算法)。
4. **标记功能**:允许玩家用右键标记可能包含地雷的方块。
5. **胜利条件**:当所有非地雷方块都被正确揭开时,玩家获胜。

### 步骤 3:设计数据结构

为了实现上述逻辑,我们需要以下数据结构:
- **网格表示**:使用一个二维数组 `grid` 来存储每个方块的状态。每个元素是一个对象,包含以下属性:
  - `isMine`:布尔值,指示该方块是否为地雷。
  - `isOpened`:布尔值,指示该方块是否已被揭开。
  - `isFlagged`:布尔值,指示该方块是否被标记。

### 步骤 4:实现网格初始化

在游戏开始或难度改变时,我们需要重新初始化网格。这包括:
1. 根据当前难度级别创建指定大小的网格。
2. 初始化所有方块的状态为默认状态(非地雷、未揭开、未标记)。

### 步骤 5:放置地雷

在第一次点击某个方块时,需要确保该方块及其相邻的方块内不放置地雷。这可以通过以下步骤实现:
1. 记录第一次点击的位置。
2. 随机在网格中选择位置放置地雷,避开第一次点击的位置及其周围的八个格子。

### 步骤 6:揭开方块逻辑

当玩家点击一个未标记且未揭开的方块时:
- 如果该方块是地雷,则游戏结束。
- 否则,计算该方块周围地雷的数量并显示。如果数量为零,则递归打开所有相邻的空白方块。

### 步骤 7:标记功能

允许玩家用右键点击方块来标记可能的地雷:
1. 在右键事件中,切换方块的 `isFlagged` 状态。
2. 更新剩余地雷计数器。

### 步骤 8:胜利和失败检测

- **失败条件**:当玩家点击一个地雷时,游戏结束,并显示所有地雷的位置。
- **胜利条件**:当所有非地雷方块都被正确揭开(即没有被标记或揭开的所有空白方块都已打开)。

### 步骤 9:用户界面设计

创建一个简单的 HTML 页面,包含:
1. 游戏网格区域。
2. 难度选择按钮。
3. 新游戏按钮。
4. 剩余地雷计数器。

### 步骤 10:实现 JavaScript 逻辑

编写 JavaScript 代码来控制游戏的逻辑,包括:
- 初始化网格。
- 处理玩家点击和右键事件。
- 更新剩余地雷计数器。
- 检测胜利或失败条件。

### 步骤 11:测试和调试

在完成上述步骤后,进行全面的测试以确保所有功能正常工作。特别注意以下方面:
- **第一次点击无地雷**:确认第一次点击的位置不会触发地雷。
- **标记功能**:确保右键标记正确更新剩余地雷计数器,并且无法揭开已被标记的方块。
- **胜利和失败条件**:测试各种情况,确保游戏能够正确检测到胜利或失败。

### 步骤 12:优化用户体验

根据测试反馈,进行以下优化:
- 添加视觉效果(如颜色变化)以增强用户反馈。
- 提供清晰的游戏状态提示(如“已获胜”或“已爆炸”)。
- 确保界面在不同难度级别下响应良好。

### 步骤 13:最终部署

将所有代码整合到一个完整的 HTML 文件中,并进行最后的测试,确保没有遗漏的功能或错误。然后,将该文件部署到服务器或共享位置,供用户访问和游玩。

通过以上步骤,你可以逐步开发出一个功能完善的扫雷游戏,满足基本的游戏规则和用户体验要求。

好了,我们来看看成品:


样式看的有模有样,玩一把看看,竟然还有计时器功能,只是点击之后的格子会掉下来,有一点点小样式问题。

多点击几个格子后,突然没反应了,打开调试代码窗口看看:


原来遇到了Javascript语法错误,。详细找了一下,出错的行是这里第六行,现实col没有定义错误。

// 显示所有地雷
function revealAll() {
    for (let row of grid) {
        for (let cell of row) {
            if (cell.isMine) {
                const element = document.querySelector(`[data-row="${row}"][data-col="${col}"]`);
                element.textContent = '';
            }
        }
    }
}

从头看了一下代码,发现这里有语法错误,row和cell都不是简单的数值类型,而是object类型,简单修改一下让他可以跑:

// 初始化网格
function initGrid() {
    const container = document.getElementById('gridContainer');
    container.innerHTML = '';
    grid = [];
    
    for (let i = 0; i < gridSize.rows; i++) {
        grid[i] = [];
        const row = document.createElement('div');
        
        for (let j = 0; j < gridSize.cols; j++) {
            // 代码手动修改部分,增加r和c两个字段分别表示cell所在的行和列序号
            grid[i][j] = { isMine: false, isOpened: false, isFlagged: false, r: i, c:j };
            const cell = document.createElement('div');
            cell.className = 'cell';
            cell.dataset.row = i;
            cell.dataset.col = j;
            cell.addEventListener('click', handleClick);
            row.appendChild(cell);
        }
        
        container.appendChild(row);
    }
}

function revealAll() {
    for (let row of grid) {
        for (let cell of row) {
            if (cell.isMine) {
                // 代码手动修改部分,修改为从cell.r和cell.c 来找到对应的格子
                const element = document.querySelector(`[data-row="${cell.r}"][data-col="${cell.c}"]`);
                element.textContent = '';
            }
        }
    }
}

修改后基本可以正常玩了。

总结:相比于Qwen2.5-coder,Deepseek-r1非常贴心的引入了游戏计时和游戏难度选择两个额外功能,是的游戏的可玩性大大增加,可以打90分;代码完成读方面,由于Bug的存在,只能打80分。

第三部分:模型评判

通过此次对Deepseek-r1和Qwen-2.5-coder在实现扫雷游戏中的对比分析,我们得出了几个值得注意的结论。首先,Deepseek-r1的表现大大超出了预期,在编程领域展现了不俗的实力。它不仅能够快速完成扫雷游戏的核心功能,还额外提供了“游戏计时”和“难度选择”等实用功能,极大地提升了用户体验。尽管在实现过程中出现了一些小的代码Bug,导致整体评分略有下降,但这些瑕不掩瑜,Deepseek-r1的整体表现令人印象深刻。

反观Qwen-2.5,作为一款专门针对编程任务的大模型,其表现却让人略感失望。在实现扫雷游戏的过程中,Qwen-2.5不仅缺少“计时功能”和“难度设置”的支持,甚至连基本的网页样式设计都显得不够完善,导致最终的游戏体验大打折扣。这一结果或许与我们对它的高期望形成了鲜明对比。

从这次实践来看,Deepseek-r1作为一款通用型AI模型,在编程领域的表现已经足够令人惊艳。它不仅能够完成基础功能开发,还能在一定程度上满足用户对复杂需求的期待。而Qwen-2.5虽然专注于编程任务,但在实际应用中却显得力不从心,其短板暴露了当前AI编程工具在功能完善性和用户体验上的不足。

总的来说,随着AI技术的不断进步,未来像Deepseek-r1这样的通用型模型可能会在更多领域展现出更强的适应能力。而对于Qwen-2.5这类专业编程模型来说,如何提升实用性、优化功能设计,将是其未来发展的重要方向。无论选择哪种工具,开发者都需要根据自己的需求和场景进行权衡,才能最大化AI带来的价值。

希望这篇文章能为开发者提供一些参考,在选择AI编程工具时更加明智,同时也期待未来能看到更多优秀的AI工具诞生,为软件开发注入新的活力!

相关推荐

Django零基础速成指南:快速打造带用户系统的博客平台

#python##服务器##API##编程##学习#不是所有教程都值得你花时间!这篇实战指南将用5分钟带你解锁Django核心技能,手把手教你从零搭建一个具备用户注册登录、文章管理功能的完整...

iOS 17.0 Bootstrap 1.2.9 半越狱来啦!更新两点

这款Bootstrap半越狱工具终于更新,离上一次更新已相隔很久,现在推出1.2.9版本,主要为内置两点功能进行更新,也是提升半越狱的稳定性。如果你正在使用这款半越狱工具的,建议你更新。注意!...

iOS 16.x Bootstrap 1.2.3 发布,支持运行清理工具

本文主要讲Bootstrap半越狱工具更新相关内容。如果你是iOS16.0至16.6.1和17.0系统的,想体验半越狱的果粉,请继续往下看。--知识点科普--Bootstrap...

SpringBoot整合工作流引擎Acticiti系统,适用于ERP、OA系统

今日推荐:SpringBoot整合工作流引擎Acticiti的源码推荐理由:1、SpringBoot整合工作流引擎Acticiti系统2、实现了三级权限结构3、持久层使用了mybatis框架4、流程包...

SpringCloud自定义Bootstrap配置指南

在SpringCloud中自定义Bootstrap配置需要以下步骤,以确保在应用启动的早期阶段加载自定义配置:1.添加依赖(针对新版本SpringCloud)从SpringCloud2020...

Python使用Dash开发网页应用(三)(python网页开发教程)

PlotlyDash开发Web应用示例一个好的网页设计通常都需要编写css甚至js来定制前端内容,例如非常流行的bootstrap框架。我们既然想使用Dash来搭建web应用,很大的一个原因是不熟悉...

Oxygen XML Editor 27.1 中的新功能

OxygenXMLEditor27.1版是面向内容作者、开发者、合作者和出版商的行业领先工具包的增量版本。在27.1版本中,AIPositronAssistant得到了增强,包括用于...

【LLM-多模态】Mini-Gemini:挖掘多模态视觉语言模型的潜力

一、结论写在前面论文提出了Mini-Gemini,一个精简而强大的多模态VLM框架。Mini-Gemini的本质在于通过战略性框架设计、丰富的数据质量和扩展的功能范围,发掘VLM的潜在能力。其核心是补...

谐云课堂 | 一文详解分布式改造理论与实战

01微服务与分布式什么是分布式?首先,我们对上图提到的部分关键词进行讲解。单体,是指一个进程完成全部的后端处理;水平拆分,是同一个后端多环境部署,他们都处理相同的内容,使用反向代理来均衡负载,这种也叫...

基于Abaqus的手动挡换挡机构可靠性仿真

手动挡,也称手动变速器,英文全称为Manualtransmission,简称MT,即用手拨动换挡操纵总成才能改变变速器内的齿轮啮合位置,改变传动比,从而达到变速的目的。家用轿车主要采用软轴连接的换挡...

【pytorch】目标检测:彻底搞懂YOLOv5详解

YOLOv5是GlennJocher等人研发,它是Ultralytics公司的开源项目。YOLOv5根据参数量分为了n、s、m、l、x五种类型,其参数量依次上升,当然了其效果也是越来越好。从2020...

超实用!50个非常实用的PS快捷键命令大全分享

今天,给大家介绍50个非常实用的快捷键命令大全,大家伙都是设计师,关于软件使用那是越快越好啊。一、常用的热键组合1、图层混合模式快捷键:正常(Shift+Option+N),正片叠底(Shif...

Pohtoshop中深藏不露的小技巧(科目一考试技巧记忆口诀看完必过)

邢帅教育ps教程为大家总结了一些Pohtoshop中深藏不露的小技巧,可以帮助到大家在设计时减少不必要的麻烦,提高工作效率哦~~~1.设置网格线保持像素完美不在1:1分辨率下也能保持像素完美,可以...

Ganglia监控安装总结(监控安装工作总结)

一、ganglia简介:Ganglia是一个跨平台可扩展的,高性能计算系统下的分布式监控系统,如集群和网格。它是基于分层设计,它使用广泛的技术,如XML数据代表,便携数据传输,RRDtool用于数据...

谁说Adobe XD做不出好看的设计?那是你没搞懂这些功能

AdobeXD的美化栏具有将设计视图美化的功能,它能使界面设计和原型设计更漂亮、更吸引眼球。美化栏的7个功能包括竖线布局设计、横线布局设计、重复网格、图形大小和位置设置、响应式调整大小、文字美化以及...