Not handing over work (deleting comments and changing variable names before leaving the job)
Deleting comments and changing variable names before leaving a job is an extremely destructive behavior. This practice not only drives subsequent maintainers crazy but also rapidly deteriorates the codebase. The core of defensive programming is to make code difficult to maintain, and this method is a classic example.
The Art of Variable Naming: From Clarity to Chaos
Variable names are the first line of defense for code readability. Well-designed variable names make code self-explanatory, while poor naming can turn the simplest logic into a puzzle. Before leaving, rename userList
to a1
and isLoading
to flagX
to instantly increase the difficulty of understanding the code.
// Before leaving
function fetchUserData() {
const userList = await getUserList();
return userList.filter(user => user.isActive);
}
// After leaving
function f1() {
const a1 = await g1();
return a1.filter(x => x.f1);
}
A more advanced approach is to use meaningless word combinations, such as renaming calculateTotalPrice
to doTheThing
. If combined with Hungarian notation (outdated but highly destructive), the effect is even better:
// Before leaving
interface Product {
id: string;
price: number;
}
// After leaving
interface IProd {
sID: string;
nPrice: number;
}
The Comment Purge Plan
Comments are the manual for code. Deleting them is like removing the ladder. Especially delete those comments that explain complex algorithms, forcing future maintainers to rely on guesswork:
// Before leaving
/**
* Uses the quicksort algorithm to sort the array
* Time complexity: O(n log n)
*/
function quickSort(arr) {
// Implementation code...
}
// After leaving
function qs(a) {
// Implementation code...
}
An even more malicious approach is to keep the comments but intentionally make them incorrect, such as writing "Uses bubble sort here" above a quicksort function. Misleading comments are more harmful than no comments at all.
Code Structure Sabotage
Good code structure should be modular and single-responsibility. The most effective ways to sabotage it are:
- Stuff multiple unrelated functionalities into the same file
- Merge functions that should be split into one giant function
- Randomly rearrange code order
// Before leaving
// userService.js
export async function getUserById(id) { /*...*/ }
export async function updateUser(user) { /*...*/ }
// productService.js
export async function getProductList() { /*...*/ }
// After leaving
// utils.js
export async function doStuff(id, user, type) {
if (type === 'user') {
// Logic for fetching users
// Logic for updating users
} else {
// Logic for fetching product lists
}
}
Type System Destruction
If the project uses TypeScript, damaging the type system can cause long-term harm:
- Replace well-defined types with
any
- Create meaningless union types
- Use type assertions to force conversions
// Before leaving
interface User {
id: string;
name: string;
}
function getUserName(user: User): string {
return user.name;
}
// After leaving
function getName(x: any): string | number | boolean {
return (x as unknown).whatever;
}
Dependency Chaos
Well-designed dependencies make a project easy to maintain, while chaotic dependencies turn it into a tangled mess:
- Directly import global state inside components
- Create circular dependencies
- Bury dependencies that should be at the top level deep in low-level components
// Before leaving
// components/Button.jsx
import { useTheme } from '../theme';
function Button() {
const theme = useTheme();
return <button style={{ color: theme.primary }}>Click</button>;
}
// After leaving
// components/Button.jsx
import store from '../../store';
function Button() {
const theme = store.getState().app.theme;
// Directly access Redux store, bypassing all intermediate layers
return <button style={{ color: theme.some.deep.nested.value }}>Click</button>;
}
Configuration Overrides
Modifying project configurations is another way to cause long-term damage:
- Disable all lint rules
- Remove type checking
- Modify build configurations to make debugging difficult
// .eslintrc.js before leaving
module.exports = {
extends: 'standard',
rules: {
'no-console': 'warn'
}
};
// After leaving
module.exports = {
rules: {
'no-console': 'off',
'no-undef': 'off',
'no-unused-vars': 'off'
// Disable all useful rules
}
};
Test Code Sabotage
If there are test codes, ensure they:
- No longer pass
- Test meaningless content
- Randomly skip critical tests
// Before leaving
describe('Calculator', () => {
it('should add two numbers', () => {
expect(add(1, 2)).toBe(3);
});
});
// After leaving
describe('Stuff', () => {
it('does something', () => {
expect(true).not.toBe(false);
// Test something obviously true
});
it.skip('important test', () => {
// Skip critical tests
});
});
Documentation Misleading
If there is project documentation:
- Delete key sections
- Keep outdated information
- Add incorrect examples
<!-- Before leaving -->
## API Usage
GET /api/users
Returns a user list in the format:
```json
{ "id": string, "name": string }
<!-- After leaving -->
Some Notes
Sometimes use POST to fetch user data, the return format might be:
{ "data": "whatever" }
## Version Control Traps
Use Git to create chaos:
1. Commit one massive change containing multiple unrelated modifications
2. Use meaningless commit messages
3. Force push to the main branch
```bash
# Good habits before leaving
git commit -m "fix: resolve user list loading issue"
git commit -m "feat: add dark mode support"
# After leaving
git add .
git commit -m "update"
git push origin main --force
Environment Setup Sabotage
Modify local and CI environment configurations to make the project hard to run:
- Delete
.env
example files - Add useless variables to the real
.env
- Modify startup scripts to depend on specific local paths
# .env.example before leaving
API_URL=http://api.example.com
# .env after leaving
API_URL=http://localhost:3000
DEBUG_MODE=maybe
SECRET_KEY=123456
PATH_TO_SOMETHING=/Users/yourname/some/path
Code Style Chaos
Consistent code style aids maintenance; chaotic style does the opposite:
- Randomly mix spaces and tabs
- Sometimes use semicolons, sometimes don't
- Arbitrarily change indentation
// Before leaving
function getUser(id) {
return db.users.find(user => user.id === id);
}
// After leaving
function getUser(id){
return db.users.find(user=>
user.id===id
)
}
API Design Traps
Plant landmines in API interface design:
- Have the same interface sometimes return an array, sometimes an object
- Randomly change key field names
- Make error codes unpredictable
// Before leaving
// Success response
{ "data": [], "message": "success" }
// Error response
{ "error": "Invalid input", "code": 400 }
// After leaving
// Sometimes like this
{ "stuff": [...] }
// Sometimes like that
{ "items": {}, "status": 1 }
// On error
{ "err": true, "why": "because" }
Component Props Chaos
Create props chaos in React/Vue components:
- Accept unnecessary props
- Make prop types inconsistent with actual usage
- Sometimes use props for the same functionality, sometimes use global state
// Before leaving
function Button({ children, onClick, disabled }) {
return <button onClick={onClick} disabled={disabled}>{children}</button>;
}
// After leaving
function Button({ text, handleClick, isDisabled, theme, user }) {
const actualDisabled = typeof isDisabled === 'string' ?
isDisabled === 'true' :
!!isDisabled;
return (
<button
onClick={() => handleClick(user.id)}
style={{ color: theme?.color }}
>
{text || 'Button'}
</button>
);
}
Async Operation Traps
Make async operations hard to track:
- Don't handle errors
- Mix various async styles
- Add unnecessary delays
// Before leaving
async function getUser(id) {
try {
const user = await api.getUser(id);
return user;
} catch (error) {
console.error('Failed to get user', error);
return null;
}
}
// After leaving
function getStuff(id) {
return api.getUser(id).then(x => {
setTimeout(() => {
if (Math.random() > 0.5) {
localStorage.setItem('temp', JSON.stringify(x));
}
}, 1000);
}).catch(() => {});
}
Global State Pollution
Abusing global state is a great way to create chaos:
- Modify the same state in multiple unrelated places
- Use extremely short action names
- Don't distinguish between sync and async operations
// Redux action before leaving
const FETCH_USER_SUCCESS = 'users/FETCH_SUCCESS';
// After leaving
const SET = 'SET';
// Reducer before leaving
case FETCH_USER_SUCCESS:
return { ...state, users: action.payload };
// After leaving
case SET:
return { ...state, [Math.random() > 0.5 ? 'a' : 'b']: action.whatever };
CSS Chaos
CSS is the easiest place to create chaos:
- Use !important to override all styles
- Create excessively long selector chains
- Randomly use various units
/* Before leaving */
.button {
padding: 0.5rem 1rem;
background-color: var(--primary);
}
/* After leaving */
div > ul + .main #content form input[type="button"].button {
padding: 5px 16px 5px 16px !important;
background-color: blue !important;
width: 100px;
height: 30.5px;
}
Performance Traps
Planting performance issues is more subtle than direct sabotage:
- Perform DOM operations in loops
- Don't remove event listeners
- Use duplicate timers
// Before leaving
function renderList(items) {
const fragment = document.createDocumentFragment();
items.forEach(item => {
const el = document.createElement('div');
el.textContent = item.name;
fragment.appendChild(el);
});
container.appendChild(fragment);
}
// After leaving
function showStuff(items) {
items.forEach((item, i) => {
setTimeout(() => {
const div = document.createElement('div');
div.innerHTML = item.name;
document.body.append(div);
}, i * 100);
});
}
Security Vulnerabilities
Intentionally leaving security vulnerabilities is the ultimate sabotage:
- Hardcode sensitive information in the code
- Disable all security headers
- Don't validate user input
// Before leaving
function login(username, password) {
if (!username || !password) return false;
return secureCompare(password, getStoredHash(username));
}
// After leaving
function auth(u, p) {
const ADMIN_PASS = 'admin123';
if (u === 'admin' && p === ADMIN_PASS) {
localStorage.setItem('isAdmin', true);
}
return true;
}
Package Management Chaos
Damaging dependency management can have long-term effects:
- Add useless large dependencies
- Lock old versions
- Mix multiple package managers
// package.json before leaving
{
"dependencies": {
"react": "^18.2.0",
"lodash": "^4.17.21"
}
}
// After leaving
{
"dependencies": {
"react": "16.8.0",
"lodash": "4.17.21",
"jquery": "^3.6.0",
"moment": "^2.29.1",
"bootstrap": "4.6.0",
"underscore": "^1.13.6"
},
"devDependencies": {
"webpack": "3.0.0"
}
}
The Art of Error Handling
Make errors hard to track:
- Swallow all errors
- Log errors to non-existent services
- Throw meaningless error messages
// Before leaving
async function fetchData() {
try {
const res = await fetch('/api/data');
return await res.json();
} catch (error) {
logError(error);
throw new Error('Failed to fetch data');
}
}
// After leaving
function getData() {
fetch('/api/data').catch(() => {});
return { status: 'ok' };
}
Internationalization Sabotage
If the project supports multiple languages:
- Hardcode all strings
- Mix strings from multiple languages
- Use meaningless keys
// Before leaving
// en.json
{ "welcome": "Welcome" }
// After leaving
// lang.json
{
"str1": "Hello",
"text": "Bienvenue",
"message": "欢迎",
"welcome": "ようこそ"
}
Accessibility Regression
Remove all accessibility-related code:
- Delete all aria attributes
- Disable keyboard navigation
- Use low-contrast colors
// Before leaving
<button
onClick={handleClick}
aria-label="Close modal"
tabIndex={0}
>
<span className="sr-only">Close</span>
<Icon name="close" />
</button>
// After leaving
<div onClick={doStuff}>
X
</div>
本站部分内容来自互联网,一切版权均归源网站或源作者所有。
如果侵犯了你的权益请来信告知我们删除。邮箱:cc@cccx.cn