“작동하는 한”이 표준입니까? [닫은]


23

내 최근 질문을보십시오 : 프로그래밍은 바닥에서 경쟁에서 직업입니까?

마지막 상점에는 절차가 없었습니다. 애자일은 본질적으로 프로젝트를 개발하거나 관리하는 방법에 대한 계획이 전혀 없다는 것을 의미했습니다. 그것은 "이봐, 여기에 엄청난 작업이 있습니다. 2 주 후에 가십시오. 우리는 빠른 속도와 민첩성입니다."

그들은 문제가 있다는 것을 알았습니다. 그들은 물건이 어떻게 쓰여 졌는지 신경 쓰지 않았습니다. 여러 개발자가 있지만 코드 검토는 없었습니다. 그들은 버그가있는 것으로 알고있는 소프트웨어를 출시했습니다.

저의 이전 직장에서 사람들은 효과가있는 한 자세가 좋았습니다. 우리가 본질적으로 사양을 탐색하는 동안 작성한 일부 코드를 다시 작성하도록 요청했을 때 그들은 그것을 거부했습니다. 코드가 여러 곳에서 반복 되었기 때문에 코드를 다시 작성하고 싶었습니다. 캡슐화가 없었으며 사람들이 코드를 변경하는 데 오랜 시간이 걸렸습니다.

본질적으로 내 인상은 이것입니다 : 프로그래밍은 다음과 같이 요약됩니다.

  1. 최신 도구 / 기술에 관한 책 읽기
  2. 회사가 "맞춤 코드 유지"를 원하지 않기 때문에 개별 코드 작성을 피하면서이를 기반으로 코드를 함께 던짐
  3. "작동하는 한"그것을 보여주고 다음으로 넘어갑니다.

나는 항상 다음 일에 더 좋은 가게를 가지겠다고 말했습니다. 결코 일어나지 않습니다. 이것이 맞다면 나는 고착 된 느낌이다. 기술은 항상 바뀝니다. 여기에서 유일한 전문 개발이 최신 MS Press 기술 서적을 읽는 중이라면 10 년 동안 무엇을 구축했지만 다양한 기술에 대한 피상적 인 지식이 있습니까? 나는 걱정하고있다 :

  1. 전문적인 표준을 갖추는 가장 좋은 방법
  2. 이 상황에서 의미있는 지식과 경험을 개발하는 방법

3
이것은 어느 나라입니까?

3
피할 수없는 딜버트 참조 : runningagile.files.wordpress.com/2007/11/…
nikie

5
<quote> Agile은 본질적으로 프로젝트를 개발하거나 관리하는 방법에 대한 계획이 전혀 없다는 것을 의미했습니다. </ quote> 이것은 민첩하지 않습니다. 이것은 아무것도 아닙니다.
Martin York

4
@Martin York : 맞습니다. 그러나 계획이나 사양이 부족한 곳에서는 애자일이라고 부르는 곳이 있습니다. 그것은 왼손을 어디에 현에 두어야하는지 전혀 모르는 상태에서 첼로를 연주하고 그것을 무음 음악이라고 부르는 것과 같습니다.
David Thornley

2
나는 사람들이 질문의 요점을 놓치고 있다고 생각합니다. 내 요점은 여기에 설명 된 역 동성이 실제로 기술이 필요하지 않거나 개발자가 기술을 키우는 것으로 보이지는 않습니다. 인내하지 않는 피상적 인 수준의 지식을 개발하는 것으로 보입니다. 회계사, 변호사 등은 교육을 더욱 가치있게 만드는 경험을 개발합니다. 내가 본 역 동성을 감안할 때, 나는 우리에게 그런 것이 아닙니다.
q303

답변:


8

훌륭한 개발자가되기위한 핵심 요소 인 " 작동하는 한 "과 잘 설계된 고급 코드 사이의 균형을 맞추는 것에 간접적으로 넘어 섰습니다 .

정치에서와 마찬가지로, 스펙트럼의 한쪽 끝에서 위치를 파악하는 것이 중간에서 미묘한 위치를 취하는 것이 훨씬 쉽습니다. 내가 경험하는 개발자의 대부분은 두 가지 범주 중 하나 인 카우보이 해킹 및 건축 우주 비행사 중 하나에 해당합니다. 나는 둘 사이의 균형을 맞추려고 노력합니다. 들리는 것처럼 쉽지 않습니다.

귀하의 질문에보다 직접적으로 대답하기 위해, "작동하는 한"이 종종 표준이라고 생각합니다. 그러나 다른 방식으로 살펴보십시오. 동료를 교육하고 더 나은 방법을 소개 할 수있는 훌륭한 위치에 있습니다. 그러나 극단적으로 나아 가지 말고 고객의 문제를 해결하기 위해 우리 모두가 왜이 일을하고 있는지 기억하십시오.


2
+1 특히 :remember why we're all doing this: to solve our customer's problems.
George Marian

21

>> 저의 이전 직장에서 사람들은 효과가있는 한 자세가 좋았습니다.

나는 소수자일지도 모르지만 같은 태도를 가지고 있으며 무언가를 다시 쓰려면 왜 이것이 필요한지 분명한 증거가 있어야한다고 믿습니다. "uf, 코딩 방법이 마음에 들지 않습니다"와 같은 의미는 아닙니다. 모든 개발자는 코드에 대한 기본 설정을 가지고 있습니다. 다시 작성하려는 부분에 문제가 있어야합니다.

  • 성능 문제
  • 시스템의 다른 부분보다 더 많은 버그가 발견되었습니다.
  • 개발자는이 부분에서 작업 할 때 더 많은 시간을 소비합니다
  • 기타

7
+1I strongly believe that to rewrite something there should be clear evidence why do we need this
George Marian

3
+1. 대부분의 프로그래머는 코드 에 대해 너무 열정적 인 것 같습니다. 아름다움과 순도 등은 코드가 실제로 개발 해야하는 것의 유물이라는 것을 깨닫지 못합니다 . 결국 중요한 것은 그것이 작동한다는 것입니다. 그것이 당신의 유료 고객이 관심을 갖는 것입니다.
Joonas Pulakka

9
나는 당신의 대답에 아무 문제가 없지만, 이러한 태도는 너무 자주 모든 사실에 동의 경영진에 의해 사용되는 좋은 코드를 다시 작성해야하는 이유 - "그건 진짜 이유 아니다"그들이 이동합니다.
니콜

4
@Michael : 리팩토링이 매우 중요합니다. 그리고 코드가 작동합니다. 또한 경쟁 업체가 이길 수 있기 때문에 빠르게 완료됩니다. 돈이 적고 할 일이 많기 때문에 제한된 자원으로 처리하는 것이 매우 중요합니다. 매우 중요한 몇 가지 사항이 있으며 비즈니스는 그 둘 사이의 균형을 유지하는 것입니다. 쉬운 작업은 아니지만 Google과 같은 성공적인 작업은 " 빠른 것을 찾아 내고 나중에 닦으십시오"라는 태도에 항상 의존하는 것 같습니다 .
Joonas Pulakka

3
@Joonas Pulakka : 그것은 전적으로 시장에 달려 있습니다. 웹 사이트의 경우 최고의 제품을 만드는 것보다 먼저하는 것이 더 중요하기 때문에 Google과 다른 사람들이하는 일입니다. 반면에, 중요한 의료 장비와 같이 "빠른 것을 꺼내고 나중에 닦으려고"한다면 오랫동안 사업을하지 못할 것입니다.
nikie

14

애자일은 버그가있는 소프트웨어를 출시하기로 결정한 사람에 대해 책임을지지 않습니다. 인간은

즉, 품질에 많은 중요성을 부여하며 좋습니다. 나는 당신이 완벽주의라고 확신하며 최신 기술을 따르지 않으면 자신의 가치에 대해 걱정하고 있습니다.

문제는 즉 완벽주의의 에 리드 꾸물 거리는 과 꾸물 거리는 리드 평범 .

그렇기 때문에 비즈니스는 시장 출시 시간민첩성 을 사용 하여 신속하고 예측 가능한 속도로 가치를 제공하는 등 우선 순위 를 결정해야합니다.

회사의 비즈니스 전략을 설명하지 않았으므로 관리자에게 질문을함으로써 시작해야한다고 생각합니다.

으로 정렬되고 자신의 목표와 계획에 대해 (그들은 당신을 고용 , 당신은 대신 자신의 개인 목표에 초점을 맞추는 그들에게 기여할 수있는 방법을 이해하는 것이 더 나은 위치에있을 것입니다 그들을 달성하기 위해).

understand그들의 가치 를 추구함으로써 당신은 당신의 것을 공유 할 수 있고 그것이 유익한 협력의 시작이 될 것이라고 확신합니다.

그리고 그들이 무엇을하고 있는지 모른다면, 당신의 유일한 선택은 그만두는 것 입니다.


2
나는 특히이 라인 같은 :The problem is that perfectionism leads to procrastination and procrastination leads to mediocrity.
조지 마리아

1
Pierre는이 사이트의 요다와 같습니다!
ozz

3

그것은 모두 당신이 짓고있는 것에 달려 있습니다. 한 달 동안 만 온라인 상태가되는 마이크로 사이트를 구축하고이를 구축하는 데 9 일이있는 경우에는 작동하는 한 충분합니다.

FA-18 시스템을위한 플라이 바이 와이어 알고리즘을 작성하는 경우 최대한 완벽하게 구축하는 것이 좋습니다.

대부분의 기술 답변의 경우와 마찬가지로 ... 그것은 달려 있습니다.


2

회사에 따라 다릅니다. 그러나 많은 회사들은 경쟁과 시간 압박이 심각합니다. 이것이 전형적인 이유 중 하나입니다. 또 다른 직원은 직원이 충분하지 않은 대규모 워크로드 일 수 있습니다. (회사의 잘못이 아닌 직원이 부족한 데에는 몇 가지 이유가 있습니다.) 일부 조직은 젖은 종이 봉지에서 벗어날 수 없었습니다.

80/20 규칙이 여기에 적용된다고 생각합니다. 기본적으로, 엉터리 80 %를 견디고 20 %로 나아가 야합니다. 그러나 그들조차도 절충을해야한다는 것을 인식하십시오. 비즈니스에서는 일반적으로 그것이 옳다는 것이 중요하지 않습니다. 지금 당장 가지고있는 것이 중요합니다.


2

여기에서 유일한 전문 개발이 최신 MS Press 기술 서적을 읽는 중이라면 10 년 동안 무엇을 구축했지만 다양한 기술에 대한 피상적 인 지식이 있습니까?

그것은 다소 짜증나지만 그 10 년 동안 주목할만한 몇 가지 실패가있을 수 있습니다. 나는 그곳에서 일하는 것에 대해 좋아하거나 좋아하지 않았던 특정한 것들을 기억할 수있는 많은 곳을 보았습니다. 회사가 Scrum을 구현하려고 시도하거나 테스트 주도 개발 접근 방식을 채택하려고 시도하는 경우, 새로운 기회가있을 수 있지만 공식적인 강의실 환경이 아닌 전문적인 개발로 간주되는 것은 아닙니다.

나는 다양한 카우보이 코딩 전략과 함께 "작동하는 한"공통적 인 다양한 장소를 알고 있습니다. 두 명의 신생 기업에서 나는 회사가 너무 어려서 그들이 실제로 무엇을하려고하는지에 대한 아이디어를 밝히려고 노력하는 경우 이해할 수있는 이런 종류의 사고 방식을 보았습니다. 내가 일했던 다른 회사들에는 더 찾기가 쉽지는 않지만 더 좋을 수있는 더 많은 과정과 성숙이있었습니다. 어떤 곳에서는보고 싶어 야 할 몇 가지 프로세스가있었습니다. "나도 좋아요. 나중 직장 상황에서 기억할 것입니다."그리고 다른 곳에서는 "나도 정말로 마음에 들지 않습니다. 앞으로는 그 일을 피하려고 노력할 것입니다. "


2

나는 그들이 이런 것을 따라 잡는 순간에 이런 가게에서 잠시 일했다. 문자 그대로 해결할 수없는 알려진 버그가있는 2 ~ 3 년 된 응용 프로그램이있었습니다. 레이아웃 너비와 높이에 대한 계산이 실행되는 4,000 줄 길이의 루프를 생각해보십시오. 한 사례에서 문제를 해결하기 위해 코드 조각을 수정하면 다른 곳에서는 20 개의 문제가 발생합니다. 이전 개발자는 계산 결과를 임의의 숫자로 임의로 조정하여 비슷한 문제를 겪었 기 때문입니다. 이 코드는 독성이 아닌 것으로 설명 할 수 없습니다.

마침내 상사가이 기존 코드를 사용하여 레이아웃을 처리 할 수 ​​있다고 말한 새로운 프로젝트를 진행했습니다. 어떻게 든 나는 그를 "변경"시켜서 그가 시간을 좀 더 주도록 설득했다. 대신 레이아웃을 돕기 위해 잘 설계된 라이브러리를 작성하는 데 시간을 사용했습니다. 이 새로운 프로젝트의 버그는 문자 그대로 10 초가 걸렸습니다. 코드를보기 전에 문제가 무엇인지 파악하기 전에 문제를 식별 할 수있었습니다.

나는 이것이 내 매니저에게 전환점이 될 것이라고 생각했지만 내가 얻은 모든 것은 뒷면에 팻이었고 그는 본질적으로 "당신의 방식도 생각합니다."라고 말했습니다.

나는 다른 상점에서 일하기 시작했고 여기가 더 좋습니다. 요점은, 당신은 그들의 마음을 바꿀 수 없다는 것입니다. 다른 곳으로 가십시오.


2
합의 ... 그들이 당신을 기대하는 선임 / 주임 개발자로 데려 오지 않는 한, 당신이 일하는 곳에서 다른 사람의 마음을 바꾸려고 노력할 필요는 없습니다. 나는 당신이 당신이 처음 일했던 곳에서 일하고있는 것처럼 느낀다. 그리고 희망적으로 더 푸른 목초지로 배를 뛰어 넘을 준비가되어있다
programmx10

같은 것; 나는 문자 그대로 일을 제대로 할 수없는 무식한 동료들과 일자리를 찾는 것처럼 보이고, 더 나은 방법을 설명하려고 할 때 나는 단지 "어?" 코드를 리팩토링 할 시간이없고, 수행해야 할 이유가없는 이유를 보거나 변명 할 수 있으므로 변경 사항이없고 잘못 작성된 내용을 처리해야하는 것에 대해 좌절감을 느끼게됩니다.
Wayne Molina

1

나는 경제에서 일종의 진화 과정이 있으며, 조만간 그러한 회사들이 사업에서 쫓겨날 것이라는 희망을 가지고있다. 그러나 빠른 속도의 기술 진보는 너무 많은 새로운 틈새를 만들어 내기 때문에 약한 경쟁자조차도 여전히 "음식"을 충분히 찾을 수 있습니다.

좋은 곳에서 일할 기회를 늘리려면 몇 주마다 새로운 것을 쓰지 말고 많은 고객에게 판매하는 제품이있는 회사를 찾으십시오. 좋은 코드 기반을 유지하고 기존 코드를 항상 손상시키지 않고 새로운 기능을 추가 할 수있는 기능에 더 많은 관심이 있어야합니다.


1

대학에서 온 메이저 친구를 생각 나게합니다. 그는 VLSI 디자인 수업을 들었고 첫 숙제에는 폭 1 마일 길이의 마이크로 미터 정도의 구성 요소가 등장했습니다. 시뮬레이션은 완벽하게 통과했습니다.

그의 비평가들에 대한 그의 대답은 "내가 아는 것은 내 똥이 효과가 있다는 것이다."


1

꽤 좋은 규범은 파레토 원칙입니다

80-20 규칙의 프로젝트 경험이 있으며 매우 잘 작동했습니다. 이 질문에 대한 답은 "완벽주의를위한 선을 어디에서 그리십니까" 도 도움이 될 수 있다고 생각합니다.

"파레토 원리"라는 용어는 파레토 효율을 지칭 할 수도있다. 파레토 원칙 (80-20 규칙, 소수의 법칙 및 요인 희소성 원칙이라고도 함)은 많은 경우에 영향의 약 80 %가 원인의 20 %에서 비롯된다고 말합니다. 비즈니스 경영 사상가 Joseph M. Juran은이 원칙을 제안하고 이탈리아 경제학자 인 빌 프레도 파레토 (Vilfredo Pareto)의 이름을 따서 1906 년 이탈리아 땅의 80 %가 인구의 20 %가 소유하고 있음을 관찰했습니다. 그는 자신의 정원에있는 완두 꼬투리의 20 %가 완두콩의 80 %를 함유하고 있음을 관찰하여 원리를 발전 시켰습니다. 비즈니스에서 일반적으로 사용되는 규칙입니다. 예를 들어 "판매의 80 %는 고객의 20 %에서 비롯됩니다". 수학적으로 충분히 큰 참가자 집합간에 무언가가 공유되는 경우 "k %가 참가자의 (100 – k) %"가되도록 50에서 100 사이의 숫자 k가 있어야합니다. k는 50 (균등 분배의 경우, 즉 인구의 100 %가 동일한 지분을 가짐)에서 거의 100 (소수의 참가자가 거의 모든 자원을 차지할 때)까지 다양 할 수 있습니다.수학적으로 80 %라는 숫자에는 특별한 것이 없지만 많은 실제 시스템은 분포의 중간 불균형 영역 주위에 k가 있습니다. 파레토의 원리는 파레토 효율과 접선 적으로 만 관련되며, 동일한 경제학자에 의해 도입되었다. 파레토는 인구의 소득과 부의 분배라는 맥락에서 두 가지 개념을 모두 발전시켰다.

소스 링크


훌륭하지만 질문과 어떻게 관련이 있습니까? 직장의 20 %가 나쁜 소프트웨어의 80 %를 생성한다고 말하고 있습니까?
Kirk Broadhurst

아니요, 소프트웨어가 80 % 작동하면 문제 없습니다. 허용되는 오류율은 20 %입니다.
Amir Rezaei

0

우리가 본질적으로 사양을 탐색하는 동안 작성한 일부 코드를 다시 작성하도록 요청했을 때 그들은 그것을 거부했습니다. 코드가 여러 곳에서 반복 되었기 때문에 코드를 다시 작성하고 싶었습니다. 캡슐화가 없었으며 사람들이 코드를 변경하는 데 오랜 시간이 걸렸습니다.

위법 행위는 없지만 관리자로서 나는 다음과 같은 문구를 읽습니다.

"내가 이미 작성한 일부 코드를 다시 작성하기 위해 두 번 지불을 요청했을 때 회사는 지불하고 싶지 않았습니다. 처음으로 작성할 때 엉망을 정리하기 위해 여분의 돈을 원했습니다. 동료들은 저의 삶을 어려워서 화가났습니다. "

그것이 당신 자신의 코드라면 당신이 불평하고 있습니다-당신은 설득력이 없습니다.

최신 정보

이 POV가 인기가 없다는 것을 이해합니다. 그러나 나는 그것이 전문 개발자의 책임과 태도에도 전혀 모순되지 않는다고 생각합니다.

깨끗한 코드를 작성하여 시작하면 (그리고 코드가 프로덕션 용도로 사용되는지 여부와 상관없이이 작업을 수행해야하는 여러 가지 이유가있는 경우)이 문제가 훨씬 덜 규칙적으로 발생합니다.

추정치에 깨끗한 코드와 리팩토링 시간을 포함 시키면 코드베이스를 깔끔하게 유지할 수 있습니다. 일정 압력으로 인해 필요한 시간을 얻지 못하면 발생하는 기술 부채를 처리 한 결과 미래의 추정치가 올라갑니다.

언젠가는 미래의 추정치 (또는 추정치와 관련된 불확실성)가 재 작성을 주장하는 데 도움이 될 것입니다 (관리자가 프로세스를 더 빨리 진행하라고 간청 할 때). 그렇지 않은 경우 비즈니스가 예상치를 수락했으며 대체 비용보다 진행 비용을 지불한다는 사실을 인정하십시오. 그것은 기술적 인 결정이 아닌 순수한 비즈니스 결정입니다.

일정을 협상하는 시간 은 코드를 작성 하기 전이 아니라 시간이 지남에 유의하십시오 . 코드가 작성된 후 (및 "작동") 고객, 관리자 및 임원은 원래 비용에 근접하거나 초과하는 "유지 관리"에 대한 다른 청구서를보고 싶지 않습니다. 비즈니스가 생각하는만큼 강하게 느끼면 언제든지 제 시간에 다시 작성하십시오. 비즈니스가 요구하는 것입니다.

당신의 관리자의 관점에서, 당신이 다시 쓰기를 예약하면 그의 엉덩이가 줄에 놓입니다. 당신이 말한대로 당신이 제공하지 않거나 생산성을 높이면 가방을 들고있는 사람입니다. 당신의 말을 듣는 것이 상대적으로 적은 불편 함과 비교할 때, 그가 선호하는 것을 추측하십시오.


2
"본질적으로 스펙 탐색"에 주목하십시오. 관리자로서 자세한 사양을 제공하고 다시 작성해야하는 경우 내 잘못입니다. 사양을 제공하지 않고 내가 작성하면서 발전시키지 않으면 코드의 이전 부분에서 모든 요구 사항을 알지 못하기 때문에 리팩터링해야합니다.
q303

8
나는이 답변을 너무 많이 아프게하고 싶다. 그러나 나는 할 수 없습니다 ... 이것은 정말 관리자의 생각입니다. 관리자가 수용 할 수있는 조건으로 작성하는 것은 개발 팀의 책임입니다. 작동하지만 "다시 쓰기"라고 말하면 마크의 반응이 매번 발생합니다. "고체화"또는 "안정화"또는 "완료"라고 말하는 것은 어려울 것입니다. 관리자는 불완전한 코드를 사용하여 프로덕션 환경에 들어갔다는 것을 인식해야하며, 작업을 완료할지 여부는 자신에게 달려 있습니다. 그렇게하지 않는 비용을 납득시키는 것은 개발자의 몫입니다.
Jeff Knecht

1
@ 제프-자리에! 한 현명한 동료가 한 번 "그들에게 말할 수있는 기회를주지 마십시오. 그것은 모두 당신이 질문을 어떻게 표현 하느냐에 달려 있습니다"라고 말했습니다.
ozz

2
원래 개발자가 떠날 때까지 관리자로서의 자세 그런 다음 다른 사람이 자신의 코드를 가져와야합니다. 그런 다음 코드에 대해 불평하는 코더가 아닙니다. 그것은 그 문제에 대해 불평하는 새로운 개발자 그들이 더 쉽게 해결되었습니다 수있을 때 해결되는 것을 방지. 개발자가 상호 교환 가능한 "자원"이라는 아이디어는 매우 순진한 관점입니다.
개미

0

그것이 당신이 얻을 수있는 일이라면, 돌아가서 오래된 코드를 다시 쓰는 대신 매번 더 나은 코드를 작성하는 데 집중하십시오. 타사 패키지를 함께 붙이는 영역 내에서 이동할 수있는 품질 범위는 여전히 있습니다.

시간이 있고 유지 관리하는 기존 구성 요소의 코드를 개선하려는 경우 작업을 수행하는 한 권한을 요청하지 않고 수행 할 수 있습니까? 구성 요소를 사용하는 다음 프로젝트의 예상 시간을 시간으로 고려하십시오.

저수준 프로그래밍의 경우, 학습 만족도를 얻을 수 없다면 오픈 소스 프로젝트를 살펴볼 때가 되었습니까?


일반적으로 사람들이 기존의 추악한 코드를 다루는 것을 싫어하는 주요 이유는 버그 수정 / 반창고를 여러 번 반복하여 작동하기 때문입니다. 허가없이이 문서를 다시 작성하는 것은 모든 버그 수정을 버리는 것과 같습니다. 공장에서 새로운 것으로 전투 테스트 코드를 교체하고 있습니다. 나는 허락을 구하지 않고는 그렇게하지 않을 것입니다.
Kirk Broadhurst

0

q303, 귀하의 질문이 흥미 로웠으며 개발자가 기술적 부채를 해결하도록 관리자를 설득하는 방법에 대해이 프로그래머 질문을 읽을 가치가 있다고 생각했습니다.

나는 일반적으로 그렇습니다, 그것은 표준입니다. 작동하지만 최적화되지 않은 소프트웨어는 작동하지 않는 소프트웨어보다 훨씬 낫다는 것을 이해하십시오. "작업"의 정의는 각 개인의 인식과 편견에 따라 달라질 수 있다는 주장도 있습니다. 새로운 시스템을 구현할 때는 항상 기존 시스템이 더 좋다고 생각할 사람이 있습니다. 그리고 개발자와 대화 할 때는 크 래피 소프트웨어 작업을 인정하지 않을 수 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.