832402208黄浩宸— First Assignment — Front-End and Back-End Separation Calculator System
EE308FZ — Software Engineering
First Assignment — Front-End and Back-End Separation Calculator System
Name: Haochen Huang
FZU ID: 832402208
MUID: 24125423
Calculator: https://140039hhh.github.io/832402208_calculator_frontend/
Table of Contents
- 1. Assignment Information
- 2. GitHub Repository and Code Standards
- 3. PSP Table
- 4. Assignment Overview
- 5. Requirement Analysis and Solution
- 6. System Architecture
- 7. Functional Structure
- 8. Design and Implementation Process
- 9. Key Code Explanation
- 10. Deployment
- 11. Finished Product Demonstration
- 12. Performance Improvement
- 13. Calculation Verification and Testing
- 14. Personal Journey and Learnings
- 15. Conclusion
1. Assignment Information
| Item | Information |
|---|---|
| Course for This Assignment | EE308FZ — Software Engineering |
| Student Name | Haogang Huang |
| FZU ID | 832402208 |
| MUID | 24127353 |
| Assignment | First Assignment — Front-End and Back-End Separation Calculator System |
| Assignment Requirements | See the official assignment page |
| Main Objective | Develop a calculator system based on front-end and back-end separation |
| Front-End Deployment | GitHub Pages |
| Back-End Deployment | Render |
| Database | SQLite |
| Main Communication Method | HTTP/HTTPS API |
Assignment Objective
The main objective of this assignment is to develop a calculator system using a front-end and back-end separation architecture.
The front end is responsible for user interaction, expression input, result presentation and history display. The back end is responsible for expression validation, mathematical calculation, exception handling and persistent calculation history.
The assignment requires the calculation itself to be completed by the back end rather than by the front end. The front end communicates with the back end through HTTP/HTTPS APIs.
2. GitHub Repository and Code Standards
2.1 Front-End Repository
Repository:832402208_calculator_frontend
Link:
Frontend GitHub Repository
The front-end repository contains the calculator user interface and the logic responsible for communicating with the back-end API.
2.2 Back-End Repository
Repository:832402208_calculator_backend
Link:
Backend GitHub Repository
The back-end repository contains the API server, calculation logic, database operations and exception handling.
2.3 Code Standards
Front-End Code Standard
Back-End Code Standard
The project follows a consistent coding style to improve readability, maintainability and code quality.
3. PSP Table
PSP stands for Personal Software Process. Before development, I estimated the time required for each stage. After completing the project, I recorded the actual time spent.
The total estimated time was 600 minutes, while the actual development time was 680 minutes.
| PSP Stage | Description | Estimated Time (min) | Actual Time (min) |
|---|---|---|---|
| Planning | Project planning and task arrangement | 20 | 20 |
| Requirement Analysis | Understanding requirements and functional analysis | 60 | 65 |
| System Design | Overall architecture, module and interface design | 50 | 55 |
| Coding Standard | Designing and organizing coding standards | 20 | 20 |
| Front-End Development | Calculator interface and interaction | 100 | 110 |
| Back-End Development | API, calculation logic and server implementation | 130 | 150 |
| Database Design | SQLite database and history persistence | 40 | 45 |
| Front-End/Back-End Integration | API communication and integration debugging | 50 | 55 |
| Testing and Bug Fixing | Functional testing and debugging | 70 | 80 |
| Deployment | GitHub Pages and Render deployment | 30 | 40 |
| Blog Writing | Documentation and technical explanation | 30 | 40 |
| Total | 600 | 680 |
PSP Analysis
The actual development time was 80 minutes longer than the original estimate.
The main reason was that the front-end and back-end integration required more debugging than expected. In particular, the project needed to ensure that the front end sent the expression to the back end and that the calculation result was generated by the back end.
Deployment also required additional time because the local development environment and the cloud deployment environment were different.
The final PSP result shows that the original estimate was relatively close to the actual development process, but future projects should reserve more time for integration testing and deployment.
4. Assignment Overview
The project is a web-based calculator implemented using a front-end and back-end separation architecture.
The system provides the following main functions:
- Basic arithmetic operations
- Compound expression calculation
- Decimal calculation
- Parentheses
- Unary positive and negative numbers
- Invalid expression handling
- Division-by-zero handling
- Calculation history
- Persistent history storage
- Deletion of calculation history
The most important architectural requirement is that the back end performs the actual calculation.
The basic workflow is:
User enters expression
↓
Front End
↓
HTTP/HTTPS Request
↓
Back End
↓
Validate expression
↓
Calculate expression
↓
Save successful result
↓
Return result
↓
Front End displays result
This design ensures that the project satisfies the requirement of front-end and back-end separation.
5. Requirement Analysis and Solution
5.1 Functional Requirements
The calculator should support basic operations:
- Addition
- Subtraction
- Multiplication
- Division
It should also support compound expressions such as:
1 + 2 * 3
(1 + 2) * 3
10 / 2 + 7
8 - 3 * 2
-5 + 8
3 * -2
The system should correctly handle:
- Operator precedence
- Parentheses
- Decimal numbers
- Unary operators
- Invalid expressions
- Division by zero
The system should also maintain calculation history.
Each successful history record contains:
ID
Expression
Result
Created Time
6. System Architecture
The project adopts a front-end and back-end separation architecture.
flowchart LR
A[User] --> B[Front-End Web Application]
B -->|HTTP/HTTPS + JSON| C[Back-End API]
C --> D[Input Validation]
D --> E[Expression Processing]
E --> F[Calculation Service]
F --> G[SQLite Database]
G --> F
F --> C
C -->|JSON Response| B
B --> A

The responsibilities of each layer are clearly separated.
Front End
The front end is responsible for:
- User input
- Calculator button interaction
- Expression display
- Result display
- Sending API requests
- Displaying calculation history
- Sending delete requests
- Displaying error messages
Back End
The back end is responsible for:
- Receiving API requests
- Validating expressions
- Processing mathematical expressions
- Performing calculations
- Handling calculation errors
- Saving calculation history
- Querying calculation history
- Deleting history records
Database
SQLite is used to persist calculation history.
Therefore, refreshing the browser does not remove previously stored records.
7. Functional Structure

The functional structure of the calculator can be represented as follows:
flowchart TD
A[Calculator System]
A --> B[Calculator Functions]
A --> C[Calculation History]
A --> D[Front End]
A --> E[Back End]
B --> B1[Addition]
B --> B2[Subtraction]
B --> B3[Multiplication]
B --> B4[Division]
B --> B5[Compound Expression]
B --> B6[Decimal Calculation]
B --> B7[Parentheses]
B --> B8[Unary Operators]
B --> B9[Error Handling]
C --> C1[Save History]
C --> C2[Query History]
C --> C3[Delete History]
D --> D1[User Input]
D --> D2[Calculator Interface]
D --> D3[Result Display]
D --> D4[History Display]
D --> D5[Error Display]
E --> E1[API Layer]
E --> E2[Validation]
E --> E3[Expression Processing]
E --> E4[Calculation Service]
E --> E5[Database Access]
This structure separates the presentation layer, business logic and data persistence layer.
8. Design and Implementation Process
8.1 Front-End Design
The front end provides the visual calculator interface.

The main responsibilities are:
- Receive input from the user.
- Construct the calculation expression.
- Send the expression to the back-end API.
- Wait for the back-end result.
- Display the returned result.
- Retrieve and display calculation history.
- Send deletion requests for selected history records.
The front end does not independently calculate the final result.
This is important because the assignment specifically requires the calculation logic to be located on the back end.
Front-End Interaction
flowchart TD
A[User presses calculator button]
B[Update expression display]
C[User presses =]
D[Send expression to Backend API]
E[Receive API response]
F{Success?}
G[Display result]
H[Display error message]
A --> B
B --> C
C --> D
D --> E
E --> F
F -->|Yes| G
F -->|No| H
8.2 Back-End Design
The back end is the core part of the project.
It receives the expression sent by the front end and performs the actual calculation.
The general process is:
Receive Request
↓
Validate Request
↓
Validate Expression
↓
Parse Expression
↓
Calculate Result
↓
Save History
↓
Return JSON Response
This approach prevents the front end from becoming responsible for the core mathematical logic.
8.3 API Design
The front end and back end communicate through HTTP/HTTPS APIs.
The main API operations are conceptually divided into three categories:
| Method | Function | Purpose |
|---|---|---|
| POST | Calculation | Send an expression and obtain the calculated result |
| GET | History | Retrieve calculation history |
| DELETE | History | Delete a specified history record |
A typical calculation request is:
{
"expression": "(1+2)*3"
}
A successful response is conceptually:
{
"success": true,
"expression": "(1+2)*3",
"result": "9"
}
An unsuccessful request should return an error response rather than causing the server to crash.
For example:
{
"success": false,
"message": "Invalid expression"
}
The API therefore provides a clear boundary between the front-end presentation layer and the back-end business layer.
8.4 Database Design
The calculation history is stored in SQLite.
The database table can be represented as follows:
erDiagram
CALCULATION_HISTORY {
INTEGER id PK
TEXT expression
TEXT result
DATETIME created_at
}

The main fields are:
| Field | Type | Description |
|---|---|---|
id | INTEGER | Unique record identifier |
expression | TEXT | Original calculation expression |
result | TEXT | Calculation result |
created_at | DATETIME | Calculation creation time |
The database is important because the assignment requires calculation history to persist on the back end rather than relying only on browser memory or local storage.
8.5 Calculation Module
The calculation module is the core business logic of the system.

The main process is:
flowchart TD
A[Input Expression]
B[Check Empty Input]
C[Validate Characters]
D[Parse Expression]
E[Process Parentheses]
F[Process Operator Precedence]
G[Process Unary Operators]
H[Calculate Result]
I{Valid?}
J[Return Result]
K[Return Error]
A --> B
B --> C
C --> D
D --> E
E --> F
F --> G
G --> H
H --> I
I -->|Yes| J
I -->|No| K
The calculation process must distinguish between different types of errors.
For example:
1 / 0
should not produce a normal numerical result.
Similarly:
1 + *
should be identified as an invalid expression.
8.6 Calculation History Module
Every successful calculation is stored in the database.

The history workflow is:
flowchart TD
A[Calculation Completed]
B[Create History Record]
C[Insert into SQLite]
D[GET History Request]
E[Query SQLite]
F[Return History]
G[DELETE Request]
H[Delete Record]
I[Return Updated State]
A --> B
B --> C
D --> E
E --> F
G --> H
H --> I
The front end obtains history through the back-end API.
Therefore, refreshing the browser does not cause the stored calculation history to disappear.
8.7 Exception Handling
Exception handling is an important part of the calculator because users may enter invalid mathematical expressions.
The system handles cases including:
Empty Expression
If the user submits an empty expression, the back end should reject the request and return an appropriate error message.
Invalid Expression
For example:
1 + *
The expression cannot be parsed and should result in an error response.
Division by Zero
For example:
10 / 0
The system should return an error rather than allowing the application to crash.
Invalid Parentheses
For example:
(1 + 2
The expression should be rejected because the parentheses are not balanced.
Front-End/Back-End Communication Failure
If the back-end service is unavailable, the front end should display an appropriate error instead of displaying a fake calculation result.
This also helps verify that the actual calculation is performed by the back end.
8.8 Front-End and Back-End Interaction
The complete interaction can be represented using the following sequence diagram:
sequenceDiagram
participant U as User
participant F as Front End
participant B as Back End
participant DB as SQLite
U->>F: Enter expression
U->>F: Press "="
F->>B: POST calculation request
B->>B: Validate expression
B->>B: Parse expression
B->>B: Calculate result
alt Calculation successful
B->>DB: Save history
DB-->>B: Save successful
B-->>F: Return result
F-->>U: Display result
else Calculation failed
B-->>F: Return error
F-->>U: Display error
end

This sequence clearly demonstrates that the front end does not calculate the final result itself.
9. Key Code Explanation
The purpose of this section is not to paste the entire source code. Instead, the key implementation logic is explained.
9.1 Front-End API Request
The front end sends the user's expression to the back end.
The important design idea is:
Frontend
↓
expression
↓
Backend API
↓
calculation
↓
result
↓
Frontend
The front end therefore acts as the client rather than the calculation engine.
Screenshot / code screenshot to insert here:
[Screenshot Placeholder — Front-End API Request Code]
Suggested screenshot:
Frontend source code
showing the request sent to the backend
9.2 Back-End Calculation Interface
The back end receives the expression and performs validation before calculation.
The important logic is:
Request
↓
Extract expression
↓
Validate expression
↓
Calculate
↓
Save history
↓
Return response
This separation makes the business logic easier to maintain and test.
Screenshot / code screenshot to insert here:
[Screenshot Placeholder — Back-End Calculation API Code]
9.3 Expression Processing
The expression-processing module is responsible for interpreting mathematical expressions.
Important cases include:
1 + 2 * 3
(1 + 2) * 3
-5 + 8
3 * -2
10 / 2
Operator precedence is especially important.
For example:
1 + 2 * 3
must be interpreted as:
1 + (2 * 3)
rather than:
(1 + 2) * 3
Therefore, the expression processing logic must respect mathematical operator precedence.
9.4 Database Insertion
After a successful calculation, the expression and result are stored in SQLite.
Conceptually:
Calculation Result
↓
Create History Record
↓
SQLite INSERT
This ensures that the calculation history is persistent.
Screenshot / code screenshot to insert here:
[Screenshot Placeholder — Database Insert Code]
9.5 Database Query
The history page obtains records from the back end.
The process is:
Frontend
↓
GET History
↓
Backend
↓
SQLite SELECT
↓
JSON Response
↓
Frontend
Screenshot / code screenshot to insert here:
[Screenshot Placeholder — Database Query Code]
9.6 Database Deletion
When the user deletes a history record, the front end sends the corresponding record ID to the back end.
The back end then deletes the record from SQLite.
User clicks Delete
↓
Frontend sends record ID
↓
Backend receives ID
↓
SQLite DELETE
↓
Return result
↓
Frontend refreshes history
Screenshot / code screenshot to insert here:
[Screenshot Placeholder — Database Delete Code]
10. Deployment
The completed project was deployed as a real front-end/back-end separated web application.

10.1 Front-End Deployment
The front end was deployed using GitHub Pages.
Online address:
The deployed web page can be opened directly in a browser.
10.2 Back-End Deployment
The back end was deployed using Render.
Online address:
The front end communicates with this deployed back-end service through HTTP/HTTPS requests.
10.3 Deployment Architecture
flowchart LR
A[User Browser]
B[GitHub Pages<br/>Frontend]
C[Render<br/>Backend API]
D[SQLite<br/>Database]
A --> B
B -->|HTTPS API Request| C
C --> D
D --> C
C -->|JSON Response| B
B --> A
The deployment demonstrates that the project is not limited to a local development environment.
11. Finished Product Demonstration
According to the assignment requirements, the finished product should be demonstrated with sufficient screenshots, GIFs or videos.
The following screenshots should be inserted into this section.
11.1 Main Calculator Interface

Description:
This screenshot shows the main calculator interface after the project has been deployed.
11.2 Addition

Description:
This screenshot demonstrates the basic addition operation.
11.3 Subtraction

Description:
This screenshot demonstrates subtraction.
11.4 Multiplication
[Screenshot 4 — Multiplication Test]

Description:
This screenshot demonstrates multiplication.
11.5 Division

Description:
This screenshot demonstrates division.
11.6 Decimal Calculation

Description:
This screenshot demonstrates decimal calculation.
11.7 Compound Expression

Description:
This screenshot demonstrates operator precedence in a compound expression.
11.8 Parentheses

Description:
This screenshot demonstrates that parentheses change the calculation order.
11.9 Unary Negative Number

Description:
This screenshot demonstrates unary negative number processing.
11.10 Invalid Expression

Expected result:
The system should display an appropriate error message.
Actual test result:
[Please insert your own screenshot and actual result here.]
11.11 Division by Zero

Expected result:
The system should reject the calculation and display an appropriate error message.
Actual test result:
[Please insert your own screenshot and actual result here.]
11.12 Calculation History

Description:
This screenshot demonstrates that successful calculations are stored in the calculation history.
11.13 Delete Calculation History




Description:
This screenshot demonstrates that a specified calculation history record can be deleted.
12. Performance Improvement
During development, one issue that required attention was the communication between the front end and the deployed back end.
Because the front end and back end are deployed independently, every calculation requires a network request.
The optimization process focused on reducing unnecessary requests and ensuring that each request contains only the information required by the calculation API.
The overall request flow was kept simple:
User Input
↓
One Calculation Request
↓
Backend Calculation
↓
Database Storage
↓
Result Response
This avoids performing the same calculation multiple times on the client and server.
Another important optimization was separating calculation logic from the user interface. This makes the calculation module easier to debug and avoids duplicating the same mathematical logic in multiple locations.
Performance Test
[Performance Test Screenshot Placeholder]
Please insert your own screenshot showing the calculation response time or browser/network information if required.
13. Calculation Verification and Testing
This section is intentionally reserved for the final testing evidence.
I did not replace the actual testing evidence with fabricated results. The following test cases can be used directly when completing the verification.
13.1 Basic Calculation Tests
| Test Case | Expression | Expected Result | Actual Result |
|---|---|---|---|
| Addition | 1 + 2 | 3 | [Fill in] |
| Subtraction | 8 - 3 | 5 | [Fill in] |
| Multiplication | 6 × 7 | 42 | [Fill in] |
| Division | 20 ÷ 4 | 5 | [Fill in] |
| Decimal | 1.5 + 2.5 | 4 | [Fill in] |
13.2 Compound Expression Tests
| Test Case | Expression | Expected Result | Actual Result |
|---|---|---|---|
| Operator precedence | 1 + 2 × 3 | 7 | [Fill in] |
| Parentheses | (1 + 2) × 3 | 9 | [Fill in] |
| Mixed operations | 10 / 2 + 7 | 12 | [Fill in] |
| Unary negative | -5 + 8 | 3 | [Fill in] |
| Negative operand | 3 × -2 | -6 | [Fill in] |
13.3 Exception Tests
| Test Case | Expression | Expected Behaviour | Actual Result |
|---|---|---|---|
| Invalid expression | 1 + * | Error message | [Fill in] |
| Division by zero | 10 / 0 | Error message | [Fill in] |
| Unbalanced parentheses | (1 + 2 | Error message | [Fill in] |
| Empty expression | Empty input | Error message | [Fill in] |
13.4 History Tests
| Test | Expected Behaviour | Actual Result |
|---|---|---|
| Save calculation | Successful calculation appears in history | [Fill in] |
| Query history | Stored records are returned | [Fill in] |
| Refresh page | History remains available | [Fill in] |
| Delete record | Selected record disappears | [Fill in] |
13.5 Front-End/Back-End Separation Verification
An important verification method is to temporarily stop or make the back-end service unavailable.
The expected behaviour is:
Frontend remains available
↓
User can still interact with the interface
↓
Calculation request is sent
↓
Backend unavailable
↓
No valid new calculation result
↓
Frontend displays an error
This verifies that the front end does not independently calculate the result.
[Screenshot 15 — Backend Unavailable Test]
Actual test result:
[Fill in your actual test result here.]
14. Personal Journey and Learnings
14.1 Understanding Front-End and Back-End Separation
One of the most important things I learned from this assignment was the difference between a traditional single-page calculator and a front-end/back-end separated system.
At the beginning, a calculator seems like a very simple application because the mathematical operations themselves are straightforward. However, after introducing a separate back end, the project becomes a complete client-server application.
The front end is no longer responsible for obtaining the final result. Instead, it sends the expression to the server and displays the result returned by the server.
14.2 Difficulties in Expression Processing
Another difficulty was processing compound expressions.
For a simple expression such as:
1 + 2
the calculation is straightforward.
However, expressions such as:
1 + 2 * 3
(1 + 2) * 3
-5 + 8
3 * -2
require the program to correctly understand operator precedence, parentheses and unary operators.
This made me realize that implementing a calculator is not simply about performing four arithmetic operations. The expression itself needs to be interpreted correctly before the calculation can be performed.
14.3 Front-End and Back-End Communication
During development, another challenge was making sure that the front end and back end could communicate correctly after deployment.
The local environment and the cloud environment are not exactly the same. A request that works locally may still need additional debugging after the system is deployed.
I learned that API testing should not only be performed locally. The deployed front end and deployed back end should also be tested together.
14.4 Database Persistence
Before this assignment, it was easy to think of calculation history simply as data displayed on the page.
However, the assignment requires the history to remain after refreshing or reopening the front end.
Therefore, the data must be stored in a back-end database.
Using SQLite allowed the project to persist calculation records while keeping the database structure relatively simple.
14.5 Deployment Experience
Deploying the project was also an important part of the learning process.
The front end was deployed using GitHub Pages and the back end was deployed using Render.
This gave me practical experience with the difference between:
Local Development
↓
GitHub Repository
↓
Cloud Deployment
↓
Public Access
The project therefore changed from a program that only worked on my computer into a web application that can be accessed through a public URL.
14.6 Problems and Solutions
During development, I encountered several types of problems.
Problem 1: Front-End/Back-End Communication
The front end needed to correctly send the expression to the deployed API.
Solution:
I checked the API request format, back-end response format and deployed service address, and then tested the communication again.
Problem 2: Calculation Errors
Invalid expressions and division by zero could cause incorrect behaviour if they were not handled properly.
Solution:
I added validation and error handling so that invalid requests would return error information instead of crashing the application.
Problem 3: Deployment
The deployed system behaved differently from the local development environment in some cases.
Solution:
I tested the deployed front end and back end independently and then performed end-to-end tests through the public front-end address.
14.7 What I Learned
Through this assignment, I learned:
- How front-end and back-end separation works.
- How to design and use REST-style APIs.
- How to process mathematical expressions.
- How to handle invalid user input.
- How to use SQLite for persistent data storage.
- How to connect a deployed front end with a deployed back end.
- How to use GitHub for project version management.
- How to deploy a complete web application to the Internet.
- How to document software development using PSP.
15. Conclusion
This assignment allowed me to develop a complete calculator system rather than only implementing a simple calculator interface.
The final project uses a clear front-end and back-end separation architecture:
Front End
↓
HTTP/HTTPS API
↓
Back End
↓
Calculation Module
↓
SQLite Database
The front end focuses on user interaction and presentation, while the back end is responsible for calculation, validation, exception handling and data persistence.
The project has been deployed publicly, with the front end hosted on GitHub Pages and the back end hosted on Render.
The most valuable part of this assignment was not simply implementing addition, subtraction, multiplication and division. Instead, it was understanding how individual modules work together to form a complete software system.
Through this project, I gained practical experience in software architecture, API communication, database persistence, debugging, deployment and software process management.
相关推荐
基于MATLAB的复合弹性模量分析,采用混合法则,结合纤维体积分数变化和图形结果。.zip
1.版本:matlab2014a/2019b/2024b 2.附赠案例数据可直接运行。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。
基于MATLAB的自适应纯追踪曲线跟踪机器人仿真,采用多路径、自适应速度控制和图形界面可视化。.zip
1.版本:matlab2014a/2019b/2024b 2.附赠案例数据可直接运行。 3.代码特点:参数化编程、参数可方便更改、代码编程思路清晰、注释明细。 4.适用对象:计算机,电子信息工程、数学等专业的大学生课程设计、期末大作业和毕业设计。
【数据库优化】通信行业B/O域查询性能提升:基于分区裁剪与覆盖索引的秒级溯源系统实现
内容概要:本文围绕通信行业中海量话单与信令数据的查询性能问题,系统阐述了从全表扫描到秒级响应的数据库优化路径。文章以运营商 cdr_detail 表为案例,揭示了因使用函数操作索引列(如DATE(call_start_time))和深分页(LIMIT offset, size)导致的全表扫描问题,并提出完整的优化方案:通过时间范围RANGE分区实现分区裁剪、构建msisdn与时间的联合覆盖索引、消除索引列函数运算、采用游标分页替代OFFSET等方式,使查询性能从P95 8.3秒降至290毫秒。同时介绍了执行计划分析(EXPLAIN)在调优中的关键作用,并展望了HTAP架构、向量化执行与AI自治优化器等未来方向。; 适合人群:具备一定数据库基础知识,从事通信行业数据开发、DBA或后端研发的技术人员,尤其是面对大规模时序数据查询性能瓶颈的工程师;; 使用场景及目标:①解决营业厅用户详单查询、网间结算对账、VoNR信令分析等高并发、低延迟查询场景下的性能问题;②掌握如何通过分区策略、索引设计和SQL改写实现从全表扫描到精准索引访问的优化落地; 阅读建议:建议结合实际生产环境中的大表查询案例,对照本文的反例与正例进行执行计划对比分析,并在测试环境中实践分区表创建、覆盖索引构建及游标分页改写,深入理解每项优化技巧的实际效果。
石墨提纯全球市场结构与产业发展趋势分析报告(QYResearch最新研究).docx
石墨提纯全球市场结构与产业发展趋势分析报告(QYResearch最新研究)
政府科技管理者如何提升科技成果转化政策的精准匹配与执行效率?.docx
政府科技管理者如何提升科技成果转化政策的精准匹配与执行效率?


